* [PATCH net-next 1/4] tcp: mandate a one-time immediate ACK
2018-08-09 16:38 [PATCH net-next 0/4] new mechanism to ACK immediately Yuchung Cheng
@ 2018-08-09 16:38 ` Yuchung Cheng
2018-08-09 16:38 ` [PATCH net-next 2/4] tcp: avoid resetting ACK timer in DCTCP Yuchung Cheng
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Yuchung Cheng @ 2018-08-09 16:38 UTC (permalink / raw)
To: davem, edumazet; +Cc: netdev, ncardwell, brakmo, weiwan, Yuchung Cheng
Add a new flag to indicate a one-time immediate ACK. This flag is
occasionaly set under specific TCP protocol states in addition to
the more common quickack mechanism for interactive application.
In several cases in the TCP code we want to force an immediate ACK
but do not want to call tcp_enter_quickack_mode() because we do
not want to forget the icsk_ack.pingpong or icsk_ack.ato state.
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Wei Wang <weiwan@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/inet_connection_sock.h | 3 ++-
net/ipv4/tcp_input.c | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 0a6c9e0f2b5a..fa43b82607d9 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -167,7 +167,8 @@ enum inet_csk_ack_state_t {
ICSK_ACK_SCHED = 1,
ICSK_ACK_TIMER = 2,
ICSK_ACK_PUSHED = 4,
- ICSK_ACK_PUSHED2 = 8
+ ICSK_ACK_PUSHED2 = 8,
+ ICSK_ACK_NOW = 16 /* Send the next ACK immediately (once) */
};
void inet_csk_init_xmit_timers(struct sock *sk,
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 715d541b52dd..b8849588c440 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5179,7 +5179,9 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
(tp->rcv_nxt - tp->copied_seq < sk->sk_rcvlowat ||
__tcp_select_window(sk) >= tp->rcv_wnd)) ||
/* We ACK each frame or... */
- tcp_in_quickack_mode(sk)) {
+ tcp_in_quickack_mode(sk) ||
+ /* Protocol state mandates a one-time immediate ACK */
+ inet_csk(sk)->icsk_ack.pending & ICSK_ACK_NOW) {
send_now:
tcp_send_ack(sk);
return;
--
2.18.0.597.ga71716f1ad-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH net-next 2/4] tcp: avoid resetting ACK timer in DCTCP
2018-08-09 16:38 [PATCH net-next 0/4] new mechanism to ACK immediately Yuchung Cheng
2018-08-09 16:38 ` [PATCH net-next 1/4] tcp: mandate a one-time immediate ACK Yuchung Cheng
@ 2018-08-09 16:38 ` Yuchung Cheng
2018-08-09 16:38 ` [PATCH net-next 3/4] tcp: always ACK immediately on hole repairs Yuchung Cheng
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Yuchung Cheng @ 2018-08-09 16:38 UTC (permalink / raw)
To: davem, edumazet; +Cc: netdev, ncardwell, brakmo, weiwan, Yuchung Cheng
The recent fix of acking immediately in DCTCP on CE status change
has an undesirable side-effect: it also resets TCP ack timer and
disables pingpong mode (interactive session). But the CE status
change has nothing to do with them. This patch addresses that by
using the new one-time immediate ACK flag instead of calling
tcp_enter_quickack_mode().
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Wei Wang <weiwan@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/tcp_dctcp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c
index 8b637f9f23a2..ca61e2a659e7 100644
--- a/net/ipv4/tcp_dctcp.c
+++ b/net/ipv4/tcp_dctcp.c
@@ -136,7 +136,7 @@ static void dctcp_ce_state_0_to_1(struct sock *sk)
*/
if (inet_csk(sk)->icsk_ack.pending & ICSK_ACK_TIMER)
__tcp_send_ack(sk, ca->prior_rcv_nxt);
- tcp_enter_quickack_mode(sk, 1);
+ inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW;
}
ca->prior_rcv_nxt = tp->rcv_nxt;
@@ -157,7 +157,7 @@ static void dctcp_ce_state_1_to_0(struct sock *sk)
*/
if (inet_csk(sk)->icsk_ack.pending & ICSK_ACK_TIMER)
__tcp_send_ack(sk, ca->prior_rcv_nxt);
- tcp_enter_quickack_mode(sk, 1);
+ inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW;
}
ca->prior_rcv_nxt = tp->rcv_nxt;
--
2.18.0.597.ga71716f1ad-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH net-next 3/4] tcp: always ACK immediately on hole repairs
2018-08-09 16:38 [PATCH net-next 0/4] new mechanism to ACK immediately Yuchung Cheng
2018-08-09 16:38 ` [PATCH net-next 1/4] tcp: mandate a one-time immediate ACK Yuchung Cheng
2018-08-09 16:38 ` [PATCH net-next 2/4] tcp: avoid resetting ACK timer in DCTCP Yuchung Cheng
@ 2018-08-09 16:38 ` Yuchung Cheng
2018-08-09 16:38 ` [PATCH net-next 4/4] tcp: avoid resetting ACK timer upon receiving packet with ECN CWR flag Yuchung Cheng
2018-08-11 18:41 ` [PATCH net-next 0/4] new mechanism to ACK immediately David Miller
4 siblings, 0 replies; 6+ messages in thread
From: Yuchung Cheng @ 2018-08-09 16:38 UTC (permalink / raw)
To: davem, edumazet; +Cc: netdev, ncardwell, brakmo, weiwan, Yuchung Cheng
RFC 5681 sec 4.2:
To provide feedback to senders recovering from losses, the receiver
SHOULD send an immediate ACK when it receives a data segment that
fills in all or part of a gap in the sequence space.
When a gap is partially filled, __tcp_ack_snd_check already checks
the out-of-order queue and correctly send an immediate ACK. However
when a gap is fully filled, the previous implementation only resets
pingpong mode which does not guarantee an immediate ACK because the
quick ACK counter may be zero. This patch addresses this issue by
marking the one-time immediate ACK flag instead.
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Wei Wang <weiwan@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/tcp_input.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index b8849588c440..9a09ff3afef2 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4735,11 +4735,11 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
if (!RB_EMPTY_ROOT(&tp->out_of_order_queue)) {
tcp_ofo_queue(sk);
- /* RFC2581. 4.2. SHOULD send immediate ACK, when
+ /* RFC5681. 4.2. SHOULD send immediate ACK, when
* gap in queue is filled.
*/
if (RB_EMPTY_ROOT(&tp->out_of_order_queue))
- inet_csk(sk)->icsk_ack.pingpong = 0;
+ inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW;
}
if (tp->rx_opt.num_sacks)
--
2.18.0.597.ga71716f1ad-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH net-next 4/4] tcp: avoid resetting ACK timer upon receiving packet with ECN CWR flag
2018-08-09 16:38 [PATCH net-next 0/4] new mechanism to ACK immediately Yuchung Cheng
` (2 preceding siblings ...)
2018-08-09 16:38 ` [PATCH net-next 3/4] tcp: always ACK immediately on hole repairs Yuchung Cheng
@ 2018-08-09 16:38 ` Yuchung Cheng
2018-08-11 18:41 ` [PATCH net-next 0/4] new mechanism to ACK immediately David Miller
4 siblings, 0 replies; 6+ messages in thread
From: Yuchung Cheng @ 2018-08-09 16:38 UTC (permalink / raw)
To: davem, edumazet; +Cc: netdev, ncardwell, brakmo, weiwan, Yuchung Cheng
Previously commit 9aee40006190 ("tcp: ack immediately when a cwr
packet arrives") calls tcp_enter_quickack_mode to force sending
two immediate ACKs upon receiving a packet w/ CWR flag. The side
effect is it'll also reset the delayed ACK timer and interactive
session tracking. This patch removes that side effect by using the
new ACK_NOW flag to force an immmediate ACK.
Packetdrill to demonstrate:
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 setsockopt(3, SOL_TCP, TCP_CONGESTION, "dctcp", 5) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0 < [ect0] SEW 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7>
+0 > SE. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
+.1 < [ect0] . 1:1(0) ack 1 win 257
+0 accept(3, ..., ...) = 4
+0 < [ect0] . 1:1001(1000) ack 1 win 257
+0 > [ect01] . 1:1(0) ack 1001
+0 write(4, ..., 1) = 1
+0 > [ect01] P. 1:2(1) ack 1001
+0 < [ect0] . 1001:2001(1000) ack 2 win 257
+0 write(4, ..., 1) = 1
+0 > [ect01] P. 2:3(1) ack 2001
+0 < [ect0] . 2001:3001(1000) ack 3 win 257
+0 < [ect0] . 3001:4001(1000) ack 3 win 257
// Ack delayed ...
+.01 < [ce] P. 4001:4501(500) ack 3 win 257
+0 > [ect01] . 3:3(0) ack 4001
+0 > [ect01] E. 3:3(0) ack 4501
+.001 read(4, ..., 4500) = 4500
+0 write(4, ..., 1) = 1
+0 > [ect01] PE. 3:4(1) ack 4501 win 100
+.01 < [ect0] W. 4501:5501(1000) ack 4 win 257
// No delayed ACK on CWR flag
+0 > [ect01] . 4:4(0) ack 5501
+.31 < [ect0] . 5501:6501(1000) ack 4 win 257
+0 > [ect01] . 4:4(0) ack 6501
Fixes: 9aee40006190 ("tcp: ack immediately when a cwr packet arrives")
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
---
net/ipv4/tcp_input.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 9a09ff3afef2..4c2dd9f863f7 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -245,16 +245,16 @@ static void tcp_ecn_queue_cwr(struct tcp_sock *tp)
tp->ecn_flags |= TCP_ECN_QUEUE_CWR;
}
-static void tcp_ecn_accept_cwr(struct tcp_sock *tp, const struct sk_buff *skb)
+static void tcp_ecn_accept_cwr(struct sock *sk, const struct sk_buff *skb)
{
if (tcp_hdr(skb)->cwr) {
- tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
+ tcp_sk(sk)->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
/* If the sender is telling us it has entered CWR, then its
* cwnd may be very low (even just 1 packet), so we should ACK
* immediately.
*/
- tcp_enter_quickack_mode((struct sock *)tp, 2);
+ inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW;
}
}
@@ -4703,7 +4703,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
skb_dst_drop(skb);
__skb_pull(skb, tcp_hdr(skb)->doff * 4);
- tcp_ecn_accept_cwr(tp, skb);
+ tcp_ecn_accept_cwr(sk, skb);
tp->rx_opt.dsack = 0;
--
2.18.0.597.ga71716f1ad-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH net-next 0/4] new mechanism to ACK immediately
2018-08-09 16:38 [PATCH net-next 0/4] new mechanism to ACK immediately Yuchung Cheng
` (3 preceding siblings ...)
2018-08-09 16:38 ` [PATCH net-next 4/4] tcp: avoid resetting ACK timer upon receiving packet with ECN CWR flag Yuchung Cheng
@ 2018-08-11 18:41 ` David Miller
4 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2018-08-11 18:41 UTC (permalink / raw)
To: ycheng; +Cc: edumazet, netdev, ncardwell, brakmo, weiwan
From: Yuchung Cheng <ycheng@google.com>
Date: Thu, 9 Aug 2018 09:38:08 -0700
> This patch is a follow-up feature improvement to the recent fixes on
> the performance issues in ECN (delayed) ACKs. Many of the fixes use
> tcp_enter_quickack_mode routine to force immediate ACKs. However the
> routine also reset tracking interactive session. This is not ideal
> because these immediate ACKs are required by protocol specifics
> unrelated to the interactiveness nature of the application.
>
> This patch set introduces a new flag to send a one-time immediate ACK
> without changing the status of interactive session tracking. With this
> patch set the immediate ACKs are generated upon these protocol states:
>
> 1) When a hole is repaired
> 2) When CE status changes between subsequent data packets received
> 3) When a data packet carries CWR flag
This looks really nice, series applied.
Thanks!
^ permalink raw reply [flat|nested] 6+ messages in thread