summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-01-14 20:40:03 -0800
committerDavid S. Miller <davem@davemloft.net>2009-01-14 20:40:03 -0800
commitf557206800801410c30e53ce7a27219b2c4cf0ba (patch)
tree0c18a5766787a9dcc038eb60c8cbdf78c585ff6b
parentfc8c7dc1b29560c016a67a34ccff32a712b5aa86 (diff)
downloadop-kernel-dev-f557206800801410c30e53ce7a27219b2c4cf0ba.zip
op-kernel-dev-f557206800801410c30e53ce7a27219b2c4cf0ba.tar.gz
gro: Fix page ref count for skbs freed normally
When an skb with page frags is merged into an existing one, we cannibalise its reference count. This is OK when the skb is reused because we set nr_frags to zero in that case. However, for the case where the skb is freed through kfree_skb, we didn't clear nr_frags which causes the page to be freed prematurely. This is fixed by moving the skb resetting into skb_gro_receive. Reported-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/skbuff.c6
2 files changed, 6 insertions, 6 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 7dec715..60377b6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2491,12 +2491,6 @@ EXPORT_SYMBOL(napi_gro_receive);
void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
{
- skb_shinfo(skb)->nr_frags = 0;
-
- skb->len -= skb->data_len;
- skb->truesize -= skb->data_len;
- skb->data_len = 0;
-
__skb_pull(skb, skb_headlen(skb));
skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb));
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 5110b35..65eac77 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2602,6 +2602,12 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t));
skb_shinfo(p)->nr_frags += skb_shinfo(skb)->nr_frags;
+ skb_shinfo(skb)->nr_frags = 0;
+
+ skb->truesize -= skb->data_len;
+ skb->len -= skb->data_len;
+ skb->data_len = 0;
+
NAPI_GRO_CB(skb)->free = 1;
goto done;
}
OpenPOWER on IntegriCloud