提交 8cf0d9d0 编写于 作者: 提交者: Jeff Garzik

Automatic merge of /spare/repo/netdev-2.6 branch veth

...@@ -924,7 +924,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, ...@@ -924,7 +924,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
spin_lock_irqsave(&cnx->lock, flags); spin_lock_irqsave(&cnx->lock, flags);
if (! cnx->state & VETH_STATE_READY) if (! (cnx->state & VETH_STATE_READY))
goto drop; goto drop;
if ((skb->len - 14) > VETH_MAX_MTU) if ((skb->len - 14) > VETH_MAX_MTU)
...@@ -1023,6 +1023,8 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1023,6 +1023,8 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
lpmask = veth_transmit_to_many(skb, lpmask, dev); lpmask = veth_transmit_to_many(skb, lpmask, dev);
dev->trans_start = jiffies;
if (! lpmask) { if (! lpmask) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
} else { } else {
...@@ -1262,13 +1264,18 @@ static void veth_receive(struct veth_lpar_connection *cnx, ...@@ -1262,13 +1264,18 @@ static void veth_receive(struct veth_lpar_connection *cnx,
vlan = skb->data[9]; vlan = skb->data[9];
dev = veth_dev[vlan]; dev = veth_dev[vlan];
if (! dev) if (! dev) {
/* Some earlier versions of the driver sent /*
broadcasts down all connections, even to * Some earlier versions of the driver sent
lpars that weren't on the relevant vlan. * broadcasts down all connections, even to lpars
So ignore packets belonging to a vlan we're * that weren't on the relevant vlan. So ignore
not on. */ * packets belonging to a vlan we're not on.
* We can also be here if we receive packets while
* the driver is going down, because then dev is NULL.
*/
dev_kfree_skb_irq(skb);
continue; continue;
}
port = (struct veth_port *)dev->priv; port = (struct veth_port *)dev->priv;
dest = *((u64 *) skb->data) & 0xFFFFFFFFFFFF0000; dest = *((u64 *) skb->data) & 0xFFFFFFFFFFFF0000;
...@@ -1381,18 +1388,25 @@ void __exit veth_module_cleanup(void) ...@@ -1381,18 +1388,25 @@ void __exit veth_module_cleanup(void)
{ {
int i; int i;
vio_unregister_driver(&veth_driver); /* Stop the queues first to stop any new packets being sent. */
for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++)
if (veth_dev[i])
netif_stop_queue(veth_dev[i]);
/* Stop the connections before we unregister the driver. This
* ensures there's no skbs lying around holding the device open. */
for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
veth_stop_connection(i); veth_stop_connection(i);
HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan); HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);
/* Hypervisor callbacks may have scheduled more work while we /* Hypervisor callbacks may have scheduled more work while we
* were destroying connections. Now that we've disconnected from * were stoping connections. Now that we've disconnected from
* the hypervisor make sure everything's finished. */ * the hypervisor make sure everything's finished. */
flush_scheduled_work(); flush_scheduled_work();
vio_unregister_driver(&veth_driver);
for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
veth_destroy_connection(i); veth_destroy_connection(i);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册