Skip to content

Commit bf5c25d

Browse files
wdebruijdavem330
authored andcommitted
skbuff: in skb_segment, call zerocopy functions once per nskb
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]>
1 parent 1f119f9 commit bf5c25d

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

net/core/skbuff.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3656,6 +3656,10 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
36563656
skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
36573657
SKBTX_SHARED_FRAG;
36583658

3659+
if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
3660+
skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
3661+
goto err;
3662+
36593663
while (pos < offset + len) {
36603664
if (i >= nfrags) {
36613665
BUG_ON(skb_headlen(list_skb));
@@ -3667,6 +3671,11 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
36673671

36683672
BUG_ON(!nfrags);
36693673

3674+
if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
3675+
skb_zerocopy_clone(nskb, frag_skb,
3676+
GFP_ATOMIC))
3677+
goto err;
3678+
36703679
list_skb = list_skb->next;
36713680
}
36723681

@@ -3678,11 +3687,6 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
36783687
goto err;
36793688
}
36803689

3681-
if (unlikely(skb_orphan_frags(frag_skb, GFP_ATOMIC)))
3682-
goto err;
3683-
if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
3684-
goto err;
3685-
36863690
*nskb_frag = *frag;
36873691
__skb_frag_ref(nskb_frag);
36883692
size = skb_frag_size(nskb_frag);

0 commit comments

Comments
 (0)