ia64/xen-unstable

changeset 6908:3a7c0b00da8a

Grant-refrence allocation pools and tracking tables should be
per interface in netfront, not global. This fixes various
bug reports including Bugzilla #183.

Signed-off-by: Jim Dykman <dykman@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Sep 16 12:47:40 2005 +0000 (2005-09-16)
parents e1cc553059e1
children 8bb3f2567b8c
files linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Sep 16 10:57:31 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Sep 16 12:47:40 2005 +0000
     1.3 @@ -59,12 +59,6 @@
     1.4  #include <asm-xen/xen-public/grant_table.h>
     1.5  #include <asm-xen/gnttab.h>
     1.6  
     1.7 -static grant_ref_t gref_tx_head;
     1.8 -static grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1]; 
     1.9 -
    1.10 -static grant_ref_t gref_rx_head;
    1.11 -static grant_ref_t grant_rx_ref[NETIF_RX_RING_SIZE + 1];
    1.12 -
    1.13  #define GRANT_INVALID_REF	(0xFFFF)
    1.14  
    1.15  #ifdef GRANT_DEBUG
    1.16 @@ -90,8 +84,6 @@ dump_packet(int tag, void *addr, u32 ap)
    1.17  
    1.18  #endif
    1.19  
    1.20 -
    1.21 -
    1.22  #ifndef __GFP_NOWARN
    1.23  #define __GFP_NOWARN 0
    1.24  #endif
    1.25 @@ -187,6 +179,11 @@ struct net_private
    1.26      struct sk_buff *tx_skbs[NETIF_TX_RING_SIZE+1];
    1.27      struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1];
    1.28  
    1.29 +    grant_ref_t gref_tx_head;
    1.30 +    grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1]; 
    1.31 +    grant_ref_t gref_rx_head;
    1.32 +    grant_ref_t grant_rx_ref[NETIF_TX_RING_SIZE + 1]; 
    1.33 +
    1.34  	struct xenbus_device *xbdev;
    1.35  	char *backend;
    1.36  	int backend_id;
    1.37 @@ -286,16 +283,16 @@ static void network_tx_buf_gc(struct net
    1.38              id  = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id;
    1.39              skb = np->tx_skbs[id];
    1.40  #ifdef CONFIG_XEN_NETDEV_GRANT
    1.41 -            if (unlikely(gnttab_query_foreign_access(grant_tx_ref[id]) != 0)) {
    1.42 +            if (unlikely(gnttab_query_foreign_access(np->grant_tx_ref[id]) != 0)) {
    1.43                  /* other domain is still using this grant - shouldn't happen
    1.44                     but if it does, we'll try to reclaim the grant later */
    1.45                  printk(KERN_ALERT "network_tx_buf_gc: warning -- grant "
    1.46                         "still in use by backend domain.\n");
    1.47                  goto out; 
    1.48              }
    1.49 -            gnttab_end_foreign_access_ref(grant_tx_ref[id], GNTMAP_readonly);
    1.50 -            gnttab_release_grant_reference(&gref_tx_head, grant_tx_ref[id]);
    1.51 -            grant_tx_ref[id] = GRANT_INVALID_REF;
    1.52 +            gnttab_end_foreign_access_ref(np->grant_tx_ref[id], GNTMAP_readonly);
    1.53 +            gnttab_release_grant_reference(&np->gref_tx_head, np->grant_tx_ref[id]);
    1.54 +            np->grant_tx_ref[id] = GRANT_INVALID_REF;
    1.55  #endif
    1.56              ADD_ID_TO_FREELIST(np->tx_skbs, id);
    1.57              dev_kfree_skb_irq(skb);
    1.58 @@ -372,12 +369,12 @@ static void network_alloc_rx_buffers(str
    1.59          
    1.60          np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id;
    1.61  #ifdef CONFIG_XEN_NETDEV_GRANT
    1.62 -	ref = gnttab_claim_grant_reference(&gref_rx_head);
    1.63 +	ref = gnttab_claim_grant_reference(&np->gref_rx_head);
    1.64          if (unlikely((signed short)ref < 0)) {
    1.65              printk(KERN_ALERT "#### netfront can't claim rx reference\n");
    1.66              BUG();
    1.67          }
    1.68 -        grant_rx_ref[id] = ref;
    1.69 +        np->grant_rx_ref[id] = ref;
    1.70          gnttab_grant_foreign_transfer_ref(ref, np->backend_id);
    1.71          np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.gref = ref;
    1.72  #endif
    1.73 @@ -470,7 +467,7 @@ static int network_start_xmit(struct sk_
    1.74  
    1.75      tx->id   = id;
    1.76  #ifdef CONFIG_XEN_NETDEV_GRANT
    1.77 -    ref = gnttab_claim_grant_reference(&gref_tx_head);
    1.78 +    ref = gnttab_claim_grant_reference(&np->gref_tx_head);
    1.79      if (unlikely((signed short)ref < 0)) {
    1.80          printk(KERN_ALERT "#### netfront can't claim tx grant reference\n");
    1.81          BUG();
    1.82 @@ -478,7 +475,7 @@ static int network_start_xmit(struct sk_
    1.83      mfn = virt_to_mfn(skb->data);
    1.84      gnttab_grant_foreign_access_ref(ref, np->backend_id, mfn, GNTMAP_readonly);
    1.85      tx->addr = ref << PAGE_SHIFT;
    1.86 -    grant_tx_ref[id] = ref;
    1.87 +    np->grant_tx_ref[id] = ref;
    1.88  #else
    1.89      tx->addr = virt_to_mfn(skb->data) << PAGE_SHIFT;
    1.90  #endif
    1.91 @@ -580,7 +577,7 @@ static int netif_poll(struct net_device 
    1.92          }
    1.93  
    1.94  #ifdef CONFIG_XEN_NETDEV_GRANT
    1.95 -        ref = grant_rx_ref[rx->id]; 
    1.96 +        ref = np->grant_rx_ref[rx->id]; 
    1.97  
    1.98          if(ref == GRANT_INVALID_REF) { 
    1.99              printk(KERN_WARNING "Bad rx grant reference %d from dom %d.\n",
   1.100 @@ -592,9 +589,9 @@ static int netif_poll(struct net_device 
   1.101              continue;
   1.102          }
   1.103  
   1.104 -        grant_rx_ref[rx->id] = GRANT_INVALID_REF;
   1.105 +        np->grant_rx_ref[rx->id] = GRANT_INVALID_REF;
   1.106          mfn = gnttab_end_foreign_transfer_ref(ref);
   1.107 -        gnttab_release_grant_reference(&gref_rx_head, ref);
   1.108 +        gnttab_release_grant_reference(&np->gref_rx_head, ref);
   1.109  #endif
   1.110  
   1.111          skb = np->rx_skbs[rx->id];
   1.112 @@ -803,10 +800,10 @@ static void network_connect(struct net_d
   1.113  
   1.114              tx->id   = i;
   1.115  #ifdef CONFIG_XEN_NETDEV_GRANT
   1.116 -            gnttab_grant_foreign_access_ref(grant_tx_ref[i], np->backend_id, 
   1.117 +            gnttab_grant_foreign_access_ref(np->grant_tx_ref[i], np->backend_id, 
   1.118                                              virt_to_mfn(np->tx_skbs[i]->data),
   1.119                                              GNTMAP_readonly); 
   1.120 -            tx->addr = grant_tx_ref[i] << PAGE_SHIFT; 
   1.121 +            tx->addr = np->grant_tx_ref[i] << PAGE_SHIFT; 
   1.122  #else
   1.123              tx->addr = virt_to_mfn(skb->data) << PAGE_SHIFT;
   1.124  #endif
   1.125 @@ -825,8 +822,8 @@ static void network_connect(struct net_d
   1.126          if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) {
   1.127  #ifdef CONFIG_XEN_NETDEV_GRANT 
   1.128              /* Reinstate the grant ref so backend can transfer mfn to us. */
   1.129 -            gnttab_grant_foreign_transfer_ref(grant_rx_ref[i], np->backend_id);
   1.130 -            np->rx->ring[requeue_idx].req.gref = grant_rx_ref[i];
   1.131 +            gnttab_grant_foreign_transfer_ref(np->grant_rx_ref[i], np->backend_id);
   1.132 +            np->rx->ring[requeue_idx].req.gref = np->grant_rx_ref[i];
   1.133  #endif
   1.134              np->rx->ring[requeue_idx].req.id   = i;
   1.135              requeue_idx++; 
   1.136 @@ -887,6 +884,15 @@ connect_device(struct net_private *np, u
   1.137  	show_device(np);
   1.138  }
   1.139  
   1.140 +static void netif_uninit(struct net_device *dev)
   1.141 +{
   1.142 +#ifdef CONFIG_XEN_NETDEV_GRANT
   1.143 +    struct net_private *np = netdev_priv(dev);
   1.144 +    gnttab_free_grant_references(np->gref_tx_head);
   1.145 +    gnttab_free_grant_references(np->gref_rx_head);
   1.146 +#endif
   1.147 +}
   1.148 +
   1.149  static struct ethtool_ops network_ethtool_ops =
   1.150  {
   1.151  	.get_tx_csum = ethtool_op_get_tx_csum,
   1.152 @@ -929,22 +935,39 @@ static int create_netdev(int handle, str
   1.153      for (i = 0; i <= NETIF_TX_RING_SIZE; i++) {
   1.154          np->tx_skbs[i] = (void *)((unsigned long) i+1);
   1.155  #ifdef CONFIG_XEN_NETDEV_GRANT
   1.156 -        grant_tx_ref[i] = GRANT_INVALID_REF;
   1.157 +        np->grant_tx_ref[i] = GRANT_INVALID_REF;
   1.158  #endif
   1.159      }
   1.160  
   1.161      for (i = 0; i <= NETIF_RX_RING_SIZE; i++) {
   1.162          np->rx_skbs[i] = (void *)((unsigned long) i+1);
   1.163  #ifdef CONFIG_XEN_NETDEV_GRANT
   1.164 -        grant_rx_ref[i] = GRANT_INVALID_REF;
   1.165 +        np->grant_rx_ref[i] = GRANT_INVALID_REF;
   1.166  #endif
   1.167      }
   1.168  
   1.169 +#ifdef CONFIG_XEN_NETDEV_GRANT
   1.170 +    /* A grant for every tx ring slot */
   1.171 +    if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE,
   1.172 +                                      &np->gref_tx_head) < 0) {
   1.173 +        printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
   1.174 +        goto exit;
   1.175 +    }
   1.176 +    /* A grant for every rx ring slot */
   1.177 +    if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE,
   1.178 +                                      &np->gref_rx_head) < 0) {
   1.179 +        printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
   1.180 +        gnttab_free_grant_references(np->gref_tx_head);
   1.181 +        goto exit;
   1.182 +    }
   1.183 +#endif
   1.184 +
   1.185      netdev->open            = network_open;
   1.186      netdev->hard_start_xmit = network_start_xmit;
   1.187      netdev->stop            = network_close;
   1.188      netdev->get_stats       = network_get_stats;
   1.189      netdev->poll            = netif_poll;
   1.190 +    netdev->uninit          = netif_uninit;
   1.191      netdev->weight          = 64;
   1.192      netdev->features        = NETIF_F_IP_CSUM;
   1.193  
   1.194 @@ -952,12 +975,12 @@ static int create_netdev(int handle, str
   1.195  
   1.196      if ((err = register_netdev(netdev)) != 0) {
   1.197          printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err);
   1.198 -        goto exit;
   1.199 +        goto exit_free_grefs;
   1.200      }
   1.201  
   1.202      if ((err = xennet_proc_addif(netdev)) != 0) {
   1.203          unregister_netdev(netdev);
   1.204 -        goto exit;
   1.205 +        goto exit_free_grefs;
   1.206      }
   1.207  
   1.208      np->netdev = netdev;
   1.209 @@ -968,17 +991,21 @@ static int create_netdev(int handle, str
   1.210      else if (val != NULL)
   1.211          *val = netdev;
   1.212      return err;
   1.213 +
   1.214 + exit_free_grefs:
   1.215 +#ifdef CONFIG_XEN_NETDEV_GRANT
   1.216 +    gnttab_free_grant_references(np->gref_tx_head);
   1.217 +    gnttab_free_grant_references(np->gref_rx_head);
   1.218 +#endif
   1.219 +    goto exit;
   1.220  }
   1.221  
   1.222  static int destroy_netdev(struct net_device *netdev)
   1.223  {
   1.224 -
   1.225  #ifdef CONFIG_PROC_FS
   1.226  	xennet_proc_delif(netdev);
   1.227  #endif
   1.228 -
   1.229          unregister_netdev(netdev);
   1.230 -
   1.231  	return 0;
   1.232  }
   1.233  
   1.234 @@ -1374,24 +1401,6 @@ static int __init netif_init(void)
   1.235  
   1.236      IPRINTK("Initialising virtual ethernet driver.\n");
   1.237  
   1.238 -#ifdef CONFIG_XEN_NETDEV_GRANT
   1.239 -    IPRINTK("Using grant tables.\n"); 
   1.240 -
   1.241 -    /* A grant for every tx ring slot */
   1.242 -    if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE,
   1.243 -                                      &gref_tx_head) < 0) {
   1.244 -        printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
   1.245 -        return 1;
   1.246 -    }
   1.247 -    /* A grant for every rx ring slot */
   1.248 -    if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE,
   1.249 -                                      &gref_rx_head) < 0) {
   1.250 -        printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
   1.251 -        return 1;
   1.252 -    }
   1.253 -#endif
   1.254 -
   1.255 -
   1.256      (void)register_inetaddr_notifier(&notifier_inetdev);
   1.257  
   1.258      init_net_xenbus();
   1.259 @@ -1403,10 +1412,6 @@ static int __init netif_init(void)
   1.260  
   1.261  static void netif_exit(void)
   1.262  {
   1.263 -#ifdef CONFIG_XEN_NETDEV_GRANT
   1.264 -    gnttab_free_grant_references(gref_tx_head);
   1.265 -    gnttab_free_grant_references(gref_rx_head);
   1.266 -#endif
   1.267  }
   1.268  
   1.269  #ifdef CONFIG_PROC_FS