ia64/xen-unstable

changeset 811:b644fab116b4

bitkeeper revision 1.500 (3f86be35Q1ywfgRyq1VKkvPUP_JZ_A)

xi_vif_params.c:
new file
dev.c, vif.h, network.h, network.c, xen_read_console.c, Makefile:
Credit-based network scheduling.
author kaf24@scramble.cl.cam.ac.uk
date Fri Oct 10 14:12:05 2003 +0000 (2003-10-10)
parents 3f44ecdcb631
children f103c0647208
files .rootkeys tools/internal/Makefile tools/internal/xi_vif_params.c tools/misc/xen_read_console.c xen/common/network.c xen/include/hypervisor-ifs/network.h xen/include/xeno/vif.h xen/net/dev.c
line diff
     1.1 --- a/.rootkeys	Fri Oct 10 09:31:49 2003 +0000
     1.2 +++ b/.rootkeys	Fri Oct 10 14:12:05 2003 +0000
     1.3 @@ -172,6 +172,7 @@ 3f108ade1v8weyh1sKx890VTd240Hw tools/int
     1.4  3eb781fd8oRfPgH7qTh7xvgmwD6NgA tools/internal/xi_start.c
     1.5  3eb781fd0Eo9K1jEFCSAVzO51i_ngg tools/internal/xi_stop.c
     1.6  3f108ae2to5nHRRXfvUK7oxgjcW_yA tools/internal/xi_usage.c
     1.7 +3f86be322bd0h9jG3krZFOUgCDoxZg tools/internal/xi_vif_params.c
     1.8  3eb781fd7211MZsLxJSiuy7W4KnJXg tools/internal/xi_vifinit
     1.9  3f776bd2Xd-dUcPKlPN2vG89VGtfvQ tools/misc/Makefile
    1.10  3f6dc136ZKOjd8PIqLbFBl_v-rnkGg tools/misc/miniterm/Makefile
     2.1 --- a/tools/internal/Makefile	Fri Oct 10 09:31:49 2003 +0000
     2.2 +++ b/tools/internal/Makefile	Fri Oct 10 14:12:05 2003 +0000
     2.3 @@ -9,7 +9,7 @@ OBJS     = $(patsubst %.c,%.o,$(SRCS))
     2.4  
     2.5  TARGETS  = xi_create xi_start xi_stop xi_destroy xi_build 
     2.6  TARGETS += xi_phys_grant xi_phys_revoke xi_phys_probe xi_list 
     2.7 -TARGETS += xi_sched_global xi_sched_domain xi_usage
     2.8 +TARGETS += xi_sched_global xi_sched_domain xi_usage xi_vif_params
     2.9  INSTALL  = $(TARGETS) xi_vifinit xi_helper
    2.10  
    2.11  all: $(TARGETS)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/internal/xi_vif_params.c	Fri Oct 10 14:12:05 2003 +0000
     3.3 @@ -0,0 +1,86 @@
     3.4 +
     3.5 +#include "hypervisor-ifs/dom0_ops.h"
     3.6 +#include "dom0_defs.h"
     3.7 +#include "mem_defs.h"
     3.8 +
     3.9 +static char *argv0 = "internal_domain_vif_params";
    3.10 +
    3.11 +int main(int argc, char **argv)
    3.12 +{
    3.13 +    network_op_t  netop;
    3.14 +    int           domain, vif;
    3.15 +    unsigned long credit_bytes, credit_usec;
    3.16 +    
    3.17 +    if ( argv[0] != NULL ) 
    3.18 +        argv0 = argv[0];
    3.19 +
    3.20 +    if ( (argc != 3) && (argc != 5) ) 
    3.21 +    {
    3.22 +        fprintf(stderr, "Usage: %s <domain-id> <vif-id> "
    3.23 +                "[<credit-bytes> <credit-usec>]\n", argv0);
    3.24 +        fprintf(stderr, "Specify <credit usec> == 0 to disable scheduling\n");
    3.25 +        return 1;
    3.26 +    }
    3.27 +
    3.28 +    domain = atol(argv[1]);
    3.29 +    vif    = atol(argv[2]);
    3.30 +
    3.31 +    if ( argc == 5 )
    3.32 +    {
    3.33 +        credit_bytes = atol(argv[3]);
    3.34 +        credit_usec  = atol(argv[4]);
    3.35 +
    3.36 +        netop.cmd = NETWORK_OP_VIFSETPARAMS;
    3.37 +        netop.u.vif_setparams.domain       = domain;
    3.38 +        netop.u.vif_setparams.vif          = vif;
    3.39 +        netop.u.vif_setparams.credit_bytes = credit_bytes;
    3.40 +        netop.u.vif_setparams.credit_usec  = credit_usec;
    3.41 +        if ( do_network_op(&netop) < 0 )
    3.42 +            return 1;
    3.43 +
    3.44 +        if ( credit_usec != 0 )
    3.45 +        {
    3.46 +            printf("Set scheduling to %lu bytes every"
    3.47 +                   " %lu usecs (%2.2f Mbps)\n",
    3.48 +                   credit_bytes, credit_usec,
    3.49 +                   ((float)credit_bytes/(1024.0*1024.0/8.0)) /
    3.50 +                   ((float)credit_usec/1000000.0));
    3.51 +        }
    3.52 +        else
    3.53 +        {
    3.54 +            printf("Disabled rate limiting for vif\n");
    3.55 +        }
    3.56 +    }
    3.57 +    else
    3.58 +    {
    3.59 +        netop.cmd = NETWORK_OP_VIFGETINFO;
    3.60 +        netop.u.vif_getinfo.domain = domain;
    3.61 +        netop.u.vif_getinfo.vif    = vif;
    3.62 +        if ( do_network_op(&netop) < 0 )
    3.63 +            return 1;
    3.64 +        
    3.65 +        printf("%lld bytes transmitted\n"
    3.66 +               "%lld packets transmitted\n"
    3.67 +               "%lld bytes received\n"
    3.68 +               "%lld packets received\n",
    3.69 +               netop.u.vif_getinfo.total_bytes_sent,
    3.70 +               netop.u.vif_getinfo.total_packets_sent,
    3.71 +               netop.u.vif_getinfo.total_bytes_received,
    3.72 +               netop.u.vif_getinfo.total_packets_received);
    3.73 +
    3.74 +        if ( netop.u.vif_getinfo.credit_usec != 0 )
    3.75 +        {
    3.76 +            printf("Scheduling: %lu bytes every %lu usecs (%2.2f Mbps)\n",
    3.77 +               netop.u.vif_getinfo.credit_bytes,
    3.78 +                   netop.u.vif_getinfo.credit_usec,
    3.79 +               ((float)netop.u.vif_getinfo.credit_bytes/(1024.0*1024.0/8.0)) /
    3.80 +               ((float)netop.u.vif_getinfo.credit_usec/1000000.0));
    3.81 +        }
    3.82 +        else
    3.83 +        {
    3.84 +            printf("Scheduling: no rate limit\n");
    3.85 +        }
    3.86 +    }
    3.87 +
    3.88 +    return 0;
    3.89 +}
     4.1 --- a/tools/misc/xen_read_console.c	Fri Oct 10 09:31:49 2003 +0000
     4.2 +++ b/tools/misc/xen_read_console.c	Fri Oct 10 14:12:05 2003 +0000
     4.3 @@ -11,7 +11,7 @@
     4.4  
     4.5  int main(void)
     4.6  {
     4.7 -    unsigned char buf[208], abuf[32];
     4.8 +    unsigned char buf[208];
     4.9      struct sockaddr_in addr, from;
    4.10      int fromlen = sizeof(from);
    4.11      int len, fd = socket(PF_INET, SOCK_DGRAM, 0);
    4.12 @@ -37,6 +37,7 @@ int main(void)
    4.13              >= 0 )
    4.14      {
    4.15  #if 0
    4.16 +        unsigned char abuf[32];
    4.17          printf("%d-byte message from %s:%d --\n", len,
    4.18                 inet_ntop(AF_INET, &from.sin_addr, abuf, sizeof(abuf)),
    4.19                 ntohs(from.sin_port));
     5.1 --- a/xen/common/network.c	Fri Oct 10 09:31:49 2003 +0000
     5.2 +++ b/xen/common/network.c	Fri Oct 10 14:12:05 2003 +0000
     5.3 @@ -105,6 +105,10 @@ net_vif_t *create_net_vif(int domain)
     5.4      spin_lock_init(&new_vif->rx_lock);
     5.5      spin_lock_init(&new_vif->tx_lock);
     5.6  
     5.7 +    new_vif->credit_bytes = new_vif->remaining_credit = ~0UL;
     5.8 +    new_vif->credit_usec  = 0UL;
     5.9 +    init_ac_timer(&new_vif->credit_timeout, 0);
    5.10 +
    5.11      if ( (p->domain == 0) && (dom_vif_idx == 0) )
    5.12      {
    5.13          /*
    5.14 @@ -246,35 +250,46 @@ int vif_query(vif_query_t *vq)
    5.15   */
    5.16  int vif_getinfo(vif_getinfo_t *info)
    5.17  {
    5.18 -    struct task_struct *p;
    5.19      net_vif_t *vif;
    5.20  
    5.21 -    info->total_bytes_sent =
    5.22 -    info->total_bytes_received =
    5.23 -    info->total_packets_sent =
    5.24 -    info->total_packets_received = -1;
    5.25 -
    5.26 -    if ( !(p = find_domain_by_id(info->domain)) )
    5.27 -        return -ENOSYS;
    5.28 -
    5.29 -    vif = p->net_vif_list[info->vif];
    5.30 -
    5.31 +    vif = find_vif_by_id((info->domain << VIF_DOMAIN_SHIFT) | info->vif);
    5.32      if ( vif == NULL )
    5.33 -    {
    5.34 -        put_task_struct(p);
    5.35 -        return -ENOSYS;
    5.36 -    }
    5.37 +        return -ESRCH;
    5.38  
    5.39      info->total_bytes_sent              = vif->total_bytes_sent;
    5.40      info->total_bytes_received          = vif->total_bytes_received;
    5.41      info->total_packets_sent            = vif->total_packets_sent;
    5.42      info->total_packets_received        = vif->total_packets_received;
    5.43  
    5.44 -    put_task_struct(p);
    5.45 +    info->credit_bytes = vif->credit_bytes;
    5.46 +    info->credit_usec  = vif->credit_usec;
    5.47 +
    5.48 +    put_vif(vif);
    5.49  
    5.50      return 0;
    5.51  }
    5.52  
    5.53 +
    5.54 +int vif_setparams(vif_setparams_t *params)
    5.55 +{
    5.56 +    net_vif_t *vif;
    5.57 +
    5.58 +    vif = find_vif_by_id((params->domain << VIF_DOMAIN_SHIFT) | params->vif);
    5.59 +    if ( vif == NULL )
    5.60 +        return -ESRCH;
    5.61 +
    5.62 +    /* Turning off rate limiting? */
    5.63 +    if ( params->credit_usec == 0 )
    5.64 +        params->credit_bytes = ~0UL;
    5.65 +
    5.66 +    vif->credit_bytes = vif->remaining_credit = params->credit_bytes;
    5.67 +    vif->credit_usec  = params->credit_usec;
    5.68 +
    5.69 +    put_vif(vif);
    5.70 +
    5.71 +    return 0;    
    5.72 +}
    5.73 +
    5.74          
    5.75  /* ----[ Net Rule Functions ]-----------------------------------------------*/
    5.76  
    5.77 @@ -572,6 +587,12 @@ long do_network_op(network_op_t *u_netwo
    5.78      }
    5.79      break;
    5.80      
    5.81 +    case NETWORK_OP_VIFSETPARAMS:
    5.82 +    {
    5.83 +        ret = vif_setparams(&op.u.vif_setparams);
    5.84 +    }
    5.85 +    break;
    5.86 +    
    5.87      default:
    5.88          ret = -ENOSYS;
    5.89      }
     6.1 --- a/xen/include/hypervisor-ifs/network.h	Fri Oct 10 09:31:49 2003 +0000
     6.2 +++ b/xen/include/hypervisor-ifs/network.h	Fri Oct 10 14:12:05 2003 +0000
     6.3 @@ -127,13 +127,30 @@ typedef struct vif_getinfo_st
     6.4  {
     6.5      unsigned int        domain;
     6.6      unsigned int        vif;
     6.7 +
     6.8      /* domain & vif are supplied by dom0, the rest are response fields */
     6.9      long long           total_bytes_sent;
    6.10      long long           total_bytes_received;
    6.11      long long           total_packets_sent;
    6.12      long long           total_packets_received;
    6.13 +
    6.14 +    /* Current scheduling parameters */
    6.15 +    unsigned long credit_bytes;
    6.16 +    unsigned long credit_usec;
    6.17  } vif_getinfo_t;
    6.18  
    6.19 +/*
    6.20 + * Set parameters associated with a VIF. Currently this is only scheduling
    6.21 + * parameters --- permit 'credit_bytes' to be transmitted every 'credit_usec'.
    6.22 + */
    6.23 +typedef struct vif_setparams_st
    6.24 +{
    6.25 +    unsigned int        domain;
    6.26 +    unsigned int        vif;
    6.27 +    unsigned long       credit_bytes;
    6.28 +    unsigned long       credit_usec;
    6.29 +} vif_setparams_t;
    6.30 +
    6.31  /* Network trap operations and associated structure. 
    6.32   * This presently just handles rule insertion and deletion, but will
    6.33   * evenually have code to add and remove interfaces.
    6.34 @@ -144,6 +161,7 @@ typedef struct vif_getinfo_st
    6.35  #define NETWORK_OP_GETRULELIST  2
    6.36  #define NETWORK_OP_VIFQUERY     3
    6.37  #define NETWORK_OP_VIFGETINFO   4
    6.38 +#define NETWORK_OP_VIFSETPARAMS 5
    6.39  
    6.40  typedef struct network_op_st 
    6.41  {
    6.42 @@ -153,6 +171,7 @@ typedef struct network_op_st
    6.43          net_rule_t net_rule;
    6.44          vif_query_t vif_query;
    6.45          vif_getinfo_t vif_getinfo;
    6.46 +        vif_setparams_t vif_setparams;
    6.47      }
    6.48      u;
    6.49  } network_op_t;
     7.1 --- a/xen/include/xeno/vif.h	Fri Oct 10 09:31:49 2003 +0000
     7.2 +++ b/xen/include/xeno/vif.h	Fri Oct 10 14:12:05 2003 +0000
     7.3 @@ -72,6 +72,12 @@ typedef struct net_vif_st {
     7.4      long long total_packets_sent;
     7.5      long long total_packets_received;
     7.6  
     7.7 +    /* Trasnmit shaping: allow 'credit_bytes' everu 'credit_usec'. */
     7.8 +    unsigned long   credit_bytes;
     7.9 +    unsigned long   credit_usec;
    7.10 +    unsigned long   remaining_credit;
    7.11 +    struct ac_timer credit_timeout;
    7.12 +
    7.13      /* Miscellaneous private stuff. */
    7.14      struct task_struct *domain;
    7.15      unsigned int idx; /* index within domain */
     8.1 --- a/xen/net/dev.c	Fri Oct 10 09:31:49 2003 +0000
     8.2 +++ b/xen/net/dev.c	Fri Oct 10 14:12:05 2003 +0000
     8.3 @@ -1824,6 +1824,18 @@ inline int init_tx_header(net_vif_t *vif
     8.4      return proto;
     8.5  }
     8.6  
     8.7 +static void tx_credit_callback(unsigned long data)
     8.8 +{
     8.9 +    net_vif_t *vif = (net_vif_t *)data;
    8.10 +
    8.11 +    vif->remaining_credit = vif->credit_bytes;
    8.12 +
    8.13 +    if ( get_tx_bufs(vif) )
    8.14 +    {
    8.15 +        add_to_net_schedule_list_tail(vif);
    8.16 +        maybe_schedule_tx_action();
    8.17 +    }    
    8.18 +}
    8.19  
    8.20  static int get_tx_bufs(net_vif_t *vif)
    8.21  {
    8.22 @@ -1837,7 +1849,7 @@ static int get_tx_bufs(net_vif_t *vif)
    8.23      unsigned short      protocol;
    8.24      struct sk_buff     *skb;
    8.25      tx_req_entry_t      tx;
    8.26 -    int                 i, j, ret;
    8.27 +    int                 i, j, ret = 0;
    8.28      unsigned long       flags;
    8.29  
    8.30      if ( vif->tx_req_cons == shared_idxs->tx_req_prod )
    8.31 @@ -1845,6 +1857,10 @@ static int get_tx_bufs(net_vif_t *vif)
    8.32  
    8.33      spin_lock_irqsave(&vif->tx_lock, flags);
    8.34  
    8.35 +    /* Currently waiting for more credit? */
    8.36 +    if ( vif->remaining_credit == 0 )
    8.37 +        goto out;
    8.38 +
    8.39      j = vif->tx_prod;
    8.40  
    8.41      /*
    8.42 @@ -1868,6 +1884,29 @@ static int get_tx_bufs(net_vif_t *vif)
    8.43              continue; 
    8.44          }
    8.45  
    8.46 +        /* Credit-based scheduling. */
    8.47 +        if ( tx.size > vif->remaining_credit )
    8.48 +        {
    8.49 +            s_time_t now = NOW(), next_credit = 
    8.50 +                vif->credit_timeout.expires + MICROSECS(vif->credit_usec);
    8.51 +            if ( next_credit <= now )
    8.52 +            {
    8.53 +                vif->credit_timeout.expires = now;
    8.54 +                vif->remaining_credit = vif->credit_bytes;
    8.55 +            }
    8.56 +            else
    8.57 +            {
    8.58 +                vif->remaining_credit = 0;
    8.59 +                vif->credit_timeout.expires  = next_credit;
    8.60 +                vif->credit_timeout.data     = (unsigned long)vif;
    8.61 +                vif->credit_timeout.function = tx_credit_callback;
    8.62 +                vif->credit_timeout.cpu      = smp_processor_id();
    8.63 +                add_ac_timer(&vif->credit_timeout);
    8.64 +                break;
    8.65 +            }
    8.66 +        }
    8.67 +        vif->remaining_credit -= tx.size;
    8.68 +
    8.69          /* No crossing a page boundary as the payload mustn't fragment. */
    8.70          if ( ((tx.addr & ~PAGE_MASK) + tx.size) >= PAGE_SIZE ) 
    8.71          {
    8.72 @@ -1966,12 +2005,14 @@ static int get_tx_bufs(net_vif_t *vif)
    8.73       */
    8.74      smp_mb();
    8.75  
    8.76 -    if ( (vif->tx_req_cons = i) != shared_idxs->tx_req_prod )
    8.77 +    if ( ((vif->tx_req_cons = i) != shared_idxs->tx_req_prod) &&
    8.78 +         (vif->remaining_credit != 0) )
    8.79          goto again;
    8.80  
    8.81      if ( (ret = (vif->tx_prod != j)) )
    8.82          vif->tx_prod = j;
    8.83  
    8.84 + out:
    8.85      spin_unlock_irqrestore(&vif->tx_lock, flags);
    8.86  
    8.87      return ret;