Message ID | 20090325085333.4bb73f55@nehalam |
---|---|
State | Rejected, archived |
Delegated to: | David Miller |
Headers | show |
From: Stephen Hemminger <shemminger@vyatta.com> Date: Wed, 25 Mar 2009 08:53:33 -0700 > Overall, this looks like the wrong code (not copying back new skb) > and in awkward place. Also your version doesn't handle case where > skb headroom is not writable. headroom is always writable and usable by the driver, this is the exact same code sequence we use in drivers/net/niu.c for this purpose: len = sizeof(struct tx_pkt_hdr) + 15; if (skb_headroom(skb) < len) { struct sk_buff *skb_new; skb_new = skb_realloc_headroom(skb, len); if (!skb_new) { rp->tx_errors++; goto out_drop; } kfree_skb(skb); skb = skb_new; otherwise the code we just came from wouldn't be able to push even the ethernet header there. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
--- a/drivers/net/gianfar.c 2009-03-25 08:39:03.890718197 -0700 +++ b/drivers/net/gianfar.c 2009-03-25 08:51:39.733279404 -0700 @@ -1309,6 +1309,17 @@ static int gfar_start_xmit(struct sk_buf unsigned long flags; unsigned int nr_frags, length; + /* make sure there is space and can write FCB */ + if (!skb_clone_writeable(skb, GMAC_FCB_LEN)) { + struct sk_buff *skb2; + + skb2 = skb_realloc_headroom(skb, GMAC_FCB_LEN); + kfree_skb(skb); + if (!skb2) + return NETDEV_TX_OK; + skb = skb2; + } + base = priv->tx_bd_base; /* total number of fragments in the SKB */