aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2005-01-02 17:05:44 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2005-01-02 17:05:44 +0000
commitb52f7b088ba50aeeb98c7b015dd952301f36a28f (patch)
tree1400a7284c0bcb856aedf8bfd5f23003495aa99e
parentde1f2c532c1da58e9e93485eac12c293cd86df47 (diff)
downloadxen-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.h5
-rw-r--r--linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c75
-rw-r--r--linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c68
-rw-r--r--linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c25
-rwxr-xr-xtools/examples/vif-bridge1
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