提交 f5572068 编写于 作者: H Herbert Xu 提交者: David S. Miller

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: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: NHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 fc8c7dc1
...@@ -2491,12 +2491,6 @@ EXPORT_SYMBOL(napi_gro_receive); ...@@ -2491,12 +2491,6 @@ EXPORT_SYMBOL(napi_gro_receive);
void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) 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_pull(skb, skb_headlen(skb));
skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb));
......
...@@ -2602,6 +2602,12 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) ...@@ -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(skb)->nr_frags * sizeof(skb_frag_t));
skb_shinfo(p)->nr_frags += skb_shinfo(skb)->nr_frags; 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; NAPI_GRO_CB(skb)->free = 1;
goto done; goto done;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册