debuggers.hg
changeset 6924: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>
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(¬ifier_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