Blame view

net/ipv4/tcp_bic.c 6.38 KB
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   * Binary Increase Congestion control for TCP
   *
   * This is from the implementation of BICTCP in
   * Lison-Xu, Kahaled Harfoush, and Injong Rhee.
   *  "Binary Increase Congestion Control for Fast, Long Distance
   *  Networks" in InfoComm 2004
   * Available from:
   *  http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf
   *
   * Unless BIC is enabled and congestion window is large
   * this behaves the same as the original Reno.
   */
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  #include <linux/mm.h>
  #include <linux/module.h>
  #include <net/tcp.h>
  
  
  #define BICTCP_BETA_SCALE    1024	/* Scale factor beta calculation
  					 * max_cwnd = snd_cwnd * beta
  					 */
  #define BICTCP_B		4	 /*
  					  * In binary search,
  					  * go to point (max+min)/N
  					  */
  
  static int fast_convergence = 1;
450b5b189   Stephen Hemminger   [TCP]: BIC max in...
28
  static int max_increment = 16;
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
29
30
  static int low_window = 14;
  static int beta = 819;		/* = 819/1024 (BICTCP_BETA_SCALE) */
66e1e3b20   David S. Miller   [TCP]: Set initia...
31
  static int initial_ssthresh;
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
32
33
34
35
36
37
38
39
40
41
  static int smooth_part = 20;
  
  module_param(fast_convergence, int, 0644);
  MODULE_PARM_DESC(fast_convergence, "turn on/off fast convergence");
  module_param(max_increment, int, 0644);
  MODULE_PARM_DESC(max_increment, "Limit on increment allowed during binary search");
  module_param(low_window, int, 0644);
  MODULE_PARM_DESC(low_window, "lower bound on congestion window (for TCP friendliness)");
  module_param(beta, int, 0644);
  MODULE_PARM_DESC(beta, "beta for multiplicative increase");
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
42
43
44
45
46
47
48
49
50
51
52
53
54
  module_param(initial_ssthresh, int, 0644);
  MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
  module_param(smooth_part, int, 0644);
  MODULE_PARM_DESC(smooth_part, "log(B/(B*Smin))/log(B/(B-1))+B, # of RTT from Wmax-B to Wmax");
  
  
  /* BIC TCP Parameters */
  struct bictcp {
  	u32	cnt;		/* increase cwnd by 1 after ACKs */
  	u32 	last_max_cwnd;	/* last maximum snd_cwnd */
  	u32	loss_cwnd;	/* congestion window at last loss */
  	u32	last_cwnd;	/* the last snd_cwnd */
  	u32	last_time;	/* time when updated last_cwnd */
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
55
56
57
58
59
60
61
62
63
64
65
66
  	u32	epoch_start;	/* beginning of an epoch */
  #define ACK_RATIO_SHIFT	4
  	u32	delayed_ack;	/* estimate the ratio of Packets/ACKs << 4 */
  };
  
  static inline void bictcp_reset(struct bictcp *ca)
  {
  	ca->cnt = 0;
  	ca->last_max_cwnd = 0;
  	ca->loss_cwnd = 0;
  	ca->last_cwnd = 0;
  	ca->last_time = 0;
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
67
68
69
  	ca->epoch_start = 0;
  	ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
  }
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
70
  static void bictcp_init(struct sock *sk)
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
71
  {
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
72
  	bictcp_reset(inet_csk_ca(sk));
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
73
  	if (initial_ssthresh)
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
74
  		tcp_sk(sk)->snd_ssthresh = initial_ssthresh;
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
  }
  
  /*
   * Compute congestion window to use.
   */
  static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
  {
  	if (ca->last_cwnd == cwnd &&
  	    (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32)
  		return;
  
  	ca->last_cwnd = cwnd;
  	ca->last_time = tcp_time_stamp;
  
  	if (ca->epoch_start == 0) /* record the beginning of an epoch */
  		ca->epoch_start = tcp_time_stamp;
  
  	/* start off normal */
  	if (cwnd <= low_window) {
  		ca->cnt = cwnd;
  		return;
  	}
  
  	/* binary increase */
  	if (cwnd < ca->last_max_cwnd) {
  		__u32 	dist = (ca->last_max_cwnd - cwnd)
  			/ BICTCP_B;
  
  		if (dist > max_increment)
  			/* linear increase */
  			ca->cnt = cwnd / max_increment;
  		else if (dist <= 1U)
  			/* binary search increase */
  			ca->cnt = (cwnd * smooth_part) / BICTCP_B;
  		else
  			/* binary search increase */
  			ca->cnt = cwnd / dist;
  	} else {
  		/* slow start AMD linear increase */
  		if (cwnd < ca->last_max_cwnd + BICTCP_B)
  			/* slow start */
  			ca->cnt = (cwnd * smooth_part) / BICTCP_B;
  		else if (cwnd < ca->last_max_cwnd + max_increment*(BICTCP_B-1))
  			/* slow start */
  			ca->cnt = (cwnd * (BICTCP_B-1))
42a39450f   Stephen Hemminger   [TCP]: BIC coding...
120
  				/ (cwnd - ca->last_max_cwnd);
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
121
122
123
124
125
126
  		else
  			/* linear increase */
  			ca->cnt = cwnd / max_increment;
  	}
  
  	/* if in slow start or link utilization is very low */
018da8f44   Stephen Hemminger   [TCP] BIC: remove...
127
  	if (ca->loss_cwnd == 0) {
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
128
129
130
131
132
133
134
135
  		if (ca->cnt > 20) /* increase cwnd 5% per RTT */
  			ca->cnt = 20;
  	}
  
  	ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;
  	if (ca->cnt == 0)			/* cannot be zero */
  		ca->cnt = 1;
  }
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
136
  static void bictcp_cong_avoid(struct sock *sk, u32 ack,
16751347a   Stephen Hemminger   [TCP]: remove unu...
137
  			      u32 in_flight, int data_acked)
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
138
  {
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
139
140
  	struct tcp_sock *tp = tcp_sk(sk);
  	struct bictcp *ca = inet_csk_ca(sk);
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
141

f4805eded   Stephen Hemminger   [TCP]: fix conges...
142
  	if (!tcp_is_cwnd_limited(sk, in_flight))
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
143
  		return;
7faffa1c7   Stephen Hemminger   [TCP]: add tcp_sl...
144
145
146
  	if (tp->snd_cwnd <= tp->snd_ssthresh)
  		tcp_slow_start(tp);
  	else {
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
147
  		bictcp_update(ca, tp->snd_cwnd);
7faffa1c7   Stephen Hemminger   [TCP]: add tcp_sl...
148
  		/* In dangerous area, increase slowly.
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  		 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
  		 */
  		if (tp->snd_cwnd_cnt >= ca->cnt) {
  			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
  				tp->snd_cwnd++;
  			tp->snd_cwnd_cnt = 0;
  		} else
  			tp->snd_cwnd_cnt++;
  	}
  
  }
  
  /*
   *	behave like Reno until low_window is reached,
   *	then increase congestion window slowly
   */
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
165
  static u32 bictcp_recalc_ssthresh(struct sock *sk)
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
166
  {
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
167
168
  	const struct tcp_sock *tp = tcp_sk(sk);
  	struct bictcp *ca = inet_csk_ca(sk);
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
169
170
  
  	ca->epoch_start = 0;	/* end of epoch */
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  	/* Wmax and fast convergence */
  	if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)
  		ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta))
  			/ (2 * BICTCP_BETA_SCALE);
  	else
  		ca->last_max_cwnd = tp->snd_cwnd;
  
  	ca->loss_cwnd = tp->snd_cwnd;
  
  
  	if (tp->snd_cwnd <= low_window)
  		return max(tp->snd_cwnd >> 1U, 2U);
  	else
  		return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U);
  }
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
186
  static u32 bictcp_undo_cwnd(struct sock *sk)
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
187
  {
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
188
189
  	const struct tcp_sock *tp = tcp_sk(sk);
  	const struct bictcp *ca = inet_csk_ca(sk);
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
190
191
  	return max(tp->snd_cwnd, ca->last_max_cwnd);
  }
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
192
  static void bictcp_state(struct sock *sk, u8 new_state)
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
193
194
  {
  	if (new_state == TCP_CA_Loss)
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
195
  		bictcp_reset(inet_csk_ca(sk));
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
196
  }
