Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34dc7c0a authored by Eric Dumazet's avatar Eric Dumazet Committed by Subash Abhinov Kasiviswanathan
Browse files

tcp: add tcp_ooo_try_coalesce() helper



[ Upstream commit 58152ecb ]

In case skb in out_or_order_queue is the result of
multiple skbs coalescing, we would like to get a proper gso_segs
counter tracking, so that future tcp_drop() can report an accurate
number.

I chose to not implement this tracking for skbs in receive queue,
since they are not dropped, unless socket is disconnected.

CRs-Fixed: 2290234
Change-Id: I77743c0c1fbf293ff0bb4bba26eeeb2a1ff31ff1
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarSoheil Hassas Yeganeh <soheil@google.com>
Acked-by: default avatarYuchung Cheng <ycheng@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
Git-commit: 66fb274f
Git-repo: https://android.googlesource.com/kernel/common/


Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parent d5dd1919
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -4323,6 +4323,23 @@ static bool tcp_try_coalesce(struct sock *sk,
	return true;
}

static bool tcp_ooo_try_coalesce(struct sock *sk,
			     struct sk_buff *to,
			     struct sk_buff *from,
			     bool *fragstolen)
{
	bool res = tcp_try_coalesce(sk, OOO_QUEUE, to, from, fragstolen);

	/* In case tcp_drop() is called later, update to->gso_segs */
	if (res) {
		u32 gso_segs = max_t(u16, 1, skb_shinfo(to)->gso_segs) +
			       max_t(u16, 1, skb_shinfo(from)->gso_segs);

		skb_shinfo(to)->gso_segs = min_t(u32, gso_segs, 0xFFFF);
	}
	return res;
}

static void tcp_drop(struct sock *sk, struct sk_buff *skb)
{
	sk_drops_add(sk, skb);
@@ -4454,7 +4471,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
	/* In the typical case, we are adding an skb to the end of the list.
	 * Use of ooo_last_skb avoids the O(Log(N)) rbtree lookup.
	 */
	if (tcp_try_coalesce(sk, OOO_QUEUE, tp->ooo_last_skb,
	if (tcp_ooo_try_coalesce(sk, tp->ooo_last_skb,
				 skb, &fragstolen)) {
coalesce_done:
		tcp_grow_window(sk, skb);
@@ -4505,7 +4522,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
				tcp_drop(sk, skb1);
				goto merge_right;
			}
		} else if (tcp_try_coalesce(sk, OOO_QUEUE, skb1,
		} else if (tcp_ooo_try_coalesce(sk, skb1,
						skb, &fragstolen)) {
			goto coalesce_done;
		}