aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
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 /net/core
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 'net/core')
-rw-r--r--net/core/dev.c63
1 files changed, 2 insertions, 61 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 1b09f1cae46e..91361bc2b682 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1222,64 +1222,6 @@ static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
1222#define illegal_highdma(dev, skb) (0) 1222#define illegal_highdma(dev, skb) (0)
1223#endif 1223#endif
1224 1224
1225/* Keep head the same: replace data */
1226int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
1227{
1228 unsigned int size;
1229 u8 *data;
1230 long offset;
1231 struct skb_shared_info *ninfo;
1232 int headerlen = skb->data - skb->head;
1233 int expand = (skb->tail + skb->data_len) - skb->end;
1234
1235 if (skb_shared(skb))
1236 BUG();
1237
1238 if (expand <= 0)
1239 expand = 0;
1240
1241 size = skb->end - skb->head + expand;
1242 size = SKB_DATA_ALIGN(size);
1243 data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
1244 if (!data)
1245 return -ENOMEM;
1246
1247 /* Copy entire thing */
1248 if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
1249 BUG();
1250
1251 /* Set up shinfo */
1252 ninfo = (struct skb_shared_info*)(data + size);
1253 atomic_set(&ninfo->dataref, 1);
1254 ninfo->tso_size = skb_shinfo(skb)->tso_size;
1255 ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
1256 ninfo->nr_frags = 0;
1257 ninfo->frag_list = NULL;
1258
1259 /* Offset between the two in bytes */
1260 offset = data - skb->head;
1261
1262 /* Free old data. */
1263 skb_release_data(skb);
1264
1265 skb->head = data;
1266 skb->end = data + size;
1267
1268 /* Set up new pointers */
1269 skb->h.raw += offset;
1270 skb->nh.raw += offset;
1271 skb->mac.raw += offset;
1272 skb->tail += offset;
1273 skb->data += offset;
1274
1275 /* We are no longer a clone, even if we were. */
1276 skb->cloned = 0;
1277
1278 skb->tail += skb->data_len;
1279 skb->data_len = 0;
1280 return 0;
1281}
1282
1283#define HARD_TX_LOCK(dev, cpu) { \ 1225#define HARD_TX_LOCK(dev, cpu) { \
1284 if ((dev->features & NETIF_F_LLTX) == 0) { \ 1226 if ((dev->features & NETIF_F_LLTX) == 0) { \
1285 netif_tx_lock(dev); \ 1227 netif_tx_lock(dev); \
@@ -1326,7 +1268,7 @@ int dev_queue_xmit(struct sk_buff *skb)
1326 1268
1327 if (skb_shinfo(skb)->frag_list && 1269 if (skb_shinfo(skb)->frag_list &&
1328 !(dev->features & NETIF_F_FRAGLIST) && 1270 !(dev->features & NETIF_F_FRAGLIST) &&
1329 __skb_linearize(skb, GFP_ATOMIC)) 1271 __skb_linearize(skb))
1330 goto out_kfree_skb; 1272 goto out_kfree_skb;
1331 1273
1332 /* Fragmented skb is linearized if device does not support SG, 1274 /* Fragmented skb is linearized if device does not support SG,
@@ -1335,7 +1277,7 @@ int dev_queue_xmit(struct sk_buff *skb)
1335 */ 1277 */
1336 if (skb_shinfo(skb)->nr_frags && 1278 if (skb_shinfo(skb)->nr_frags &&
1337 (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) && 1279 (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
1338 __skb_linearize(skb, GFP_ATOMIC)) 1280 __skb_linearize(skb))
1339 goto out_kfree_skb; 1281 goto out_kfree_skb;
1340 1282
1341 /* If packet is not checksummed and device does not support 1283 /* If packet is not checksummed and device does not support
@@ -3473,7 +3415,6 @@ subsys_initcall(net_dev_init);
3473EXPORT_SYMBOL(__dev_get_by_index); 3415EXPORT_SYMBOL(__dev_get_by_index);
3474EXPORT_SYMBOL(__dev_get_by_name); 3416EXPORT_SYMBOL(__dev_get_by_name);
3475EXPORT_SYMBOL(__dev_remove_pack); 3417EXPORT_SYMBOL(__dev_remove_pack);
3476EXPORT_SYMBOL(__skb_linearize);
3477EXPORT_SYMBOL(dev_valid_name); 3418EXPORT_SYMBOL(dev_valid_name);
3478EXPORT_SYMBOL(dev_add_pack); 3419EXPORT_SYMBOL(dev_add_pack);
3479EXPORT_SYMBOL(dev_alloc_name); 3420EXPORT_SYMBOL(dev_alloc_name);