Skip to content

Commit 58152ec

Browse files
Eric Dumazetdavem330
authored andcommitted
tcp: add tcp_ooo_try_coalesce() helper
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. Signed-off-by: Eric Dumazet <[email protected]> Acked-by: Soheil Hassas Yeganeh <[email protected]> Acked-by: Yuchung Cheng <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8541b21 commit 58152ec

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

net/ipv4/tcp_input.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4358,6 +4358,23 @@ static bool tcp_try_coalesce(struct sock *sk,
43584358
return true;
43594359
}
43604360

4361+
static bool tcp_ooo_try_coalesce(struct sock *sk,
4362+
struct sk_buff *to,
4363+
struct sk_buff *from,
4364+
bool *fragstolen)
4365+
{
4366+
bool res = tcp_try_coalesce(sk, to, from, fragstolen);
4367+
4368+
/* In case tcp_drop() is called later, update to->gso_segs */
4369+
if (res) {
4370+
u32 gso_segs = max_t(u16, 1, skb_shinfo(to)->gso_segs) +
4371+
max_t(u16, 1, skb_shinfo(from)->gso_segs);
4372+
4373+
skb_shinfo(to)->gso_segs = min_t(u32, gso_segs, 0xFFFF);
4374+
}
4375+
return res;
4376+
}
4377+
43614378
static void tcp_drop(struct sock *sk, struct sk_buff *skb)
43624379
{
43634380
sk_drops_add(sk, skb);
@@ -4481,8 +4498,8 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
44814498
/* In the typical case, we are adding an skb to the end of the list.
44824499
* Use of ooo_last_skb avoids the O(Log(N)) rbtree lookup.
44834500
*/
4484-
if (tcp_try_coalesce(sk, tp->ooo_last_skb,
4485-
skb, &fragstolen)) {
4501+
if (tcp_ooo_try_coalesce(sk, tp->ooo_last_skb,
4502+
skb, &fragstolen)) {
44864503
coalesce_done:
44874504
tcp_grow_window(sk, skb);
44884505
kfree_skb_partial(skb, fragstolen);
@@ -4532,8 +4549,8 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
45324549
tcp_drop(sk, skb1);
45334550
goto merge_right;
45344551
}
4535-
} else if (tcp_try_coalesce(sk, skb1,
4536-
skb, &fragstolen)) {
4552+
} else if (tcp_ooo_try_coalesce(sk, skb1,
4553+
skb, &fragstolen)) {
45374554
goto coalesce_done;
45384555
}
45394556
p = &parent->rb_right;

0 commit comments

Comments
 (0)