History

tcp: introduce a per-route knob for quick ack

In previous discussions, I tried to find some reasonable heuristics for delayed ACK, however this seems not possible, according to Eric: "ACKS might also be delayed because of bidirectional traffic, and is more controlled by the application response time. TCP stack can not easily estimate it." "ACK can be incredibly useful to recover from losses in a short time. The vast majority of TCP sessions are small lived, and we send one ACK per received segment anyway at beginning or retransmits to let the sender smoothly increase its cwnd, so an auto-tuning facility wont help them that much." and according to David: "ACKs are the only information we have to detect loss. And, for the same reasons that TCP VEGAS is fundamentally broken, we cannot measure the pipe or some other receiver-side-visible piece of information to determine when it's "safe" to stretch ACK. And even if it's "safe", we should not do it so that losses are accurately detected and we don't spuriously retransmit. The only way to know when the bandwidth increases is to "test" it, by sending more and more packets until drops happen. That's why all successful congestion control algorithms must operate on explicited tested pieces of information. Similarly, it's not really possible to universally know if it's safe to stretch ACK or not." It still makes sense to enable or disable quick ack mode like what TCP_QUICK_ACK does. Similar to TCP_QUICK_ACK option, but for people who can't modify the source code and still wants to control TCP delayed ACK behavior. As David suggested, this should belong to per-path scope, since different pathes may want different behaviors.

Cong Wang committed 13 years ago

Commit bcefe171 parent 2c0740e3 files · +10 −3Browse files

Unified · Split

3 files
  1. include/uapi/linux/rtnetlink.h +2 −0
  2. net/ipv4/tcp_input.c +4 −1
  3. net/ipv4/tcp_output.c +4 −2
include/uapi/linux/rtnetlink.h+2−0
@@ -386,6 +386,8 @@ enum { · 385 unmodified lines
386#define RTAX_RTO_MIN RTAX_RTO_MIN386#define RTAX_RTO_MIN RTAX_RTO_MIN
387 RTAX_INITRWND,387 RTAX_INITRWND,
388#define RTAX_INITRWND RTAX_INITRWND388#define RTAX_INITRWND RTAX_INITRWND
389 RTAX_QUICKACK,
390#define RTAX_QUICKACK RTAX_QUICKACK
389 __RTAX_MAX391 __RTAX_MAX
390};392};
391 393
net/ipv4/tcp_input.c+4−1
@@ -3717,6 +3717,7 @@ void tcp_reset(struct sock *sk) · 3716 unmodified lines
3717static void tcp_fin(struct sock *sk)3717static void tcp_fin(struct sock *sk)
3718{3718{
3719 struct tcp_sock *tp = tcp_sk(sk);3719 struct tcp_sock *tp = tcp_sk(sk);
3720 const struct dst_entry *dst;
3720 3721
3721 inet_csk_schedule_ack(sk);3722 inet_csk_schedule_ack(sk);
3722 3723
@@ -3728,7 +3729,9 @@ static void tcp_fin(struct sock *sk) · 5 unmodified lines
3728 case TCP_ESTABLISHED:3729 case TCP_ESTABLISHED:
3729 /* Move to CLOSE_WAIT */3730 /* Move to CLOSE_WAIT */
3730 tcp_set_state(sk, TCP_CLOSE_WAIT);3731 tcp_set_state(sk, TCP_CLOSE_WAIT);
3731 inet_csk(sk)->icsk_ack.pingpong = 1;3732 dst = __sk_dst_get(sk);
3733 if (!dst || !dst_metric(dst, RTAX_QUICKACK))
3734 inet_csk(sk)->icsk_ack.pingpong = 1;
3732 break;3735 break;
3733 3736
3734 case TCP_CLOSE_WAIT:3737 case TCP_CLOSE_WAIT:
net/ipv4/tcp_output.c+4−2
@@ -160,6 +160,7 @@ static void tcp_event_data_sent(struct tcp_sock *tp, · 159 unmodified lines
160{160{
161 struct inet_connection_sock *icsk = inet_csk(sk);161 struct inet_connection_sock *icsk = inet_csk(sk);
162 const u32 now = tcp_time_stamp;162 const u32 now = tcp_time_stamp;
163 const struct dst_entry *dst = __sk_dst_get(sk);
163 164
164 if (sysctl_tcp_slow_start_after_idle &&165 if (sysctl_tcp_slow_start_after_idle &&
165 (!tp->packets_out && (s32)(now - tp->lsndtime) > icsk->icsk_rto))166 (!tp->packets_out && (s32)(now - tp->lsndtime) > icsk->icsk_rto))
@@ -170,8 +171,9 @@ static void tcp_event_data_sent(struct tcp_sock *tp, · 4 unmodified lines
170 /* If it is a reply for ato after last received171 /* If it is a reply for ato after last received
171 * packet, enter pingpong mode.172 * packet, enter pingpong mode.
172 */173 */
173 if ((u32)(now - icsk->icsk_ack.lrcvtime) < icsk->icsk_ack.ato)174 if ((u32)(now - icsk->icsk_ack.lrcvtime) < icsk->icsk_ack.ato &&
174 icsk->icsk_ack.pingpong = 1;175 (!dst || !dst_metric(dst, RTAX_QUICKACK)))
176 icsk->icsk_ack.pingpong = 1;
175}177}
176 178
177/* Account for an ACK we sent. */179/* Account for an ACK we sent. */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t