Commit 3cc4949269e01f39443d0fcfffb5bc6b47878d45
Committed by
David S. Miller
1 parent
bad43ca832
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
ipv4: use skb coalescing in defragmentation
ip_frag_reasm() can use skb_try_coalesce() to build optimized skb, reducing memory used by them (truesize), and reducing number of cache line misses and overhead for the consumer. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 1 changed file with 20 additions and 6 deletions Side-by-side Diff
net/ipv4/ip_fragment.c
... | ... | @@ -545,6 +545,7 @@ |
545 | 545 | int len; |
546 | 546 | int ihlen; |
547 | 547 | int err; |
548 | + int sum_truesize; | |
548 | 549 | u8 ecn; |
549 | 550 | |
550 | 551 | ipq_kill(qp); |
551 | 552 | |
552 | 553 | |
553 | 554 | |
... | ... | @@ -611,19 +612,32 @@ |
611 | 612 | atomic_add(clone->truesize, &qp->q.net->mem); |
612 | 613 | } |
613 | 614 | |
614 | - skb_shinfo(head)->frag_list = head->next; | |
615 | 615 | skb_push(head, head->data - skb_network_header(head)); |
616 | 616 | |
617 | - for (fp=head->next; fp; fp = fp->next) { | |
618 | - head->data_len += fp->len; | |
619 | - head->len += fp->len; | |
617 | + sum_truesize = head->truesize; | |
618 | + for (fp = head->next; fp;) { | |
619 | + bool headstolen; | |
620 | + int delta; | |
621 | + struct sk_buff *next = fp->next; | |
622 | + | |
623 | + sum_truesize += fp->truesize; | |
620 | 624 | if (head->ip_summed != fp->ip_summed) |
621 | 625 | head->ip_summed = CHECKSUM_NONE; |
622 | 626 | else if (head->ip_summed == CHECKSUM_COMPLETE) |
623 | 627 | head->csum = csum_add(head->csum, fp->csum); |
624 | - head->truesize += fp->truesize; | |
628 | + | |
629 | + if (skb_try_coalesce(head, fp, &headstolen, &delta)) { | |
630 | + kfree_skb_partial(fp, headstolen); | |
631 | + } else { | |
632 | + if (!skb_shinfo(head)->frag_list) | |
633 | + skb_shinfo(head)->frag_list = fp; | |
634 | + head->data_len += fp->len; | |
635 | + head->len += fp->len; | |
636 | + head->truesize += fp->truesize; | |
637 | + } | |
638 | + fp = next; | |
625 | 639 | } |
626 | - atomic_sub(head->truesize, &qp->q.net->mem); | |
640 | + atomic_sub(sum_truesize, &qp->q.net->mem); | |
627 | 641 | |
628 | 642 | head->next = NULL; |
629 | 643 | head->dev = dev; |