direct-io.hg
changeset 1831:51332b88e187
bitkeeper revision 1.1108.4.1 (40fccf15MMHXnf0_66am3vGFf6fVDA)
Merge net frontend drivers in 2.4 and 2.6.
Fix some bugs that would cause crashes in low-memory conditions.
There may well be some bugs still lurking, but better hidden than
before!
Merge net frontend drivers in 2.4 and 2.6.
Fix some bugs that would cause crashes in low-memory conditions.
There may well be some bugs still lurking, but better hidden than
before!
author | kaf24@scramble.cl.cam.ac.uk |
---|---|
date | Tue Jul 20 07:51:49 2004 +0000 (2004-07-20) |
parents | 1a488e40456a |
children | 79d5d57de7d1 |
files | .rootkeys linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c linux-2.4.26-xen-sparse/mkbuildtree linux-2.6.7-xen-sparse/drivers/xen/net/network.c |
line diff
1.1 --- a/.rootkeys Sun Jul 18 16:38:30 2004 +0000 1.2 +++ b/.rootkeys Tue Jul 20 07:51:49 2004 +0000 1.3 @@ -72,7 +72,6 @@ 4097ba83glWYwQTkbPqgLIlYDOPVLg linux-2.4 1.4 4097ba837h2tuiweIWp-voNVzCRI6g linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/interface.c 1.5 4087cf0d5dudKw_DecIJgOhLlBF_0Q linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c 1.6 405853f2wg7JXZJNltspMwOZJklxgw linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/Makefile 1.7 -405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c 1.8 4097ba83Qy2eafeFUhGhm6_4iMIIDw linux-2.4.26-xen-sparse/arch/xen/drivers/netif/netif.h 1.9 3e5a4e65lWzkiPXsZdzPt2RNnJGG1g linux-2.4.26-xen-sparse/arch/xen/kernel/Makefile 1.10 4075806dE5mQwlVUf8-t3YXjiMMWDQ linux-2.4.26-xen-sparse/arch/xen/kernel/ctrl_if.c 1.11 @@ -199,7 +198,7 @@ 40f56239KYxO0YabhPzCTeUuln-lnA linux-2.6 1.12 40f56239DoibTX6R-ZYd3QTXAB8_TA linux-2.6.7-xen-sparse/drivers/xen/evtchn/evtchn.c 1.13 40f56239lrg_Ob0BJ8WBFS1zeg2CYw linux-2.6.7-xen-sparse/drivers/xen/net/Kconfig 1.14 40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.7-xen-sparse/drivers/xen/net/Makefile 1.15 -40f56239vUsbJCS9tGFfRVi1YZlGEg linux-2.6.7-xen-sparse/drivers/xen/net/network.c 1.16 +405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.6.7-xen-sparse/drivers/xen/net/network.c 1.17 40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/desc.h 1.18 40f5623anSzpuEHgiNmQ56fIRfCoaQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/e820.h 1.19 40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h
2.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c Sun Jul 18 16:38:30 2004 +0000 2.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c Tue Jul 20 07:51:49 2004 +0000 2.3 @@ -495,7 +495,7 @@ static void net_tx_action(unsigned long 2.4 2.5 pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; 2.6 2.7 - if ( unlikely((skb = dev_alloc_skb(PKT_PROT_LEN)) == NULL) ) 2.8 + if ( unlikely((skb = alloc_skb(PKT_PROT_LEN+16, GFP_ATOMIC)) == NULL) ) 2.9 { 2.10 DPRINTK("Can't allocate a skb in start_xmit.\n"); 2.11 make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); 2.12 @@ -503,6 +503,9 @@ static void net_tx_action(unsigned long 2.13 break; 2.14 } 2.15 2.16 + /* Packets passed to netif_rx() must have some headroom. */ 2.17 + skb_reserve(skb, 16); 2.18 + 2.19 mcl[0].op = __HYPERVISOR_update_va_mapping_otherdomain; 2.20 mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT; 2.21 mcl[0].args[1] = (txreq.addr & PAGE_MASK) | __PAGE_KERNEL;
3.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c Sun Jul 18 16:38:30 2004 +0000 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,867 +0,0 @@ 3.4 -/****************************************************************************** 3.5 - * arch/xen/drivers/netif/frontend/main.c 3.6 - * 3.7 - * Virtual network driver for conversing with remote driver backends. 3.8 - * 3.9 - * Copyright (c) 2002-2004, K A Fraser 3.10 - */ 3.11 - 3.12 -#include <linux/config.h> 3.13 -#include <linux/module.h> 3.14 - 3.15 -#include <linux/kernel.h> 3.16 -#include <linux/sched.h> 3.17 -#include <linux/slab.h> 3.18 -#include <linux/string.h> 3.19 -#include <linux/errno.h> 3.20 - 3.21 -#include <linux/netdevice.h> 3.22 -#include <linux/inetdevice.h> 3.23 -#include <linux/etherdevice.h> 3.24 -#include <linux/skbuff.h> 3.25 -#include <linux/init.h> 3.26 - 3.27 -#include <asm/io.h> 3.28 -#include <net/sock.h> 3.29 -#include <net/pkt_sched.h> 3.30 - 3.31 -#include <asm/evtchn.h> 3.32 -#include <asm/ctrl_if.h> 3.33 - 3.34 -#include <asm/page.h> 3.35 - 3.36 -#include "../netif.h" 3.37 - 3.38 -#define RX_BUF_SIZE ((PAGE_SIZE/2)+1) /* Fool the slab allocator :-) */ 3.39 - 3.40 -static void network_tx_buf_gc(struct net_device *dev); 3.41 -static void network_alloc_rx_buffers(struct net_device *dev); 3.42 - 3.43 -static unsigned long rx_pfn_array[NETIF_RX_RING_SIZE]; 3.44 -static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1]; 3.45 -static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE]; 3.46 - 3.47 -static struct list_head dev_list; 3.48 - 3.49 -struct net_private 3.50 -{ 3.51 - struct list_head list; 3.52 - struct net_device *dev; 3.53 - 3.54 - struct net_device_stats stats; 3.55 - NETIF_RING_IDX rx_resp_cons, tx_resp_cons; 3.56 - unsigned int tx_full; 3.57 - 3.58 - netif_tx_interface_t *tx; 3.59 - netif_rx_interface_t *rx; 3.60 - 3.61 - spinlock_t tx_lock; 3.62 - spinlock_t rx_lock; 3.63 - 3.64 - unsigned int handle; 3.65 - unsigned int evtchn; 3.66 - unsigned int irq; 3.67 - 3.68 - /* What is the status of our connection to the remote backend? */ 3.69 -#define BEST_CLOSED 0 3.70 -#define BEST_DISCONNECTED 1 3.71 -#define BEST_CONNECTED 2 3.72 - unsigned int backend_state; 3.73 - 3.74 - /* Is this interface open or closed (down or up)? */ 3.75 -#define UST_CLOSED 0 3.76 -#define UST_OPEN 1 3.77 - unsigned int user_state; 3.78 - 3.79 - /* 3.80 - * {tx,rx}_skbs store outstanding skbuffs. The first entry in each 3.81 - * array is an index into a chain of free entries. 3.82 - */ 3.83 - struct sk_buff *tx_skbs[NETIF_TX_RING_SIZE+1]; 3.84 - struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1]; 3.85 -}; 3.86 - 3.87 -/* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */ 3.88 -#define ADD_ID_TO_FREELIST(_list, _id) \ 3.89 - (_list)[(_id)] = (_list)[0]; \ 3.90 - (_list)[0] = (void *)(unsigned long)(_id); 3.91 -#define GET_ID_FROM_FREELIST(_list) \ 3.92 - ({ unsigned long _id = (unsigned long)(_list)[0]; \ 3.93 - (_list)[0] = (_list)[_id]; \ 3.94 - (unsigned short)_id; }) 3.95 - 3.96 -static struct net_device *find_dev_by_handle(unsigned int handle) 3.97 -{ 3.98 - struct list_head *ent; 3.99 - struct net_private *np; 3.100 - list_for_each ( ent, &dev_list ) 3.101 - { 3.102 - np = list_entry(ent, struct net_private, list); 3.103 - if ( np->handle == handle ) 3.104 - return np->dev; 3.105 - } 3.106 - return NULL; 3.107 -} 3.108 - 3.109 -/** Network interface info. */ 3.110 -struct netif_ctrl { 3.111 - /** Number of interfaces. */ 3.112 - int interface_n; 3.113 - /** Number of connected interfaces. */ 3.114 - int connected_n; 3.115 - /** Error code. */ 3.116 - int err; 3.117 -}; 3.118 - 3.119 -static struct netif_ctrl netctrl; 3.120 - 3.121 -static void netctrl_init(void) 3.122 -{ 3.123 - memset(&netctrl, 0, sizeof(netctrl)); 3.124 - netctrl.interface_n = -1; 3.125 -} 3.126 - 3.127 -/** Get or set a network interface error. 3.128 - */ 3.129 -static int netctrl_err(int err) 3.130 -{ 3.131 - if(err < 0 && !netctrl.err){ 3.132 - netctrl.err = err; 3.133 - printk(KERN_WARNING "%s> err=%d\n", __FUNCTION__, err); 3.134 - } 3.135 - return netctrl.err; 3.136 -} 3.137 - 3.138 -/** Test if all network interfaces are connected. 3.139 - * 3.140 - * @return 1 if all connected, 0 if not, negative error code otherwise 3.141 - */ 3.142 -static int netctrl_connected(void) 3.143 -{ 3.144 - int ok = 0; 3.145 - ok = (netctrl.err ? netctrl.err : 3.146 - (netctrl.connected_n == netctrl.interface_n)); 3.147 - return ok; 3.148 -} 3.149 - 3.150 -/** Count the connected network interfaces. 3.151 - * 3.152 - * @return connected count 3.153 - */ 3.154 -static int netctrl_connected_count(void) 3.155 -{ 3.156 - 3.157 - struct list_head *ent; 3.158 - struct net_private *np; 3.159 - unsigned int connected; 3.160 - 3.161 - connected = 0; 3.162 - 3.163 - list_for_each(ent, &dev_list) 3.164 - { 3.165 - np = list_entry(ent, struct net_private, list); 3.166 - if ( np->backend_state == BEST_CONNECTED ) 3.167 - connected++; 3.168 - } 3.169 - 3.170 - netctrl.connected_n = connected; 3.171 - return connected; 3.172 -} 3.173 - 3.174 -static int network_open(struct net_device *dev) 3.175 -{ 3.176 - struct net_private *np = dev->priv; 3.177 - 3.178 - memset(&np->stats, 0, sizeof(np->stats)); 3.179 - 3.180 - np->user_state = UST_OPEN; 3.181 - 3.182 - network_alloc_rx_buffers(dev); 3.183 - np->rx->event = np->rx_resp_cons + 1; 3.184 - 3.185 - netif_start_queue(dev); 3.186 - 3.187 - return 0; 3.188 -} 3.189 - 3.190 - 3.191 -static void network_tx_buf_gc(struct net_device *dev) 3.192 -{ 3.193 - NETIF_RING_IDX i, prod; 3.194 - unsigned short id; 3.195 - struct net_private *np = dev->priv; 3.196 - struct sk_buff *skb; 3.197 - 3.198 - if ( np->backend_state != BEST_CONNECTED ) 3.199 - return; 3.200 - 3.201 - do { 3.202 - prod = np->tx->resp_prod; 3.203 - 3.204 - for ( i = np->tx_resp_cons; i != prod; i++ ) 3.205 - { 3.206 - id = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id; 3.207 - skb = np->tx_skbs[id]; 3.208 - ADD_ID_TO_FREELIST(np->tx_skbs, id); 3.209 - dev_kfree_skb_any(skb); 3.210 - } 3.211 - 3.212 - np->tx_resp_cons = prod; 3.213 - 3.214 - /* 3.215 - * Set a new event, then check for race with update of tx_cons. Note 3.216 - * that it is essential to schedule a callback, no matter how few 3.217 - * buffers are pending. Even if there is space in the transmit ring, 3.218 - * higher layers may be blocked because too much data is outstanding: 3.219 - * in such cases notification from Xen is likely to be the only kick 3.220 - * that we'll get. 3.221 - */ 3.222 - np->tx->event = 3.223 - prod + ((np->tx->req_prod - prod) >> 1) + 1; 3.224 - mb(); 3.225 - } 3.226 - while ( prod != np->tx->resp_prod ); 3.227 - 3.228 - if ( np->tx_full && 3.229 - ((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE) ) 3.230 - { 3.231 - np->tx_full = 0; 3.232 - if ( np->user_state == UST_OPEN ) 3.233 - netif_wake_queue(dev); 3.234 - } 3.235 -} 3.236 - 3.237 - 3.238 -static void network_alloc_rx_buffers(struct net_device *dev) 3.239 -{ 3.240 - unsigned short id; 3.241 - struct net_private *np = dev->priv; 3.242 - struct sk_buff *skb; 3.243 - NETIF_RING_IDX i = np->rx->req_prod; 3.244 - int nr_pfns = 0; 3.245 - 3.246 - /* Make sure the batch is large enough to be worthwhile (1/2 ring). */ 3.247 - if ( unlikely((i - np->rx_resp_cons) > (NETIF_RX_RING_SIZE/2)) || 3.248 - unlikely(np->backend_state != BEST_CONNECTED) ) 3.249 - return; 3.250 - 3.251 - do { 3.252 - skb = dev_alloc_skb(RX_BUF_SIZE); 3.253 - if ( unlikely(skb == NULL) ) 3.254 - break; 3.255 - 3.256 - skb->dev = dev; 3.257 - 3.258 - if ( unlikely(((unsigned long)skb->head & (PAGE_SIZE-1)) != 0) ) 3.259 - panic("alloc_skb needs to provide us page-aligned buffers."); 3.260 - 3.261 - id = GET_ID_FROM_FREELIST(np->rx_skbs); 3.262 - 3.263 - np->rx_skbs[id] = skb; 3.264 - 3.265 - np->rx->ring[MASK_NETIF_RX_IDX(i)].req.id = id; 3.266 - 3.267 - rx_pfn_array[nr_pfns] = virt_to_machine(skb->head) >> PAGE_SHIFT; 3.268 - 3.269 - rx_mcl[nr_pfns].op = __HYPERVISOR_update_va_mapping; 3.270 - rx_mcl[nr_pfns].args[0] = (unsigned long)skb->head >> PAGE_SHIFT; 3.271 - rx_mcl[nr_pfns].args[1] = 0; 3.272 - rx_mcl[nr_pfns].args[2] = 0; 3.273 - 3.274 - nr_pfns++; 3.275 - } 3.276 - while ( (++i - np->rx_resp_cons) != NETIF_RX_RING_SIZE ); 3.277 - 3.278 - /* 3.279 - * We may have allocated buffers which have entries outstanding in the page 3.280 - * update queue -- make sure we flush those first! 3.281 - */ 3.282 - flush_page_update_queue(); 3.283 - 3.284 - /* After all PTEs have been zapped we blow away stale TLB entries. */ 3.285 - rx_mcl[nr_pfns-1].args[2] = UVMF_FLUSH_TLB; 3.286 - 3.287 - /* Give away a batch of pages. */ 3.288 - rx_mcl[nr_pfns].op = __HYPERVISOR_dom_mem_op; 3.289 - rx_mcl[nr_pfns].args[0] = MEMOP_decrease_reservation; 3.290 - rx_mcl[nr_pfns].args[1] = (unsigned long)rx_pfn_array; 3.291 - rx_mcl[nr_pfns].args[2] = (unsigned long)nr_pfns; 3.292 - 3.293 - /* Zap PTEs and give away pages in one big multicall. */ 3.294 - (void)HYPERVISOR_multicall(rx_mcl, nr_pfns+1); 3.295 - 3.296 - /* Check return status of HYPERVISOR_dom_mem_op(). */ 3.297 - if ( rx_mcl[nr_pfns].args[5] != nr_pfns ) 3.298 - panic("Unable to reduce memory reservation\n"); 3.299 - 3.300 - np->rx->req_prod = i; 3.301 -} 3.302 - 3.303 - 3.304 -static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) 3.305 -{ 3.306 - unsigned short id; 3.307 - struct net_private *np = (struct net_private *)dev->priv; 3.308 - netif_tx_request_t *tx; 3.309 - NETIF_RING_IDX i; 3.310 - 3.311 - if ( unlikely(np->tx_full) ) 3.312 - { 3.313 - printk(KERN_ALERT "%s: full queue wasn't stopped!\n", dev->name); 3.314 - netif_stop_queue(dev); 3.315 - return -ENOBUFS; 3.316 - } 3.317 - 3.318 - if ( unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= 3.319 - PAGE_SIZE) ) 3.320 - { 3.321 - struct sk_buff *new_skb = dev_alloc_skb(RX_BUF_SIZE); 3.322 - if ( unlikely(new_skb == NULL) ) 3.323 - return 1; 3.324 - skb_put(new_skb, skb->len); 3.325 - memcpy(new_skb->data, skb->data, skb->len); 3.326 - dev_kfree_skb(skb); 3.327 - skb = new_skb; 3.328 - } 3.329 - 3.330 - spin_lock_irq(&np->tx_lock); 3.331 - 3.332 - if ( np->backend_state != BEST_CONNECTED ) 3.333 - { 3.334 - spin_unlock_irq(&np->tx_lock); 3.335 - return 1; 3.336 - } 3.337 - 3.338 - i = np->tx->req_prod; 3.339 - 3.340 - id = GET_ID_FROM_FREELIST(np->tx_skbs); 3.341 - np->tx_skbs[id] = skb; 3.342 - 3.343 - tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req; 3.344 - 3.345 - tx->id = id; 3.346 - tx->addr = virt_to_machine(skb->data); 3.347 - tx->size = skb->len; 3.348 - 3.349 - wmb(); 3.350 - np->tx->req_prod = i + 1; 3.351 - 3.352 - network_tx_buf_gc(dev); 3.353 - 3.354 - if ( (i - np->tx_resp_cons) == (NETIF_TX_RING_SIZE - 1) ) 3.355 - { 3.356 - np->tx_full = 1; 3.357 - netif_stop_queue(dev); 3.358 - } 3.359 - 3.360 - spin_unlock_irq(&np->tx_lock); 3.361 - 3.362 - np->stats.tx_bytes += skb->len; 3.363 - np->stats.tx_packets++; 3.364 - 3.365 - /* Only notify Xen if there are no outstanding responses. */ 3.366 - mb(); 3.367 - if ( np->tx->resp_prod == i ) 3.368 - notify_via_evtchn(np->evtchn); 3.369 - 3.370 - return 0; 3.371 -} 3.372 - 3.373 - 3.374 -static void netif_int(int irq, void *dev_id, struct pt_regs *ptregs) 3.375 -{ 3.376 - struct net_device *dev = dev_id; 3.377 - struct net_private *np = dev->priv; 3.378 - unsigned long flags; 3.379 - 3.380 - spin_lock_irqsave(&np->tx_lock, flags); 3.381 - network_tx_buf_gc(dev); 3.382 - spin_unlock_irqrestore(&np->tx_lock, flags); 3.383 - 3.384 - if ( (np->rx_resp_cons != np->rx->resp_prod) && 3.385 - (np->user_state == UST_OPEN) ) 3.386 - netif_rx_schedule(dev); 3.387 -} 3.388 - 3.389 - 3.390 -static int netif_poll(struct net_device *dev, int *pbudget) 3.391 -{ 3.392 - struct net_private *np = dev->priv; 3.393 - struct sk_buff *skb; 3.394 - netif_rx_response_t *rx; 3.395 - NETIF_RING_IDX i; 3.396 - mmu_update_t *mmu = rx_mmu; 3.397 - multicall_entry_t *mcl = rx_mcl; 3.398 - int work_done, budget, more_to_do = 1; 3.399 - struct sk_buff_head rxq; 3.400 - unsigned long flags; 3.401 - 3.402 - spin_lock(&np->rx_lock); 3.403 - 3.404 - if ( np->backend_state != BEST_CONNECTED ) 3.405 - { 3.406 - spin_unlock(&np->rx_lock); 3.407 - return 0; 3.408 - } 3.409 - 3.410 - skb_queue_head_init(&rxq); 3.411 - 3.412 - if ( (budget = *pbudget) > dev->quota ) 3.413 - budget = dev->quota; 3.414 - 3.415 - for ( i = np->rx_resp_cons, work_done = 0; 3.416 - (i != np->rx->resp_prod) && (work_done < budget); 3.417 - i++, work_done++ ) 3.418 - { 3.419 - rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp; 3.420 - 3.421 - skb = np->rx_skbs[rx->id]; 3.422 - ADD_ID_TO_FREELIST(np->rx_skbs, rx->id); 3.423 - 3.424 - if ( unlikely(rx->status <= 0) ) 3.425 - { 3.426 - /* Gate this error. We get a (valid) slew of them on suspend. */ 3.427 - if ( np->user_state != UST_OPEN ) 3.428 - printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status); 3.429 - dev_kfree_skb(skb); 3.430 - continue; 3.431 - } 3.432 - 3.433 - skb->data = skb->tail = skb->head + (rx->addr & ~PAGE_MASK); 3.434 - skb_put(skb, rx->status); 3.435 - 3.436 - np->stats.rx_packets++; 3.437 - np->stats.rx_bytes += rx->status; 3.438 - 3.439 - /* Remap the page. */ 3.440 - mmu->ptr = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE; 3.441 - mmu->val = __pa(skb->head) >> PAGE_SHIFT; 3.442 - mmu++; 3.443 - mcl->op = __HYPERVISOR_update_va_mapping; 3.444 - mcl->args[0] = (unsigned long)skb->head >> PAGE_SHIFT; 3.445 - mcl->args[1] = (rx->addr & PAGE_MASK) | __PAGE_KERNEL; 3.446 - mcl->args[2] = 0; 3.447 - mcl++; 3.448 - 3.449 - phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = 3.450 - rx->addr >> PAGE_SHIFT; 3.451 - 3.452 - __skb_queue_tail(&rxq, skb); 3.453 - } 3.454 - 3.455 - /* Do all the remapping work, and M->P updates, in one big hypercall. */ 3.456 - if ( likely((mcl - rx_mcl) != 0) ) 3.457 - { 3.458 - mcl->op = __HYPERVISOR_mmu_update; 3.459 - mcl->args[0] = (unsigned long)rx_mmu; 3.460 - mcl->args[1] = mmu - rx_mmu; 3.461 - mcl->args[2] = 0; 3.462 - mcl++; 3.463 - (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); 3.464 - } 3.465 - 3.466 - while ( (skb = __skb_dequeue(&rxq)) != NULL ) 3.467 - { 3.468 - /* Set the shared-info area, which is hidden behind the real data. */ 3.469 - atomic_set(&(skb_shinfo(skb)->dataref), 1); 3.470 - skb_shinfo(skb)->nr_frags = 0; 3.471 - skb_shinfo(skb)->frag_list = NULL; 3.472 - 3.473 - /* Ethernet-specific work. Delayed to here as it peeks the header. */ 3.474 - skb->protocol = eth_type_trans(skb, dev); 3.475 - 3.476 - /* Pass it up. */ 3.477 - netif_rx(skb); 3.478 - dev->last_rx = jiffies; 3.479 - } 3.480 - 3.481 - np->rx_resp_cons = i; 3.482 - 3.483 - network_alloc_rx_buffers(dev); 3.484 - 3.485 - *pbudget -= work_done; 3.486 - dev->quota -= work_done; 3.487 - 3.488 - if ( work_done < budget ) 3.489 - { 3.490 - local_irq_save(flags); 3.491 - 3.492 - np->rx->event = i + 1; 3.493 - 3.494 - /* Deal with hypervisor racing our resetting of rx_event. */ 3.495 - mb(); 3.496 - if ( np->rx->resp_prod == i ) 3.497 - { 3.498 - __netif_rx_complete(dev); 3.499 - more_to_do = 0; 3.500 - } 3.501 - 3.502 - local_irq_restore(flags); 3.503 - } 3.504 - 3.505 - spin_unlock(&np->rx_lock); 3.506 - 3.507 - return more_to_do; 3.508 -} 3.509 - 3.510 - 3.511 -static int network_close(struct net_device *dev) 3.512 -{ 3.513 - struct net_private *np = dev->priv; 3.514 - np->user_state = UST_CLOSED; 3.515 - netif_stop_queue(np->dev); 3.516 - return 0; 3.517 -} 3.518 - 3.519 - 3.520 -static struct net_device_stats *network_get_stats(struct net_device *dev) 3.521 -{ 3.522 - struct net_private *np = (struct net_private *)dev->priv; 3.523 - return &np->stats; 3.524 -} 3.525 - 3.526 - 3.527 -static void network_connect(struct net_device *dev, 3.528 - netif_fe_interface_status_changed_t *status) 3.529 -{ 3.530 - struct net_private *np; 3.531 - int i, requeue_idx; 3.532 - netif_tx_request_t *tx; 3.533 - 3.534 - np = dev->priv; 3.535 - spin_lock_irq(&np->rx_lock); 3.536 - spin_lock(&np->tx_lock); 3.537 - 3.538 - /* Recovery procedure: */ 3.539 - 3.540 - /* Step 1: Reinitialise variables. */ 3.541 - np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0; 3.542 - np->rx->event = 1; 3.543 - 3.544 - /* Step 2: Rebuild the RX and TX ring contents. 3.545 - * NB. We could just free the queued TX packets now but we hope 3.546 - * that sending them out might do some good. We have to rebuild 3.547 - * the RX ring because some of our pages are currently flipped out 3.548 - * so we can't just free the RX skbs. 3.549 - * NB2. Freelist index entries are always going to be less than 3.550 - * __PAGE_OFFSET, whereas pointers to skbs will always be equal or 3.551 - * greater than __PAGE_OFFSET: we use this property to distinguish 3.552 - * them. 3.553 - */ 3.554 - 3.555 - /* Rebuild the TX buffer freelist and the TX ring itself. 3.556 - * NB. This reorders packets. We could keep more private state 3.557 - * to avoid this but maybe it doesn't matter so much given the 3.558 - * interface has been down. 3.559 - */ 3.560 - for ( requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++ ) 3.561 - { 3.562 - if ( (unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET ) 3.563 - { 3.564 - struct sk_buff *skb = np->tx_skbs[i]; 3.565 - 3.566 - tx = &np->tx->ring[requeue_idx++].req; 3.567 - 3.568 - tx->id = i; 3.569 - tx->addr = virt_to_machine(skb->data); 3.570 - tx->size = skb->len; 3.571 - 3.572 - np->stats.tx_bytes += skb->len; 3.573 - np->stats.tx_packets++; 3.574 - } 3.575 - } 3.576 - wmb(); 3.577 - np->tx->req_prod = requeue_idx; 3.578 - 3.579 - /* Rebuild the RX buffer freelist and the RX ring itself. */ 3.580 - for ( requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++ ) 3.581 - if ( (unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET ) 3.582 - np->rx->ring[requeue_idx++].req.id = i; 3.583 - wmb(); 3.584 - np->rx->req_prod = requeue_idx; 3.585 - 3.586 - /* Step 3: All public and private state should now be sane. Get 3.587 - * ready to start sending and receiving packets and give the driver 3.588 - * domain a kick because we've probably just requeued some 3.589 - * packets. 3.590 - */ 3.591 - np->backend_state = BEST_CONNECTED; 3.592 - notify_via_evtchn(status->evtchn); 3.593 - network_tx_buf_gc(dev); 3.594 - 3.595 - if ( np->user_state == UST_OPEN ) 3.596 - netif_start_queue(dev); 3.597 - 3.598 - spin_unlock(&np->tx_lock); 3.599 - spin_unlock_irq(&np->rx_lock); 3.600 -} 3.601 - 3.602 -static void netif_status_change(netif_fe_interface_status_changed_t *status) 3.603 -{ 3.604 - ctrl_msg_t cmsg; 3.605 - netif_fe_interface_connect_t up; 3.606 - struct net_device *dev; 3.607 - struct net_private *np; 3.608 - 3.609 - if ( netctrl.interface_n <= 0 ) 3.610 - { 3.611 - printk(KERN_WARNING "Status change: no interfaces\n"); 3.612 - return; 3.613 - } 3.614 - 3.615 - dev = find_dev_by_handle(status->handle); 3.616 - if(!dev){ 3.617 - printk(KERN_WARNING "Status change: invalid netif handle %u\n", 3.618 - status->handle); 3.619 - return; 3.620 - } 3.621 - np = dev->priv; 3.622 - 3.623 - switch ( status->status ) 3.624 - { 3.625 - case NETIF_INTERFACE_STATUS_DESTROYED: 3.626 - printk(KERN_WARNING "Unexpected netif-DESTROYED message in state %d\n", 3.627 - np->backend_state); 3.628 - break; 3.629 - 3.630 - case NETIF_INTERFACE_STATUS_DISCONNECTED: 3.631 - if ( np->backend_state != BEST_CLOSED ) 3.632 - { 3.633 - printk(KERN_WARNING "Unexpected netif-DISCONNECTED message" 3.634 - " in state %d\n", np->backend_state); 3.635 - printk(KERN_INFO "Attempting to reconnect network interface\n"); 3.636 - 3.637 - /* Begin interface recovery. 3.638 - * 3.639 - * NB. Whilst we're recovering, we turn the carrier state off. We 3.640 - * take measures to ensure that this device isn't used for 3.641 - * anything. We also stop the queue for this device. Various 3.642 - * different approaches (e.g. continuing to buffer packets) have 3.643 - * been tested but don't appear to improve the overall impact on 3.644 - * TCP connections. 3.645 - * 3.646 - * TODO: (MAW) Change the Xend<->Guest protocol so that a recovery 3.647 - * is initiated by a special "RESET" message - disconnect could 3.648 - * just mean we're not allowed to use this interface any more. 3.649 - */ 3.650 - 3.651 - /* Stop old i/f to prevent errors whilst we rebuild the state. */ 3.652 - spin_lock_irq(&np->tx_lock); 3.653 - spin_lock(&np->rx_lock); 3.654 - netif_stop_queue(dev); 3.655 - np->backend_state = BEST_DISCONNECTED; 3.656 - spin_unlock(&np->rx_lock); 3.657 - spin_unlock_irq(&np->tx_lock); 3.658 - 3.659 - /* Free resources. */ 3.660 - free_irq(np->irq, dev); 3.661 - unbind_evtchn_from_irq(np->evtchn); 3.662 - free_page((unsigned long)np->tx); 3.663 - free_page((unsigned long)np->rx); 3.664 - } 3.665 - 3.666 - /* Move from CLOSED to DISCONNECTED state. */ 3.667 - np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL); 3.668 - np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL); 3.669 - memset(np->tx, 0, PAGE_SIZE); 3.670 - memset(np->rx, 0, PAGE_SIZE); 3.671 - np->backend_state = BEST_DISCONNECTED; 3.672 - 3.673 - /* Construct an interface-CONNECT message for the domain controller. */ 3.674 - cmsg.type = CMSG_NETIF_FE; 3.675 - cmsg.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT; 3.676 - cmsg.length = sizeof(netif_fe_interface_connect_t); 3.677 - up.handle = status->handle; 3.678 - up.tx_shmem_frame = virt_to_machine(np->tx) >> PAGE_SHIFT; 3.679 - up.rx_shmem_frame = virt_to_machine(np->rx) >> PAGE_SHIFT; 3.680 - memcpy(cmsg.msg, &up, sizeof(up)); 3.681 - 3.682 - /* Tell the controller to bring up the interface. */ 3.683 - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 3.684 - break; 3.685 - 3.686 - case NETIF_INTERFACE_STATUS_CONNECTED: 3.687 - if ( np->backend_state == BEST_CLOSED ) 3.688 - { 3.689 - printk(KERN_WARNING "Unexpected netif-CONNECTED message" 3.690 - " in state %d\n", np->backend_state); 3.691 - break; 3.692 - } 3.693 - 3.694 - memcpy(dev->dev_addr, status->mac, ETH_ALEN); 3.695 - 3.696 - network_connect(dev, status); 3.697 - 3.698 - np->evtchn = status->evtchn; 3.699 - np->irq = bind_evtchn_to_irq(np->evtchn); 3.700 - (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, 3.701 - dev->name, dev); 3.702 - 3.703 - netctrl_connected_count(); 3.704 - break; 3.705 - 3.706 - default: 3.707 - printk(KERN_WARNING "Status change to unknown value %d\n", 3.708 - status->status); 3.709 - break; 3.710 - } 3.711 -} 3.712 - 3.713 -/** Create a network device. 3.714 - * @param handle device handle 3.715 - * @param val return parameter for created device 3.716 - * @return 0 on success, error code otherwise 3.717 - */ 3.718 -static int create_netdev(int handle, struct net_device **val) 3.719 -{ 3.720 - int i, err = 0; 3.721 - struct net_device *dev = NULL; 3.722 - struct net_private *np = NULL; 3.723 - 3.724 - if ( (dev = alloc_etherdev(sizeof(struct net_private))) == NULL ) 3.725 - { 3.726 - printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__); 3.727 - err = -ENOMEM; 3.728 - goto exit; 3.729 - } 3.730 - 3.731 - np = dev->priv; 3.732 - np->backend_state = BEST_CLOSED; 3.733 - np->user_state = UST_CLOSED; 3.734 - np->handle = handle; 3.735 - 3.736 - spin_lock_init(&np->tx_lock); 3.737 - spin_lock_init(&np->rx_lock); 3.738 - 3.739 - /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ 3.740 - for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ ) 3.741 - np->tx_skbs[i] = (void *)(i+1); 3.742 - for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ ) 3.743 - np->rx_skbs[i] = (void *)(i+1); 3.744 - 3.745 - dev->open = network_open; 3.746 - dev->hard_start_xmit = network_start_xmit; 3.747 - dev->stop = network_close; 3.748 - dev->get_stats = network_get_stats; 3.749 - dev->poll = netif_poll; 3.750 - dev->weight = 64; 3.751 - 3.752 - if ( (err = register_netdev(dev)) != 0 ) 3.753 - { 3.754 - printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err); 3.755 - goto exit; 3.756 - } 3.757 - np->dev = dev; 3.758 - list_add(&np->list, &dev_list); 3.759 - 3.760 - exit: 3.761 - if ( (err != 0) && (dev != NULL ) ) 3.762 - kfree(dev); 3.763 - else if ( val != NULL ) 3.764 - *val = dev; 3.765 - return err; 3.766 -} 3.767 - 3.768 -/* 3.769 - * Initialize the network control interface. Set the number of network devices 3.770 - * and create them. 3.771 - */ 3.772 -static void netif_driver_status_change( 3.773 - netif_fe_driver_status_changed_t *status) 3.774 -{ 3.775 - int err = 0; 3.776 - int i; 3.777 - 3.778 - netctrl.interface_n = status->nr_interfaces; 3.779 - netctrl.connected_n = 0; 3.780 - 3.781 - for ( i = 0; i < netctrl.interface_n; i++ ) 3.782 - { 3.783 - if ( (err = create_netdev(i, NULL)) != 0 ) 3.784 - { 3.785 - netctrl_err(err); 3.786 - break; 3.787 - } 3.788 - } 3.789 -} 3.790 - 3.791 -static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) 3.792 -{ 3.793 - int respond = 1; 3.794 - 3.795 - switch ( msg->subtype ) 3.796 - { 3.797 - case CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED: 3.798 - if ( msg->length != sizeof(netif_fe_interface_status_changed_t) ) 3.799 - goto error; 3.800 - netif_status_change((netif_fe_interface_status_changed_t *) 3.801 - &msg->msg[0]); 3.802 - break; 3.803 - 3.804 - case CMSG_NETIF_FE_DRIVER_STATUS_CHANGED: 3.805 - if ( msg->length != sizeof(netif_fe_driver_status_changed_t) ) 3.806 - goto error; 3.807 - netif_driver_status_change((netif_fe_driver_status_changed_t *) 3.808 - &msg->msg[0]); 3.809 - /* Message is a response */ 3.810 - respond = 0; 3.811 - break; 3.812 - 3.813 - error: 3.814 - default: 3.815 - msg->length = 0; 3.816 - break; 3.817 - } 3.818 - 3.819 - if ( respond ) 3.820 - ctrl_if_send_response(msg); 3.821 -} 3.822 - 3.823 - 3.824 -static int __init netif_init(void) 3.825 -{ 3.826 - ctrl_msg_t cmsg; 3.827 - netif_fe_driver_status_changed_t st; 3.828 - int err = 0, wait_i, wait_n = 20; 3.829 - 3.830 - if ( (start_info.flags & SIF_INITDOMAIN) || 3.831 - (start_info.flags & SIF_NET_BE_DOMAIN) ) 3.832 - return 0; 3.833 - 3.834 - printk("Initialising Xen virtual ethernet frontend driver"); 3.835 - 3.836 - INIT_LIST_HEAD(&dev_list); 3.837 - 3.838 - netctrl_init(); 3.839 - 3.840 - (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx, 3.841 - CALLBACK_IN_BLOCKING_CONTEXT); 3.842 - 3.843 - /* Send a driver-UP notification to the domain controller. */ 3.844 - cmsg.type = CMSG_NETIF_FE; 3.845 - cmsg.subtype = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED; 3.846 - cmsg.length = sizeof(netif_fe_driver_status_changed_t); 3.847 - st.status = NETIF_DRIVER_STATUS_UP; 3.848 - st.nr_interfaces = 0; 3.849 - memcpy(cmsg.msg, &st, sizeof(st)); 3.850 - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 3.851 - 3.852 - /* Wait for all interfaces to be connected. */ 3.853 - for ( wait_i = 0; ; wait_i++) 3.854 - { 3.855 - if ( (err = (wait_i < wait_n) ? netctrl_connected() : -ENETDOWN) != 0 ) 3.856 - { 3.857 - err = (err > 0) ? 0 : err; 3.858 - break; 3.859 - } 3.860 - set_current_state(TASK_INTERRUPTIBLE); 3.861 - schedule_timeout(1); 3.862 - } 3.863 - 3.864 - if ( err ) 3.865 - ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx); 3.866 - 3.867 - return err; 3.868 -} 3.869 - 3.870 -__initcall(netif_init);
4.1 --- a/linux-2.4.26-xen-sparse/mkbuildtree Sun Jul 18 16:38:30 2004 +0000 4.2 +++ b/linux-2.4.26-xen-sparse/mkbuildtree Tue Jul 20 07:51:49 2004 +0000 4.3 @@ -225,5 +225,5 @@ ln -sf ../../i386/mm/extable.c 4.4 ln -sf ../../i386/mm/pageattr.c 4.5 cd ../drivers/console 4.6 ln -sf ../../../../${LINUX_26}/drivers/xen/console/console.c 4.7 -#cd ../netif/frontend 4.8 -#ln -sf ../../../../../${LINUX_26}/drivers/xen/net/network.c main.c 4.9 +cd ../netif/frontend 4.10 +ln -sf ../../../../../${LINUX_26}/drivers/xen/net/network.c main.c
5.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/net/network.c Sun Jul 18 16:38:30 2004 +0000 5.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/net/network.c Tue Jul 20 07:51:49 2004 +0000 5.3 @@ -1,6 +1,4 @@ 5.4 /****************************************************************************** 5.5 - * network.c 5.6 - * 5.7 * Virtual network driver for conversing with remote driver backends. 5.8 * 5.9 * Copyright (c) 2002-2004, K A Fraser 5.10 @@ -8,13 +6,12 @@ 5.11 5.12 #include <linux/config.h> 5.13 #include <linux/module.h> 5.14 - 5.15 +#include <linux/version.h> 5.16 #include <linux/kernel.h> 5.17 #include <linux/sched.h> 5.18 #include <linux/slab.h> 5.19 #include <linux/string.h> 5.20 #include <linux/errno.h> 5.21 - 5.22 #include <linux/netdevice.h> 5.23 #include <linux/inetdevice.h> 5.24 #include <linux/etherdevice.h> 5.25 @@ -30,7 +27,13 @@ 5.26 5.27 #include <asm/page.h> 5.28 5.29 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 5.30 #include <asm-xen/netif.h> 5.31 +#else 5.32 +#include "../netif.h" 5.33 +#define irqreturn_t void 5.34 +#define IRQ_HANDLED 5.35 +#endif 5.36 5.37 #define RX_BUF_SIZE ((PAGE_SIZE/2)+1) /* Fool the slab allocator :-) */ 5.38 5.39 @@ -368,7 +371,7 @@ static int network_start_xmit(struct sk_ 5.40 } 5.41 5.42 5.43 -static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs) 5.44 +static void netif_int(int irq, void *dev_id, struct pt_regs *ptregs) 5.45 { 5.46 struct net_device *dev = dev_id; 5.47 struct net_private *np = dev->priv; 5.48 @@ -381,8 +384,6 @@ static irqreturn_t netif_int(int irq, vo 5.49 if ( (np->rx_resp_cons != np->rx->resp_prod) && 5.50 (np->user_state == UST_OPEN) ) 5.51 netif_rx_schedule(dev); 5.52 - 5.53 - return IRQ_HANDLED; 5.54 } 5.55 5.56 5.57 @@ -417,18 +418,25 @@ static int netif_poll(struct net_device 5.58 { 5.59 rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp; 5.60 5.61 - skb = np->rx_skbs[rx->id]; 5.62 - ADD_ID_TO_FREELIST(np->rx_skbs, rx->id); 5.63 - 5.64 + /* 5.65 + * An error here is very odd. Usually indicates a backend bug, 5.66 + * low-memory condition, or that we didn't have reservation headroom. 5.67 + * Whatever - print an error and queue the id again straight away. 5.68 + */ 5.69 if ( unlikely(rx->status <= 0) ) 5.70 { 5.71 /* Gate this error. We get a (valid) slew of them on suspend. */ 5.72 - if ( np->user_state != UST_OPEN ) 5.73 + if ( np->user_state == UST_OPEN ) 5.74 printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status); 5.75 - dev_kfree_skb(skb); 5.76 + np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id; 5.77 + wmb(); 5.78 + np->rx->req_prod++; 5.79 continue; 5.80 } 5.81 5.82 + skb = np->rx_skbs[rx->id]; 5.83 + ADD_ID_TO_FREELIST(np->rx_skbs, rx->id); 5.84 + 5.85 skb->data = skb->tail = skb->head + (rx->addr & ~PAGE_MASK); 5.86 skb_put(skb, rx->status); 5.87