aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-06-09 19:10:40 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-18 00:30:16 -0400
commit364c6badde0dd62a0a38e5ed67f85d87d6665780 (patch)
tree56c8ad3e3f45fafec010da4f5858825db5dbc86c /drivers
parent932ff279a43ab7257942cddff2595acd541cc49b (diff)
[NET]: Clean up skb_linearize
The linearisation operation doesn't need to be super-optimised. So we can replace __skb_linearize with __pskb_pull_tail which does the same thing but is more general. Also, most users of skb_linearize end up testing whether the skb is linear or not so it helps to make skb_linearize do just that. Some callers of skb_linearize also use it to copy cloned data, so it's useful to have a new function skb_linearize_cow to copy the data if it's either non-linear or cloned. Last but not least, I've removed the gfp argument since nobody uses it anymore. If it's ever needed we can easily add it back. Misc bugs fixed by this patch: * via-velocity error handling (also, no SG => no frags) Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/aoe/aoenet.c3
-rw-r--r--drivers/net/mv643xx_eth.c2
-rw-r--r--drivers/net/via-velocity.c10
3 files changed, 9 insertions, 6 deletions
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index fdff774b8ab9..c1434ed11880 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -116,8 +116,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
116 skb = skb_share_check(skb, GFP_ATOMIC); 116 skb = skb_share_check(skb, GFP_ATOMIC);
117 if (skb == NULL) 117 if (skb == NULL)
118 return 0; 118 return 0;
119 if (skb_is_nonlinear(skb)) 119 if (skb_linearize(skb))
120 if (skb_linearize(skb, GFP_ATOMIC) < 0)
121 goto exit; 120 goto exit;
122 if (!is_aoe_netif(ifp)) 121 if (!is_aoe_netif(ifp))
123 goto exit; 122 goto exit;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 411f4d809c47..625ff61c9988 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1200,7 +1200,7 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
1200 } 1200 }
1201 1201
1202 if (has_tiny_unaligned_frags(skb)) { 1202 if (has_tiny_unaligned_frags(skb)) {
1203 if ((skb_linearize(skb, GFP_ATOMIC) != 0)) { 1203 if (__skb_linearize(skb)) {
1204 stats->tx_dropped++; 1204 stats->tx_dropped++;
1205 printk(KERN_DEBUG "%s: failed to linearize tiny " 1205 printk(KERN_DEBUG "%s: failed to linearize tiny "
1206 "unaligned fragment\n", dev->name); 1206 "unaligned fragment\n", dev->name);
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index ed1f837c8fda..2eb6b5f9ba0d 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1899,6 +1899,13 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
1899 1899
1900 int pktlen = skb->len; 1900 int pktlen = skb->len;
1901 1901
1902#ifdef VELOCITY_ZERO_COPY_SUPPORT
1903 if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
1904 kfree_skb(skb);
1905 return 0;
1906 }
1907#endif
1908
1902 spin_lock_irqsave(&vptr->lock, flags); 1909 spin_lock_irqsave(&vptr->lock, flags);
1903 1910
1904 index = vptr->td_curr[qnum]; 1911 index = vptr->td_curr[qnum];
@@ -1914,8 +1921,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
1914 */ 1921 */
1915 if (pktlen < ETH_ZLEN) { 1922 if (pktlen < ETH_ZLEN) {
1916 /* Cannot occur until ZC support */ 1923 /* Cannot occur until ZC support */
1917 if(skb_linearize(skb, GFP_ATOMIC))
1918 return 0;
1919 pktlen = ETH_ZLEN; 1924 pktlen = ETH_ZLEN;
1920 memcpy(tdinfo->buf, skb->data, skb->len); 1925 memcpy(tdinfo->buf, skb->data, skb->len);
1921 memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len); 1926 memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
@@ -1933,7 +1938,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
1933 int nfrags = skb_shinfo(skb)->nr_frags; 1938 int nfrags = skb_shinfo(skb)->nr_frags;
1934 tdinfo->skb = skb; 1939 tdinfo->skb = skb;
1935 if (nfrags > 6) { 1940 if (nfrags > 6) {
1936 skb_linearize(skb, GFP_ATOMIC);
1937 memcpy(tdinfo->buf, skb->data, skb->len); 1941 memcpy(tdinfo->buf, skb->data, skb->len);
1938 tdinfo->skb_dma[0] = tdinfo->buf_dma; 1942 tdinfo->skb_dma[0] = tdinfo->buf_dma;
1939 td_ptr->tdesc0.pktsize = 1943 td_ptr->tdesc0.pktsize =