05d054503   Stephen Hemminger   [TCP] BIC: spelli...
197
  /* Track delayed acknowledgment ratio using sliding window
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
198
199
   * ratio = (15*ratio + sample) / 16
   */
164891aad   Stephen Hemminger   [TCP]: Congestion...
200
  static void bictcp_acked(struct sock *sk, u32 cnt, ktime_t last)
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
201
  {
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
202
  	const struct inet_connection_sock *icsk = inet_csk(sk);
05d054503   Stephen Hemminger   [TCP] BIC: spelli...
203
  	if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) {
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
204
  		struct bictcp *ca = inet_csk_ca(sk);
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
205
206
207
208
209
210
211
212
213
214
215
216
  		cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
  		ca->delayed_ack += cnt;
  	}
  }
  
  
  static struct tcp_congestion_ops bictcp = {
  	.init		= bictcp_init,
  	.ssthresh	= bictcp_recalc_ssthresh,
  	.cong_avoid	= bictcp_cong_avoid,
  	.set_state	= bictcp_state,
  	.undo_cwnd	= bictcp_undo_cwnd,
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
217
218
219
220
221
222
223
  	.pkts_acked     = bictcp_acked,
  	.owner		= THIS_MODULE,
  	.name		= "bic",
  };
  
  static int __init bictcp_register(void)
  {
65e3d7265   Alexey Dobriyan   [TCP] tcp_bic: us...
224
  	BUILD_BUG_ON(sizeof(struct bictcp) > ICSK_CA_PRIV_SIZE);
83803034f   Stephen Hemminger   [TCP]: Add TCP BI...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
  	return tcp_register_congestion_control(&bictcp);
  }
  
  static void __exit bictcp_unregister(void)
  {
  	tcp_unregister_congestion_control(&bictcp);
  }
  
  module_init(bictcp_register);
  module_exit(bictcp_unregister);
  
  MODULE_AUTHOR("Stephen Hemminger");
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("BIC TCP");