aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2016-09-19 23:39:21 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-21 00:23:01 -0400
commitc0402760f565ae066621ebf8720a32fba074d538 (patch)
treeda6a5945e2985312febcf7e2a2493b5544d52742 /net/ipv4/tcp_input.c
parent77bfc174c38e558a3425d3b069aa2762b2fedfdd (diff)
tcp: new CC hook to set sending rate with rate_sample in any CA state
This commit introduces an optional new "omnipotent" hook, cong_control(), for congestion control modules. The cong_control() function is called at the end of processing an ACK (i.e., after updating sequence numbers, the SACK scoreboard, and loss detection). At that moment we have precise delivery rate information the congestion control module can use to control the sending behavior (using cwnd, TSO skb size, and pacing rate) in any CA state. This function can also be used by a congestion control that prefers not to use the default cwnd reduction approach (i.e., the PRR algorithm) during CA_Recovery to control the cwnd and sending rate during loss recovery. We take advantage of the fact that recent changes defer the retransmission or transmission of new data (e.g. by F-RTO) in recovery until the new tcp_cong_control() function is run. With this commit, we only run tcp_update_pacing_rate() if the congestion control is not using this new API. New congestion controls which use the new API do not want the TCP stack to run the default pacing rate calculation and overwrite whatever pacing rate they have chosen at initialization time. Signed-off-by: Van Jacobson <vanj@google.com> Signed-off-by: Neal Cardwell <ncardwell@google.com> Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: Nandita Dukkipati <nanditad@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Soheil Hassas Yeganeh <soheil@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 13a2e70141f5..980a83edfa63 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2536,6 +2536,9 @@ static inline void tcp_end_cwnd_reduction(struct sock *sk)
2536{ 2536{
2537 struct tcp_sock *tp = tcp_sk(sk); 2537 struct tcp_sock *tp = tcp_sk(sk);
2538 2538
2539 if (inet_csk(sk)->icsk_ca_ops->cong_control)
2540 return;
2541
2539 /* Reset cwnd to ssthresh in CWR or Recovery (unless it's undone) */ 2542 /* Reset cwnd to ssthresh in CWR or Recovery (unless it's undone) */
2540 if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR || 2543 if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR ||
2541 (tp->undo_marker && tp->snd_ssthresh < TCP_INFINITE_SSTHRESH)) { 2544 (tp->undo_marker && tp->snd_ssthresh < TCP_INFINITE_SSTHRESH)) {
@@ -3312,8 +3315,15 @@ static inline bool tcp_may_raise_cwnd(const struct sock *sk, const int flag)
3312 * information. All transmission or retransmission are delayed afterwards. 3315 * information. All transmission or retransmission are delayed afterwards.
3313 */ 3316 */
3314static void tcp_cong_control(struct sock *sk, u32 ack, u32 acked_sacked, 3317static void tcp_cong_control(struct sock *sk, u32 ack, u32 acked_sacked,
3315 int flag) 3318 int flag, const struct rate_sample *rs)
3316{ 3319{
3320 const struct inet_connection_sock *icsk = inet_csk(sk);
3321
3322 if (icsk->icsk_ca_ops->cong_control) {
3323 icsk->icsk_ca_ops->cong_control(sk, rs);
3324 return;
3325 }
3326
3317 if (tcp_in_cwnd_reduction(sk)) { 3327 if (tcp_in_cwnd_reduction(sk)) {
3318 /* Reduce cwnd if state mandates */ 3328 /* Reduce cwnd if state mandates */
3319 tcp_cwnd_reduction(sk, acked_sacked, flag); 3329 tcp_cwnd_reduction(sk, acked_sacked, flag);
@@ -3683,7 +3693,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3683 delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */ 3693 delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */
3684 lost = tp->lost - lost; /* freshly marked lost */ 3694 lost = tp->lost - lost; /* freshly marked lost */
3685 tcp_rate_gen(sk, delivered, lost, &now, &rs); 3695 tcp_rate_gen(sk, delivered, lost, &now, &rs);
3686 tcp_cong_control(sk, ack, delivered, flag); 3696 tcp_cong_control(sk, ack, delivered, flag, &rs);
3687 tcp_xmit_recovery(sk, rexmit); 3697 tcp_xmit_recovery(sk, rexmit);
3688 return 1; 3698 return 1;
3689 3699
@@ -5982,7 +5992,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
5982 } else 5992 } else
5983 tcp_init_metrics(sk); 5993 tcp_init_metrics(sk);
5984 5994
5985 tcp_update_pacing_rate(sk); 5995 if (!inet_csk(sk)->icsk_ca_ops->cong_control)
5996 tcp_update_pacing_rate(sk);
5986 5997
5987 /* Prevent spurious tcp_cwnd_restart() on first data packet */ 5998 /* Prevent spurious tcp_cwnd_restart() on first data packet */
5988 tp->lsndtime = tcp_time_stamp; 5999 tp->lsndtime = tcp_time_stamp;