diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2012-05-02 17:19:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-05-03 04:21:33 -0400 |
commit | 34a802a5b9c4c4efb61828781230805be6dd0f8e (patch) | |
tree | 45be14af435925382374f42619af2d1b602eee52 /net/ipv4 | |
parent | 57b55a7ec684d8b846d6d5e67f4982363a83db7e (diff) |
tcp: move stats merge to the end of tcp_try_coalesce
This change cleans up the last bits of tcp_try_coalesce so that we only
need one goto which jumps to the end of the function. The idea is to make
the code more readable by putting things in a linear order so that we start
execution at the top of the function, and end it at the bottom.
I also made a slight tweak to the code for handling frags when we are a
clone. Instead of making it an if (clone) loop else nr_frags = 0 I changed
the logic so that if (!clone) we just set the number of frags to 0 which
disables the for loop anyway.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/tcp_input.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 41fa5df9abbc..84e69e02fe20 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4548,15 +4548,13 @@ static bool tcp_try_coalesce(struct sock *sk, | |||
4548 | int i, delta, len = from->len; | 4548 | int i, delta, len = from->len; |
4549 | 4549 | ||
4550 | *fragstolen = false; | 4550 | *fragstolen = false; |
4551 | |||
4551 | if (tcp_hdr(from)->fin || skb_cloned(to)) | 4552 | if (tcp_hdr(from)->fin || skb_cloned(to)) |
4552 | return false; | 4553 | return false; |
4554 | |||
4553 | if (len <= skb_tailroom(to)) { | 4555 | if (len <= skb_tailroom(to)) { |
4554 | BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len)); | 4556 | BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len)); |
4555 | merge: | 4557 | goto merge; |
4556 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOALESCE); | ||
4557 | TCP_SKB_CB(to)->end_seq = TCP_SKB_CB(from)->end_seq; | ||
4558 | TCP_SKB_CB(to)->ack_seq = TCP_SKB_CB(from)->ack_seq; | ||
4559 | return true; | ||
4560 | } | 4558 | } |
4561 | 4559 | ||
4562 | if (skb_has_frag_list(to) || skb_has_frag_list(from)) | 4560 | if (skb_has_frag_list(to) || skb_has_frag_list(from)) |
@@ -4581,7 +4579,6 @@ merge: | |||
4581 | skb_fill_page_desc(to, skb_shinfo(to)->nr_frags, | 4579 | skb_fill_page_desc(to, skb_shinfo(to)->nr_frags, |
4582 | page, offset, skb_headlen(from)); | 4580 | page, offset, skb_headlen(from)); |
4583 | *fragstolen = true; | 4581 | *fragstolen = true; |
4584 | goto copyfrags; | ||
4585 | } else { | 4582 | } else { |
4586 | if (skb_shinfo(to)->nr_frags + | 4583 | if (skb_shinfo(to)->nr_frags + |
4587 | skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS) | 4584 | skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS) |
@@ -4589,27 +4586,33 @@ merge: | |||
4589 | 4586 | ||
4590 | delta = from->truesize - | 4587 | delta = from->truesize - |
4591 | SKB_TRUESIZE(skb_end_pointer(from) - from->head); | 4588 | SKB_TRUESIZE(skb_end_pointer(from) - from->head); |
4592 | copyfrags: | ||
4593 | WARN_ON_ONCE(delta < len); | ||
4594 | memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags, | ||
4595 | skb_shinfo(from)->frags, | ||
4596 | skb_shinfo(from)->nr_frags * sizeof(skb_frag_t)); | ||
4597 | skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags; | ||
4598 | |||
4599 | if (skb_cloned(from)) | ||
4600 | for (i = 0; i < skb_shinfo(from)->nr_frags; i++) | ||
4601 | skb_frag_ref(from, i); | ||
4602 | else | ||
4603 | skb_shinfo(from)->nr_frags = 0; | ||
4604 | |||
4605 | to->truesize += delta; | ||
4606 | atomic_add(delta, &sk->sk_rmem_alloc); | ||
4607 | sk_mem_charge(sk, delta); | ||
4608 | to->len += len; | ||
4609 | to->data_len += len; | ||
4610 | goto merge; | ||
4611 | } | 4589 | } |
4612 | return false; | 4590 | |
4591 | WARN_ON_ONCE(delta < len); | ||
4592 | |||
4593 | memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags, | ||
4594 | skb_shinfo(from)->frags, | ||
4595 | skb_shinfo(from)->nr_frags * sizeof(skb_frag_t)); | ||
4596 | skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags; | ||
4597 | |||
4598 | if (!skb_cloned(from)) | ||
4599 | skb_shinfo(from)->nr_frags = 0; | ||
4600 | |||
4601 | /* if the skb is cloned this does nothing since we set nr_frags to 0 */ | ||
4602 | for (i = 0; i < skb_shinfo(from)->nr_frags; i++) | ||
4603 | skb_frag_ref(from, i); | ||
4604 | |||
4605 | to->truesize += delta; | ||
4606 | atomic_add(delta, &sk->sk_rmem_alloc); | ||
4607 | sk_mem_charge(sk, delta); | ||
4608 | to->len += len; | ||
4609 | to->data_len += len; | ||
4610 | |||
4611 | merge: | ||
4612 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOALESCE); | ||
4613 | TCP_SKB_CB(to)->end_seq = TCP_SKB_CB(from)->end_seq; | ||
4614 | TCP_SKB_CB(to)->ack_seq = TCP_SKB_CB(from)->ack_seq; | ||
4615 | return true; | ||
4613 | } | 4616 | } |
4614 | 4617 | ||
4615 | static void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) | 4618 | static void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) |