summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Wang <weiwan@google.com>2019-01-25 13:53:19 -0500
committerDavid S. Miller <davem@davemloft.net>2019-01-27 16:29:43 -0500
commit31954cd8bb667030b1c0d3d77f28fe71f06999f9 (patch)
treef00b43f2669ac70db625d8babe06e89cd0a731e2
parentfb1b69999130e9800c4e341a2b0f0991cdd8fcfc (diff)
tcp: Refactor pingpong code
Instead of using pingpong as a single bit information, we refactor the code to treat it as a counter. When interactive session is detected, we set pingpong count to TCP_PINGPONG_THRESH. And when pingpong count is >= TCP_PINGPONG_THRESH, we consider the session in pingpong mode. This patch is a pure refactor and sets foundation for the next patch. This patch itself does not change any pingpong logic. Signed-off-by: Wei Wang <weiwan@google.com> Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/inet_connection_sock.h17
-rw-r--r--net/dccp/input.c2
-rw-r--r--net/dccp/timer.c4
-rw-r--r--net/ipv4/tcp.c10
-rw-r--r--net/ipv4/tcp_input.c8
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv4/tcp_output.c4
-rw-r--r--net/ipv4/tcp_timer.c4
-rw-r--r--net/ipv6/tcp_ipv6.c2
9 files changed, 35 insertions, 18 deletions
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index fe0d9b44d6fc..179609d1d1ea 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -314,4 +314,21 @@ int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
314 char __user *optval, unsigned int optlen); 314 char __user *optval, unsigned int optlen);
315 315
316struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu); 316struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu);
317
318#define TCP_PINGPONG_THRESH 1
319
320static inline void inet_csk_enter_pingpong_mode(struct sock *sk)
321{
322 inet_csk(sk)->icsk_ack.pingpong = TCP_PINGPONG_THRESH;
323}
324
325static inline void inet_csk_exit_pingpong_mode(struct sock *sk)
326{
327 inet_csk(sk)->icsk_ack.pingpong = 0;
328}
329
330static inline bool inet_csk_in_pingpong_mode(struct sock *sk)
331{
332 return inet_csk(sk)->icsk_ack.pingpong >= TCP_PINGPONG_THRESH;
333}
317#endif /* _INET_CONNECTION_SOCK_H */ 334#endif /* _INET_CONNECTION_SOCK_H */
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 85d6c879383d..8d03707abdac 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -480,7 +480,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
480 sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT); 480 sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
481 } 481 }
482 482
483 if (sk->sk_write_pending || icsk->icsk_ack.pingpong || 483 if (sk->sk_write_pending || inet_csk_in_pingpong_mode(sk) ||
484 icsk->icsk_accept_queue.rskq_defer_accept) { 484 icsk->icsk_accept_queue.rskq_defer_accept) {
485 /* Save one ACK. Data will be ready after 485 /* Save one ACK. Data will be ready after
486 * several ticks, if write_pending is set. 486 * several ticks, if write_pending is set.
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index 1501a20a94ca..74e138495d67 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -199,7 +199,7 @@ static void dccp_delack_timer(struct timer_list *t)
199 icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER; 199 icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER;
200 200
201 if (inet_csk_ack_scheduled(sk)) { 201 if (inet_csk_ack_scheduled(sk)) {
202 if (!icsk->icsk_ack.pingpong) { 202 if (!inet_csk_in_pingpong_mode(sk)) {
203 /* Delayed ACK missed: inflate ATO. */ 203 /* Delayed ACK missed: inflate ATO. */
204 icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1, 204 icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1,
205 icsk->icsk_rto); 205 icsk->icsk_rto);
@@ -207,7 +207,7 @@ static void dccp_delack_timer(struct timer_list *t)
207 /* Delayed ACK missed: leave pingpong mode and 207 /* Delayed ACK missed: leave pingpong mode and
208 * deflate ATO. 208 * deflate ATO.
209 */ 209 */
210 icsk->icsk_ack.pingpong = 0; 210 inet_csk_exit_pingpong_mode(sk);
211 icsk->icsk_ack.ato = TCP_ATO_MIN; 211 icsk->icsk_ack.ato = TCP_ATO_MIN;
212 } 212 }
213 dccp_send_ack(sk); 213 dccp_send_ack(sk);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 12ba21433dd0..6f8d292ad501 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1551,7 +1551,7 @@ static void tcp_cleanup_rbuf(struct sock *sk, int copied)
1551 (copied > 0 && 1551 (copied > 0 &&
1552 ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) || 1552 ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) ||
1553 ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) && 1553 ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) &&
1554 !icsk->icsk_ack.pingpong)) && 1554 !inet_csk_in_pingpong_mode(sk))) &&
1555 !atomic_read(&sk->sk_rmem_alloc))) 1555 !atomic_read(&sk->sk_rmem_alloc)))
1556 time_to_ack = true; 1556 time_to_ack = true;
1557 } 1557 }
@@ -2984,16 +2984,16 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
2984 2984
2985 case TCP_QUICKACK: 2985 case TCP_QUICKACK:
2986 if (!val) { 2986 if (!val) {
2987 icsk->icsk_ack.pingpong = 1; 2987 inet_csk_enter_pingpong_mode(sk);
2988 } else { 2988 } else {
2989 icsk->icsk_ack.pingpong = 0; 2989 inet_csk_exit_pingpong_mode(sk);
2990 if ((1 << sk->sk_state) & 2990 if ((1 << sk->sk_state) &
2991 (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && 2991 (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) &&
2992 inet_csk_ack_scheduled(sk)) { 2992 inet_csk_ack_scheduled(sk)) {
2993 icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; 2993 icsk->icsk_ack.pending |= ICSK_ACK_PUSHED;
2994 tcp_cleanup_rbuf(sk, 1); 2994 tcp_cleanup_rbuf(sk, 1);
2995 if (!(val & 1)) 2995 if (!(val & 1))
2996 icsk->icsk_ack.pingpong = 1; 2996 inet_csk_enter_pingpong_mode(sk);
2997 } 2997 }
2998 } 2998 }
2999 break; 2999 break;
@@ -3407,7 +3407,7 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
3407 return 0; 3407 return 0;
3408 } 3408 }
3409 case TCP_QUICKACK: 3409 case TCP_QUICKACK:
3410 val = !icsk->icsk_ack.pingpong; 3410 val = !inet_csk_in_pingpong_mode(sk);
3411 break; 3411 break;
3412 3412
3413 case TCP_CONGESTION: 3413 case TCP_CONGESTION:
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 76858b14ebe9..7a027dec649b 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -221,7 +221,7 @@ void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks)
221 struct inet_connection_sock *icsk = inet_csk(sk); 221 struct inet_connection_sock *icsk = inet_csk(sk);
222 222
223 tcp_incr_quickack(sk, max_quickacks); 223 tcp_incr_quickack(sk, max_quickacks);
224 icsk->icsk_ack.pingpong = 0; 224 inet_csk_exit_pingpong_mode(sk);
225 icsk->icsk_ack.ato = TCP_ATO_MIN; 225 icsk->icsk_ack.ato = TCP_ATO_MIN;
226} 226}
227EXPORT_SYMBOL(tcp_enter_quickack_mode); 227EXPORT_SYMBOL(tcp_enter_quickack_mode);
@@ -236,7 +236,7 @@ static bool tcp_in_quickack_mode(struct sock *sk)
236 const struct dst_entry *dst = __sk_dst_get(sk); 236 const struct dst_entry *dst = __sk_dst_get(sk);
237 237
238 return (dst && dst_metric(dst, RTAX_QUICKACK)) || 238 return (dst && dst_metric(dst, RTAX_QUICKACK)) ||
239 (icsk->icsk_ack.quick && !icsk->icsk_ack.pingpong); 239 (icsk->icsk_ack.quick && !inet_csk_in_pingpong_mode(sk));
240} 240}
241 241
242static void tcp_ecn_queue_cwr(struct tcp_sock *tp) 242static void tcp_ecn_queue_cwr(struct tcp_sock *tp)
@@ -4094,7 +4094,7 @@ void tcp_fin(struct sock *sk)
4094 case TCP_ESTABLISHED: 4094 case TCP_ESTABLISHED:
4095 /* Move to CLOSE_WAIT */ 4095 /* Move to CLOSE_WAIT */
4096 tcp_set_state(sk, TCP_CLOSE_WAIT); 4096 tcp_set_state(sk, TCP_CLOSE_WAIT);
4097 inet_csk(sk)->icsk_ack.pingpong = 1; 4097 inet_csk_enter_pingpong_mode(sk);
4098 break; 4098 break;
4099 4099
4100 case TCP_CLOSE_WAIT: 4100 case TCP_CLOSE_WAIT:
@@ -5889,7 +5889,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
5889 return -1; 5889 return -1;
5890 if (sk->sk_write_pending || 5890 if (sk->sk_write_pending ||
5891 icsk->icsk_accept_queue.rskq_defer_accept || 5891 icsk->icsk_accept_queue.rskq_defer_accept ||
5892 icsk->icsk_ack.pingpong) { 5892 inet_csk_in_pingpong_mode(sk)) {
5893 /* Save one ACK. Data will be ready after 5893 /* Save one ACK. Data will be ready after
5894 * several ticks, if write_pending is set. 5894 * several ticks, if write_pending is set.
5895 * 5895 *
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index efc6fef692ff..662b034f1795 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2437,7 +2437,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i)
2437 refcount_read(&sk->sk_refcnt), sk, 2437 refcount_read(&sk->sk_refcnt), sk,
2438 jiffies_to_clock_t(icsk->icsk_rto), 2438 jiffies_to_clock_t(icsk->icsk_rto),
2439 jiffies_to_clock_t(icsk->icsk_ack.ato), 2439 jiffies_to_clock_t(icsk->icsk_ack.ato),
2440 (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, 2440 (icsk->icsk_ack.quick << 1) | inet_csk_in_pingpong_mode(sk),
2441 tp->snd_cwnd, 2441 tp->snd_cwnd,
2442 state == TCP_LISTEN ? 2442 state == TCP_LISTEN ?
2443 fastopenq->max_qlen : 2443 fastopenq->max_qlen :
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 26a2948dca95..06228e2d010e 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -171,7 +171,7 @@ static void tcp_event_data_sent(struct tcp_sock *tp,
171 * packet, enter pingpong mode. 171 * packet, enter pingpong mode.
172 */ 172 */
173 if ((u32)(now - icsk->icsk_ack.lrcvtime) < icsk->icsk_ack.ato) 173 if ((u32)(now - icsk->icsk_ack.lrcvtime) < icsk->icsk_ack.ato)
174 icsk->icsk_ack.pingpong = 1; 174 inet_csk_enter_pingpong_mode(sk);
175} 175}
176 176
177/* Account for an ACK we sent. */ 177/* Account for an ACK we sent. */
@@ -3569,7 +3569,7 @@ void tcp_send_delayed_ack(struct sock *sk)
3569 const struct tcp_sock *tp = tcp_sk(sk); 3569 const struct tcp_sock *tp = tcp_sk(sk);
3570 int max_ato = HZ / 2; 3570 int max_ato = HZ / 2;
3571 3571
3572 if (icsk->icsk_ack.pingpong || 3572 if (inet_csk_in_pingpong_mode(sk) ||
3573 (icsk->icsk_ack.pending & ICSK_ACK_PUSHED)) 3573 (icsk->icsk_ack.pending & ICSK_ACK_PUSHED))
3574 max_ato = TCP_DELACK_MAX; 3574 max_ato = TCP_DELACK_MAX;
3575 3575
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index d7399a89469d..f0c86398e6a7 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -277,14 +277,14 @@ void tcp_delack_timer_handler(struct sock *sk)
277 icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER; 277 icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER;
278 278
279 if (inet_csk_ack_scheduled(sk)) { 279 if (inet_csk_ack_scheduled(sk)) {
280 if (!icsk->icsk_ack.pingpong) { 280 if (!inet_csk_in_pingpong_mode(sk)) {
281 /* Delayed ACK missed: inflate ATO. */ 281 /* Delayed ACK missed: inflate ATO. */
282 icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1, icsk->icsk_rto); 282 icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1, icsk->icsk_rto);
283 } else { 283 } else {
284 /* Delayed ACK missed: leave pingpong mode and 284 /* Delayed ACK missed: leave pingpong mode and
285 * deflate ATO. 285 * deflate ATO.
286 */ 286 */
287 icsk->icsk_ack.pingpong = 0; 287 inet_csk_exit_pingpong_mode(sk);
288 icsk->icsk_ack.ato = TCP_ATO_MIN; 288 icsk->icsk_ack.ato = TCP_ATO_MIN;
289 } 289 }
290 tcp_mstamp_refresh(tcp_sk(sk)); 290 tcp_mstamp_refresh(tcp_sk(sk));
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index b81eb7cb815e..e51cda79f0cc 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1864,7 +1864,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1864 refcount_read(&sp->sk_refcnt), sp, 1864 refcount_read(&sp->sk_refcnt), sp,
1865 jiffies_to_clock_t(icsk->icsk_rto), 1865 jiffies_to_clock_t(icsk->icsk_rto),
1866 jiffies_to_clock_t(icsk->icsk_ack.ato), 1866 jiffies_to_clock_t(icsk->icsk_ack.ato),
1867 (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, 1867 (icsk->icsk_ack.quick << 1) | inet_csk_in_pingpong_mode(sp),
1868 tp->snd_cwnd, 1868 tp->snd_cwnd,
1869 state == TCP_LISTEN ? 1869 state == TCP_LISTEN ?
1870 fastopenq->max_qlen : 1870 fastopenq->max_qlen :