diff options
author | Wei Wang <weiwan@google.com> | 2019-01-25 13:53:19 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-01-27 16:29:43 -0500 |
commit | 31954cd8bb667030b1c0d3d77f28fe71f06999f9 (patch) | |
tree | f00b43f2669ac70db625d8babe06e89cd0a731e2 | |
parent | fb1b69999130e9800c4e341a2b0f0991cdd8fcfc (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.h | 17 | ||||
-rw-r--r-- | net/dccp/input.c | 2 | ||||
-rw-r--r-- | net/dccp/timer.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 10 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 8 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_timer.c | 4 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 2 |
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 | ||
316 | struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu); | 316 | struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu); |
317 | |||
318 | #define TCP_PINGPONG_THRESH 1 | ||
319 | |||
320 | static inline void inet_csk_enter_pingpong_mode(struct sock *sk) | ||
321 | { | ||
322 | inet_csk(sk)->icsk_ack.pingpong = TCP_PINGPONG_THRESH; | ||
323 | } | ||
324 | |||
325 | static inline void inet_csk_exit_pingpong_mode(struct sock *sk) | ||
326 | { | ||
327 | inet_csk(sk)->icsk_ack.pingpong = 0; | ||
328 | } | ||
329 | |||
330 | static 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 | } |
227 | EXPORT_SYMBOL(tcp_enter_quickack_mode); | 227 | EXPORT_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 | ||
242 | static void tcp_ecn_queue_cwr(struct tcp_sock *tp) | 242 | static 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 : |