[PATCH] PPC64 iSeries fix virtual ethernet transmit block

Stephen Rothwell sfr at canb.auug.org.au
Mon May 31 18:40:26 EST 2004


Hi Linus, Andrew,

This patch fixes the virtual ethernet driver so that it will not block the
transmit queue indefinitely.  This patch appplies on top of the previous
patch from Rusty that removed skb_clone. There is one white space fix in
hte middle of this - I hope that doesn't offend :-).

Please apply.

Signed-off-by: Stephen Rothwell <sfr at canb.auug.org.au>

--
Cheers,
Stephen Rothwell                    sfr at canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
-------------- next part --------------
diff -ruN 2.6.7-rc2.wd.rusty/drivers/net/iseries_veth.c 2.6.7-rc2.wd.rusty.block/drivers/net/iseries_veth.c
--- 2.6.7-rc2.wd.rusty/drivers/net/iseries_veth.c	2004-05-31 18:10:30.000000000 +1000
+++ 2.6.7-rc2.wd.rusty.block/drivers/net/iseries_veth.c	2004-05-31 18:15:25.000000000 +1000
@@ -461,6 +461,11 @@
 		if (cnx->msgs)
 			for (i = 0; i < VETH_NUMBUFFERS; ++i)
 				veth_recycle_msg(cnx, cnx->msgs + i);
+		spin_unlock_irq(&cnx->lock);
+		veth_flush_pending(cnx);
+		spin_lock_irq(&cnx->lock);
+		if (cnx->state & VETH_STATE_RESET)
+			goto restart;
 	}

 	if (cnx->state & VETH_STATE_SHUTDOWN)
@@ -1020,27 +1025,28 @@
 		lpmask = port->lpar_map;
 	}

+	spin_lock_irqsave(&port->pending_gate, flags);
+
 	lpmask = veth_transmit_to_many(skb, lpmask, dev);

 	if (! lpmask) {
 		dev_kfree_skb(skb);
 	} else {
-		spin_lock_irqsave(&port->pending_gate, flags);
 		if (port->pending_skb) {
 			veth_error("%s: Tx while skb was pending!\n",
 				   dev->name);
 			dev_kfree_skb(skb);
-                       spin_unlock_irqrestore(&port->pending_gate, flags);
+			spin_unlock_irqrestore(&port->pending_gate, flags);
 			return 1;
 		}

 		port->pending_skb = skb;
 		port->pending_lpmask = lpmask;
 		netif_stop_queue(dev);
-
-		spin_unlock_irqrestore(&port->pending_gate, flags);
 	}

+	spin_unlock_irqrestore(&port->pending_gate, flags);
+
 	return 0;
 }

@@ -1094,7 +1100,7 @@
 			if (! port->pending_lpmask) {
 				dev_kfree_skb_any(port->pending_skb);
 				port->pending_skb = NULL;
-				netif_start_queue(dev);
+				netif_wake_queue(dev);
 			}
 		}
 		spin_unlock_irqrestore(&port->pending_gate, flags);


More information about the Linuxppc64-dev mailing list