diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2005-01-02 17:05:44 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2005-01-02 17:05:44 +0000 |
commit | b52f7b088ba50aeeb98c7b015dd952301f36a28f (patch) | |
tree | 1400a7284c0bcb856aedf8bfd5f23003495aa99e | |
parent | de1f2c532c1da58e9e93485eac12c293cd86df47 (diff) | |
download | xen-b52f7b088ba50aeeb98c7b015dd952301f36a28f.tar.gz xen-b52f7b088ba50aeeb98c7b015dd952301f36a28f.tar.bz2 xen-b52f7b088ba50aeeb98c7b015dd952301f36a28f.zip |
bitkeeper revision 1.1159.170.78 (41d829e8lHqACg7gEEHdWaU-Jb1YdQ)
Network driver fixes.
-rw-r--r-- | linux-2.6.10-xen-sparse/drivers/xen/netback/common.h | 5 | ||||
-rw-r--r-- | linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c | 75 | ||||
-rw-r--r-- | linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c | 68 | ||||
-rw-r--r-- | linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c | 25 | ||||
-rwxr-xr-x | tools/examples/vif-bridge | 1 |
5 files changed, 89 insertions, 85 deletions
diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/common.h b/linux-2.6.10-xen-sparse/drivers/xen/netback/common.h index a8eeac8aac..0831cbe311 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netback/common.h +++ b/linux-2.6.10-xen-sparse/drivers/xen/netback/common.h @@ -59,6 +59,7 @@ typedef struct netif_st { /* Miscellaneous private stuff. */ enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; + int active; /* * DISCONNECT response is deferred until pending requests are ack'ed. * We therefore need to store the id from the original request. @@ -67,7 +68,6 @@ typedef struct netif_st { struct netif_st *hash_next; struct list_head list; /* scheduling list */ atomic_t refcnt; - spinlock_t rx_lock, tx_lock; struct net_device *dev; struct net_device_stats stats; @@ -90,7 +90,8 @@ netif_t *netif_find_by_handle(domid_t domid, unsigned int handle); void netif_interface_init(void); void netif_ctrlif_init(void); -void netif_deschedule(netif_t *netif); +void netif_schedule_work(netif_t *netif); +void netif_deschedule_work(netif_t *netif); int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev); struct net_device_stats *netif_be_get_stats(struct net_device *dev); diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c index 8de03f644b..9a3eea5932 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c @@ -27,6 +27,44 @@ netif_t *netif_find_by_handle(domid_t domid, unsigned int handle) return netif; } +static void __netif_up(netif_t *netif) +{ + struct net_device *dev = netif->dev; + spin_lock_bh(&dev->xmit_lock); + netif->active = 1; + spin_unlock_bh(&dev->xmit_lock); + (void)request_irq(netif->irq, netif_be_int, 0, dev->name, netif); + netif_schedule_work(netif); +} + +static void __netif_down(netif_t *netif) +{ + struct net_device *dev = netif->dev; + spin_lock_bh(&dev->xmit_lock); + netif->active = 0; + spin_unlock_bh(&dev->xmit_lock); + free_irq(netif->irq, netif); + netif_deschedule_work(netif); +} + +static int net_open(struct net_device *dev) +{ + netif_t *netif = netdev_priv(dev); + if ( netif->status == CONNECTED ) + __netif_up(netif); + netif_start_queue(dev); + return 0; +} + +static int net_close(struct net_device *dev) +{ + netif_t *netif = netdev_priv(dev); + netif_stop_queue(dev); + if ( netif->status == CONNECTED ) + __netif_down(netif); + return 0; +} + static void __netif_disconnect_complete(void *arg) { netif_t *netif = (netif_t *)arg; @@ -40,9 +78,6 @@ static void __netif_disconnect_complete(void *arg) */ unbind_evtchn_from_irq(netif->evtchn); vfree(netif->tx); /* Frees netif->rx as well. */ - rtnl_lock(); - (void)dev_close(netif->dev); - rtnl_unlock(); /* Construct the deferred response message. */ cmsg.type = CMSG_NETIF_BE; @@ -95,13 +130,11 @@ void netif_create(netif_be_create_t *create) return; } - netif = dev->priv; + netif = netdev_priv(dev); memset(netif, 0, sizeof(*netif)); netif->domid = domid; netif->handle = handle; netif->status = DISCONNECTED; - spin_lock_init(&netif->rx_lock); - spin_lock_init(&netif->tx_lock); atomic_set(&netif->refcnt, 0); netif->dev = dev; @@ -124,6 +157,8 @@ void netif_create(netif_be_create_t *create) dev->hard_start_xmit = netif_be_start_xmit; dev->get_stats = netif_be_get_stats; + dev->open = net_open; + dev->stop = net_close; /* Disable queuing. */ dev->tx_queue_len = 0; @@ -136,7 +171,11 @@ void netif_create(netif_be_create_t *create) memset(dev->dev_addr, 0xFF, ETH_ALEN); dev->dev_addr[0] &= ~0x01; - if ( (err = register_netdev(dev)) != 0 ) + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + + if ( err != 0 ) { DPRINTK("Could not register new net device %s: err=%d\n", dev->name, err); @@ -249,18 +288,17 @@ void netif_connect(netif_be_connect_t *connect) (netif_tx_interface_t *)vma->addr; netif->rx = (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE); - netif->status = CONNECTED; - netif_get(netif); - netif->tx->resp_prod = netif->rx->resp_prod = 0; + netif_get(netif); + wmb(); /* Other CPUs see new state before interface is started. */ rtnl_lock(); - (void)dev_open(netif->dev); + netif->status = CONNECTED; + wmb(); + if ( netif_running(netif->dev) ) + __netif_up(netif); rtnl_unlock(); - (void)request_irq(netif->irq, netif_be_int, 0, netif->dev->name, netif); - netif_start_queue(netif->dev); - connect->status = NETIF_BE_STATUS_OKAY; } @@ -281,12 +319,13 @@ int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id) if ( netif->status == CONNECTED ) { + rtnl_lock(); netif->status = DISCONNECTING; netif->disconnect_rspid = rsp_id; - wmb(); /* Let other CPUs see the status change. */ - netif_stop_queue(netif->dev); - free_irq(netif->irq, netif); - netif_deschedule(netif); + wmb(); + if ( netif_running(netif->dev) ) + __netif_down(netif); + rtnl_unlock(); netif_put(netif); return 0; /* Caller should not send response message. */ } diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c index 41d947bacf..d45b0c3f59 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c @@ -58,7 +58,6 @@ static PEND_RING_IDX pending_prod, pending_cons; /* Freed TX SKBs get batched on this ring before return to pending_ring. */ static u16 dealloc_ring[MAX_PENDING_REQS]; -static spinlock_t dealloc_lock = SPIN_LOCK_UNLOCKED; static PEND_RING_IDX dealloc_prod, dealloc_cons; static struct sk_buff_head tx_queue; @@ -122,12 +121,13 @@ static inline int is_xen_skb(struct sk_buff *skb) int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) { - netif_t *netif = (netif_t *)dev->priv; + netif_t *netif = netdev_priv(dev); ASSERT(skb->dev == dev); /* Drop the packet if the target domain has no receive buffers. */ - if ( (netif->rx_req_cons == netif->rx->req_prod) || + if ( !netif->active || + (netif->rx_req_cons == netif->rx->req_prod) || ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE) ) goto drop; @@ -153,6 +153,7 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) } netif->rx_req_cons++; + netif_get(netif); skb_queue_tail(&rx_queue, skb); tasklet_schedule(&net_rx_tasklet); @@ -203,7 +204,7 @@ static void net_rx_action(unsigned long unused) mmu = rx_mmu; while ( (skb = skb_dequeue(&rx_queue)) != NULL ) { - netif = (netif_t *)skb->dev->priv; + netif = netdev_priv(skb->dev); vdata = (unsigned long)skb->data; mdata = virt_to_machine(vdata); @@ -213,6 +214,7 @@ static void net_rx_action(unsigned long unused) if ( net_ratelimit() ) printk(KERN_WARNING "Memory squeeze in netback driver.\n"); mod_timer(&net_timer, jiffies + HZ); + skb_queue_head(&rx_queue, skb); break; } @@ -260,7 +262,7 @@ static void net_rx_action(unsigned long unused) mmu = rx_mmu; while ( (skb = __skb_dequeue(&rxq)) != NULL ) { - netif = (netif_t *)skb->dev->priv; + netif = netdev_priv(skb->dev); size = skb->tail - skb->data; /* Rederive the machine addresses. */ @@ -297,6 +299,7 @@ static void net_rx_action(unsigned long unused) notify_list[notify_nr++] = evtchn; } + netif_put(netif); dev_kfree_skb(skb); mcl += 2; @@ -326,7 +329,7 @@ static void net_alarm(unsigned long unused) struct net_device_stats *netif_be_get_stats(struct net_device *dev) { - netif_t *netif = dev->priv; + netif_t *netif = netdev_priv(dev); return &netif->stats; } @@ -353,7 +356,7 @@ static void add_to_net_schedule_list_tail(netif_t *netif) return; spin_lock_irq(&net_schedule_list_lock); - if ( !__on_net_schedule_list(netif) && (netif->status == CONNECTED) ) + if ( !__on_net_schedule_list(netif) && netif->active ) { list_add_tail(&netif->list, &net_schedule_list); netif_get(netif); @@ -361,7 +364,7 @@ static void add_to_net_schedule_list_tail(netif_t *netif) spin_unlock_irq(&net_schedule_list_lock); } -static inline void netif_schedule_work(netif_t *netif) +void netif_schedule_work(netif_t *netif) { if ( (netif->tx_req_cons != netif->tx->req_prod) && ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE) ) @@ -371,7 +374,7 @@ static inline void netif_schedule_work(netif_t *netif) } } -void netif_deschedule(netif_t *netif) +void netif_deschedule_work(netif_t *netif) { remove_from_net_schedule_list(netif); } @@ -426,10 +429,8 @@ static void net_tx_action(unsigned long unused) netif = pending_tx_info[pending_idx].netif; - spin_lock(&netif->tx_lock); make_tx_response(netif, pending_tx_info[pending_idx].req.id, NETIF_RSP_OKAY); - spin_unlock(&netif->tx_lock); pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; @@ -630,11 +631,12 @@ static void net_tx_action(unsigned long unused) static void netif_idx_release(u16 pending_idx) { + static spinlock_t _lock = SPIN_LOCK_UNLOCKED; unsigned long flags; - spin_lock_irqsave(&dealloc_lock, flags); + spin_lock_irqsave(&_lock, flags); dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx; - spin_unlock_irqrestore(&dealloc_lock, flags); + spin_unlock_irqrestore(&_lock, flags); tasklet_schedule(&net_tx_tasklet); } @@ -657,46 +659,6 @@ static void netif_skb_release(struct sk_buff *skb) netif_idx_release(pending_idx); } -#if 0 -long flush_bufs_for_netif(netif_t *netif) -{ - NETIF_RING_IDX i; - - /* Return any outstanding receive buffers to the guest OS. */ - spin_lock(&netif->rx_lock); - for ( i = netif->rx_req_cons; - (i != netif->rx->req_prod) && - ((i-netif->rx_resp_prod) != NETIF_RX_RING_SIZE); - i++ ) - { - make_rx_response(netif, - netif->rx->ring[MASK_NETIF_RX_IDX(i)].req.id, - NETIF_RSP_DROPPED, 0, 0); - } - netif->rx_req_cons = i; - spin_unlock(&netif->rx_lock); - - /* - * Flush pending transmit buffers. The guest may still have to wait for - * buffers that are queued at a physical NIC. - */ - spin_lock(&netif->tx_lock); - for ( i = netif->tx_req_cons; - (i != netif->tx->req_prod) && - ((i-netif->tx_resp_prod) != NETIF_TX_RING_SIZE); - i++ ) - { - make_tx_response(netif, - netif->tx->ring[MASK_NETIF_TX_IDX(i)].req.id, - NETIF_RSP_DROPPED); - } - netif->tx_req_cons = i; - spin_unlock(&netif->tx_lock); - - return 0; -} -#endif - irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs) { netif_t *netif = dev_id; diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c index d2b96cbe0f..01bea1e6fc 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c @@ -277,7 +277,7 @@ static int vif_wake(struct net_device *dev) static int network_open(struct net_device *dev) { - struct net_private *np = dev->priv; + struct net_private *np = netdev_priv(dev); memset(&np->stats, 0, sizeof(np->stats)); @@ -295,7 +295,7 @@ static void network_tx_buf_gc(struct net_device *dev) { NETIF_RING_IDX i, prod; unsigned short id; - struct net_private *np = dev->priv; + struct net_private *np = netdev_priv(dev); struct sk_buff *skb; if ( np->backend_state != BEST_CONNECTED ) @@ -342,7 +342,7 @@ static void network_tx_buf_gc(struct net_device *dev) static void network_alloc_rx_buffers(struct net_device *dev) { unsigned short id; - struct net_private *np = dev->priv; + struct net_private *np = netdev_priv(dev); struct sk_buff *skb; int i, batch_target; NETIF_RING_IDX req_prod = np->rx->req_prod; @@ -433,7 +433,7 @@ static void network_alloc_rx_buffers(struct net_device *dev) static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned short id; - struct net_private *np = (struct net_private *)dev->priv; + struct net_private *np = netdev_priv(dev); netif_tx_request_t *tx; NETIF_RING_IDX i; @@ -509,7 +509,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs) { struct net_device *dev = dev_id; - struct net_private *np = dev->priv; + struct net_private *np = netdev_priv(dev); unsigned long flags; spin_lock_irqsave(&np->tx_lock, flags); @@ -526,7 +526,7 @@ static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs) static int netif_poll(struct net_device *dev, int *pbudget) { - struct net_private *np = dev->priv; + struct net_private *np = netdev_priv(dev); struct sk_buff *skb, *nskb; netif_rx_response_t *rx; NETIF_RING_IDX i, rp; @@ -704,7 +704,7 @@ static int netif_poll(struct net_device *dev, int *pbudget) static int network_close(struct net_device *dev) { - struct net_private *np = dev->priv; + struct net_private *np = netdev_priv(dev); np->user_state = UST_CLOSED; netif_stop_queue(np->dev); return 0; @@ -713,7 +713,7 @@ static int network_close(struct net_device *dev) static struct net_device_stats *network_get_stats(struct net_device *dev) { - struct net_private *np = (struct net_private *)dev->priv; + struct net_private *np = netdev_priv(dev); return &np->stats; } @@ -725,7 +725,7 @@ static void network_connect(struct net_device *dev, int i, requeue_idx; netif_tx_request_t *tx; - np = dev->priv; + np = netdev_priv(dev); spin_lock_irq(&np->tx_lock); spin_lock(&np->rx_lock); @@ -889,7 +889,8 @@ static void vif_close(struct net_private *np) * Allocates tx/rx pages. * Sends connect message to xend. */ -static void vif_disconnect(struct net_private *np){ +static void vif_disconnect(struct net_private *np) +{ DPRINTK(">\n"); if(np->tx) free_page((unsigned long)np->tx); if(np->rx) free_page((unsigned long)np->rx); @@ -967,7 +968,7 @@ static int create_netdev(int handle, struct net_device **val) goto exit; } - np = dev->priv; + np = netdev_priv(dev); np->backend_state = BEST_CLOSED; np->user_state = UST_CLOSED; np->handle = handle; @@ -1046,7 +1047,7 @@ target_vif( exit: if ( np != NULL ) - *np = ((dev && !err) ? dev->priv : NULL); + *np = ((dev && !err) ? netdev_priv(dev) : NULL); DPRINTK("< err=%d\n", err); return err; } diff --git a/tools/examples/vif-bridge b/tools/examples/vif-bridge index 505ac1ec51..42bdf0e173 100755 --- a/tools/examples/vif-bridge +++ b/tools/examples/vif-bridge @@ -76,6 +76,7 @@ fi # Add/remove vif to/from bridge. brctl ${brcmd} ${bridge} ${vif} +ifconfig ${vif} $OP if [ ${ip} ] ; then |