diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2006-06-23 05:06:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-06-23 05:06:41 -0400 |
commit | 5b057c6b1a25d57edf2b4d1e956e50936480a9ff (patch) | |
tree | e641febd6f562e0ed1198c160ff353ab513f0612 /include/linux/skbuff.h | |
parent | 5fa21d821f6972e70942f2c555ec29dde962bdb2 (diff) |
[NET]: Avoid allocating skb in skb_pad
First of all it is unnecessary to allocate a new skb in skb_pad since
the existing one is not shared. More importantly, our hard_start_xmit
interface does not allow a new skb to be allocated since that breaks
requeueing.
This patch uses pskb_expand_head to expand the existing skb and linearize
it if needed. Actually, someone should sift through every instance of
skb_pad on a non-linear skb as they do not fit the reasons why this was
originally created.
Incidentally, this fixes a minor bug when the skb is cloned (tcpdump,
TCP, etc.). As it is skb_pad will simply write over a cloned skb. Because
of the position of the write it is unlikely to cause problems but still
it's best if we don't do it.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/skbuff.h')
-rw-r--r-- | include/linux/skbuff.h | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 66f8819f9568..f8c7eb79a27f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -345,7 +345,7 @@ extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, | |||
345 | extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb, | 345 | extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb, |
346 | int newheadroom, int newtailroom, | 346 | int newheadroom, int newtailroom, |
347 | gfp_t priority); | 347 | gfp_t priority); |
348 | extern struct sk_buff * skb_pad(struct sk_buff *skb, int pad); | 348 | extern int skb_pad(struct sk_buff *skb, int pad); |
349 | #define dev_kfree_skb(a) kfree_skb(a) | 349 | #define dev_kfree_skb(a) kfree_skb(a) |
350 | extern void skb_over_panic(struct sk_buff *skb, int len, | 350 | extern void skb_over_panic(struct sk_buff *skb, int len, |
351 | void *here); | 351 | void *here); |
@@ -1122,16 +1122,15 @@ static inline int skb_cow(struct sk_buff *skb, unsigned int headroom) | |||
1122 | * | 1122 | * |
1123 | * Pads up a buffer to ensure the trailing bytes exist and are | 1123 | * Pads up a buffer to ensure the trailing bytes exist and are |
1124 | * blanked. If the buffer already contains sufficient data it | 1124 | * blanked. If the buffer already contains sufficient data it |
1125 | * is untouched. Returns the buffer, which may be a replacement | 1125 | * is untouched. Otherwise it is extended. Returns zero on |
1126 | * for the original, or NULL for out of memory - in which case | 1126 | * success. The skb is freed on error. |
1127 | * the original buffer is still freed. | ||
1128 | */ | 1127 | */ |
1129 | 1128 | ||
1130 | static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) | 1129 | static inline int skb_padto(struct sk_buff *skb, unsigned int len) |
1131 | { | 1130 | { |
1132 | unsigned int size = skb->len; | 1131 | unsigned int size = skb->len; |
1133 | if (likely(size >= len)) | 1132 | if (likely(size >= len)) |
1134 | return skb; | 1133 | return 0; |
1135 | return skb_pad(skb, len-size); | 1134 | return skb_pad(skb, len-size); |
1136 | } | 1135 | } |
1137 | 1136 | ||