Skip to content

Commit c040276

Browse files
yuchungchengdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: Neal Cardwell <[email protected]> Signed-off-by: Yuchung Cheng <[email protected]> Signed-off-by: Nandita Dukkipati <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: Soheil Hassas Yeganeh <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 77bfc17 commit c040276

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

include/net/tcp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,10 @@ struct tcp_congestion_ops {
919919
u32 (*tso_segs_goal)(struct sock *sk);
920920
/* returns the multiplier used in tcp_sndbuf_expand (optional) */
921921
u32 (*sndbuf_expand)(struct sock *sk);
922+
/* call when packets are delivered to update cwnd and pacing rate,
923+
* after all the ca_state processing. (optional)
924+
*/
925+
void (*cong_control)(struct sock *sk, const struct rate_sample *rs);
922926
/* get info for inet_diag (optional) */
923927
size_t (*get_info)(struct sock *sk, u32 ext, int *attr,
924928
union tcp_cc_info *info);

net/ipv4/tcp_cong.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ int tcp_register_congestion_control(struct tcp_congestion_ops *ca)
6969
int ret = 0;
7070

7171
/* all algorithms must implement ssthresh and cong_avoid ops */
72-
if (!ca->ssthresh || !ca->cong_avoid) {
72+
if (!ca->ssthresh || !(ca->cong_avoid || ca->cong_control)) {
7373
pr_err("%s does not implement required ops\n", ca->name);
7474
return -EINVAL;
7575
}

net/ipv4/tcp_input.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2536,6 +2536,9 @@ static inline void tcp_end_cwnd_reduction(struct sock *sk)
25362536
{
25372537
struct tcp_sock *tp = tcp_sk(sk);
25382538

2539+
if (inet_csk(sk)->icsk_ca_ops->cong_control)
2540+
return;
2541+
25392542
/* Reset cwnd to ssthresh in CWR or Recovery (unless it's undone) */
25402543
if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR ||
25412544
(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)
33123315
* information. All transmission or retransmission are delayed afterwards.
33133316
*/
33143317
static void tcp_cong_control(struct sock *sk, u32 ack, u32 acked_sacked,
3315-
int flag)
3318+
int flag, const struct rate_sample *rs)
33163319
{
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+
33173327
if (tcp_in_cwnd_reduction(sk)) {
33183328
/* Reduce cwnd if state mandates */
33193329
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)
36833693
delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */
36843694
lost = tp->lost - lost; /* freshly marked lost */
36853695
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);
36873697
tcp_xmit_recovery(sk, rexmit);
36883698
return 1;
36893699

@@ -5982,7 +5992,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
59825992
} else
59835993
tcp_init_metrics(sk);
59845994

5985-
tcp_update_pacing_rate(sk);
5995+
if (!inet_csk(sk)->icsk_ca_ops->cong_control)
5996+
tcp_update_pacing_rate(sk);
59865997

59875998
/* Prevent spurious tcp_cwnd_restart() on first data packet */
59885999
tp->lsndtime = tcp_time_stamp;

0 commit comments

Comments
 (0)