Commit 3cc4949269e01f39443d0fcfffb5bc6b47878d45

Authored by Eric Dumazet
Committed by David S. Miller
1 parent bad43ca832

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;