Skip to content

Commit

Permalink
skbuff: in skb_segment, call zerocopy functions once per nskb
Browse files Browse the repository at this point in the history
This is a net-next follow-up to commit 268b790 ("skbuff: orphan
frags before zerocopy clone"), which fixed a bug in net, but added a
call to skb_zerocopy_clone at each frag to do so.

When segmenting skbs with user frags, either the user frags must be
replaced with private copies and uarg released, or the uarg must have
its refcount increased for each new skb.

skb_orphan_frags does the first, except for cases that can handle
reference counting. skb_zerocopy_clone then does the second.

Call these once per nskb, instead of once per frag.

That is, in the common case. With a frag list, also refresh when the
origin skb (frag_skb) changes.

Signed-off-by: Willem de Bruijn <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
wdebruij authored and davem330 committed Dec 27, 2017
1 parent 1f119f9 commit bf5c25d
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions net/core/skbuff.c
Original file line number Diff line number Diff line change
Expand Up @@ -3656,6 +3656,10 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
SKBTX_SHARED_FRAG;

if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
goto err;

while (pos < offset + len) {
if (i >= nfrags) {
BUG_ON(skb_headlen(list_skb));
Expand All @@ -3667,6 +3671,11 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,

BUG_ON(!nfrags);

if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
skb_zerocopy_clone(nskb, frag_skb,
GFP_ATOMIC))
goto err;

list_skb = list_skb->next;
}

Expand All @@ -3678,11 +3687,6 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
goto err;
}

if (unlikely(skb_orphan_frags(frag_skb, GFP_ATOMIC)))
goto err;
if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
goto err;

*nskb_frag = *frag;
__skb_frag_ref(nskb_frag);
size = skb_frag_size(nskb_frag);
Expand Down

0 comments on commit bf5c25d

Please sign in to comment.