diff options
-rw-r--r-- | net/ipv4/tcp_htcp.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c index 63318b6e9d51..1020eb48d8d1 100644 --- a/net/ipv4/tcp_htcp.c +++ b/net/ipv4/tcp_htcp.c | |||
@@ -10,22 +10,23 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <net/tcp.h> | 11 | #include <net/tcp.h> |
12 | 12 | ||
13 | #define ALPHA_BASE (1<<7) /* 1.0 with shift << 7 */ | 13 | #define ALPHA_BASE (1<<7) /* 1.0 with shift << 7 */ |
14 | #define BETA_MIN (1<<6) /* 0.5 with shift << 7 */ | 14 | #define BETA_MIN (1<<6) /* 0.5 with shift << 7 */ |
15 | #define BETA_MAX 102 /* 0.8 with shift << 7 */ | 15 | #define BETA_MAX 102 /* 0.8 with shift << 7 */ |
16 | 16 | ||
17 | static int use_rtt_scaling = 1; | 17 | static int use_rtt_scaling __read_mostly = 1; |
18 | module_param(use_rtt_scaling, int, 0644); | 18 | module_param(use_rtt_scaling, int, 0644); |
19 | MODULE_PARM_DESC(use_rtt_scaling, "turn on/off RTT scaling"); | 19 | MODULE_PARM_DESC(use_rtt_scaling, "turn on/off RTT scaling"); |
20 | 20 | ||
21 | static int use_bandwidth_switch = 1; | 21 | static int use_bandwidth_switch __read_mostly = 1; |
22 | module_param(use_bandwidth_switch, int, 0644); | 22 | module_param(use_bandwidth_switch, int, 0644); |
23 | MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher"); | 23 | MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher"); |
24 | 24 | ||
25 | struct htcp { | 25 | struct htcp { |
26 | u32 alpha; /* Fixed point arith, << 7 */ | 26 | u32 alpha; /* Fixed point arith, << 7 */ |
27 | u8 beta; /* Fixed point arith, << 7 */ | 27 | u8 beta; /* Fixed point arith, << 7 */ |
28 | u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */ | 28 | u8 modeswitch; /* Delay modeswitch |
29 | until we had at least one congestion event */ | ||
29 | u16 pkts_acked; | 30 | u16 pkts_acked; |
30 | u32 packetcount; | 31 | u32 packetcount; |
31 | u32 minRTT; | 32 | u32 minRTT; |
@@ -44,14 +45,14 @@ struct htcp { | |||
44 | u32 lasttime; | 45 | u32 lasttime; |
45 | }; | 46 | }; |
46 | 47 | ||
47 | static inline u32 htcp_cong_time(struct htcp *ca) | 48 | static inline u32 htcp_cong_time(const struct htcp *ca) |
48 | { | 49 | { |
49 | return jiffies - ca->last_cong; | 50 | return jiffies - ca->last_cong; |
50 | } | 51 | } |
51 | 52 | ||
52 | static inline u32 htcp_ccount(struct htcp *ca) | 53 | static inline u32 htcp_ccount(const struct htcp *ca) |
53 | { | 54 | { |
54 | return htcp_cong_time(ca)/ca->minRTT; | 55 | return htcp_cong_time(ca) / ca->minRTT; |
55 | } | 56 | } |
56 | 57 | ||
57 | static inline void htcp_reset(struct htcp *ca) | 58 | static inline void htcp_reset(struct htcp *ca) |
@@ -67,10 +68,12 @@ static u32 htcp_cwnd_undo(struct sock *sk) | |||
67 | { | 68 | { |
68 | const struct tcp_sock *tp = tcp_sk(sk); | 69 | const struct tcp_sock *tp = tcp_sk(sk); |
69 | struct htcp *ca = inet_csk_ca(sk); | 70 | struct htcp *ca = inet_csk_ca(sk); |
71 | |||
70 | ca->last_cong = ca->undo_last_cong; | 72 | ca->last_cong = ca->undo_last_cong; |
71 | ca->maxRTT = ca->undo_maxRTT; | 73 | ca->maxRTT = ca->undo_maxRTT; |
72 | ca->old_maxB = ca->undo_old_maxB; | 74 | ca->old_maxB = ca->undo_old_maxB; |
73 | return max(tp->snd_cwnd, (tp->snd_ssthresh<<7)/ca->beta); | 75 | |
76 | return max(tp->snd_cwnd, (tp->snd_ssthresh << 7) / ca->beta); | ||
74 | } | 77 | } |
75 | 78 | ||
76 | static inline void measure_rtt(struct sock *sk) | 79 | static inline void measure_rtt(struct sock *sk) |
@@ -78,17 +81,19 @@ static inline void measure_rtt(struct sock *sk) | |||
78 | const struct inet_connection_sock *icsk = inet_csk(sk); | 81 | const struct inet_connection_sock *icsk = inet_csk(sk); |
79 | const struct tcp_sock *tp = tcp_sk(sk); | 82 | const struct tcp_sock *tp = tcp_sk(sk); |
80 | struct htcp *ca = inet_csk_ca(sk); | 83 | struct htcp *ca = inet_csk_ca(sk); |
81 | u32 srtt = tp->srtt>>3; | 84 | u32 srtt = tp->srtt >> 3; |
82 | 85 | ||
83 | /* keep track of minimum RTT seen so far, minRTT is zero at first */ | 86 | /* keep track of minimum RTT seen so far, minRTT is zero at first */ |
84 | if (ca->minRTT > srtt || !ca->minRTT) | 87 | if (ca->minRTT > srtt || !ca->minRTT) |
85 | ca->minRTT = srtt; | 88 | ca->minRTT = srtt; |
86 | 89 | ||
87 | /* max RTT */ | 90 | /* max RTT */ |
88 | if (icsk->icsk_ca_state == TCP_CA_Open && tp->snd_ssthresh < 0xFFFF && htcp_ccount(ca) > 3) { | 91 | if (icsk->icsk_ca_state == TCP_CA_Open |
92 | && tp->snd_ssthresh < 0xFFFF && htcp_ccount(ca) > 3) { | ||
89 | if (ca->maxRTT < ca->minRTT) | 93 | if (ca->maxRTT < ca->minRTT) |
90 | ca->maxRTT = ca->minRTT; | 94 | ca->maxRTT = ca->minRTT; |
91 | if (ca->maxRTT < srtt && srtt <= ca->maxRTT+msecs_to_jiffies(20)) | 95 | if (ca->maxRTT < srtt |
96 | && srtt <= ca->maxRTT + msecs_to_jiffies(20)) | ||
92 | ca->maxRTT = srtt; | 97 | ca->maxRTT = srtt; |
93 | } | 98 | } |
94 | } | 99 | } |
@@ -116,15 +121,16 @@ static void measure_achieved_throughput(struct sock *sk, u32 pkts_acked) | |||
116 | 121 | ||
117 | ca->packetcount += pkts_acked; | 122 | ca->packetcount += pkts_acked; |
118 | 123 | ||
119 | if (ca->packetcount >= tp->snd_cwnd - (ca->alpha>>7? : 1) | 124 | if (ca->packetcount >= tp->snd_cwnd - (ca->alpha >> 7 ? : 1) |
120 | && now - ca->lasttime >= ca->minRTT | 125 | && now - ca->lasttime >= ca->minRTT |
121 | && ca->minRTT > 0) { | 126 | && ca->minRTT > 0) { |
122 | __u32 cur_Bi = ca->packetcount*HZ/(now - ca->lasttime); | 127 | __u32 cur_Bi = ca->packetcount * HZ / (now - ca->lasttime); |
128 | |||
123 | if (htcp_ccount(ca) <= 3) { | 129 | if (htcp_ccount(ca) <= 3) { |
124 | /* just after backoff */ | 130 | /* just after backoff */ |
125 | ca->minB = ca->maxB = ca->Bi = cur_Bi; | 131 | ca->minB = ca->maxB = ca->Bi = cur_Bi; |
126 | } else { | 132 | } else { |
127 | ca->Bi = (3*ca->Bi + cur_Bi)/4; | 133 | ca->Bi = (3 * ca->Bi + cur_Bi) / 4; |
128 | if (ca->Bi > ca->maxB) | 134 | if (ca->Bi > ca->maxB) |
129 | ca->maxB = ca->Bi; | 135 | ca->maxB = ca->Bi; |
130 | if (ca->minB > ca->maxB) | 136 | if (ca->minB > ca->maxB) |
@@ -142,7 +148,7 @@ static inline void htcp_beta_update(struct htcp *ca, u32 minRTT, u32 maxRTT) | |||
142 | u32 old_maxB = ca->old_maxB; | 148 | u32 old_maxB = ca->old_maxB; |
143 | ca->old_maxB = ca->maxB; | 149 | ca->old_maxB = ca->maxB; |
144 | 150 | ||
145 | if (!between(5*maxB, 4*old_maxB, 6*old_maxB)) { | 151 | if (!between(5 * maxB, 4 * old_maxB, 6 * old_maxB)) { |
146 | ca->beta = BETA_MIN; | 152 | ca->beta = BETA_MIN; |
147 | ca->modeswitch = 0; | 153 | ca->modeswitch = 0; |
148 | return; | 154 | return; |
@@ -150,7 +156,7 @@ static inline void htcp_beta_update(struct htcp *ca, u32 minRTT, u32 maxRTT) | |||
150 | } | 156 | } |
151 | 157 | ||
152 | if (ca->modeswitch && minRTT > msecs_to_jiffies(10) && maxRTT) { | 158 | if (ca->modeswitch && minRTT > msecs_to_jiffies(10) && maxRTT) { |
153 | ca->beta = (minRTT<<7)/maxRTT; | 159 | ca->beta = (minRTT << 7) / maxRTT; |
154 | if (ca->beta < BETA_MIN) | 160 | if (ca->beta < BETA_MIN) |
155 | ca->beta = BETA_MIN; | 161 | ca->beta = BETA_MIN; |
156 | else if (ca->beta > BETA_MAX) | 162 | else if (ca->beta > BETA_MAX) |
@@ -169,23 +175,26 @@ static inline void htcp_alpha_update(struct htcp *ca) | |||
169 | 175 | ||
170 | if (diff > HZ) { | 176 | if (diff > HZ) { |
171 | diff -= HZ; | 177 | diff -= HZ; |
172 | factor = 1+ ( 10*diff + ((diff/2)*(diff/2)/HZ) )/HZ; | 178 | factor = 1 + (10 * diff + ((diff / 2) * (diff / 2) / HZ)) / HZ; |
173 | } | 179 | } |
174 | 180 | ||
175 | if (use_rtt_scaling && minRTT) { | 181 | if (use_rtt_scaling && minRTT) { |
176 | u32 scale = (HZ<<3)/(10*minRTT); | 182 | u32 scale = (HZ << 3) / (10 * minRTT); |
177 | scale = min(max(scale, 1U<<2), 10U<<3); /* clamping ratio to interval [0.5,10]<<3 */ | 183 | |
178 | factor = (factor<<3)/scale; | 184 | /* clamping ratio to interval [0.5,10]<<3 */ |
185 | scale = min(max(scale, 1U << 2), 10U << 3); | ||
186 | factor = (factor << 3) / scale; | ||
179 | if (!factor) | 187 | if (!factor) |
180 | factor = 1; | 188 | factor = 1; |
181 | } | 189 | } |
182 | 190 | ||
183 | ca->alpha = 2*factor*((1<<7)-ca->beta); | 191 | ca->alpha = 2 * factor * ((1 << 7) - ca->beta); |
184 | if (!ca->alpha) | 192 | if (!ca->alpha) |
185 | ca->alpha = ALPHA_BASE; | 193 | ca->alpha = ALPHA_BASE; |
186 | } | 194 | } |
187 | 195 | ||
188 | /* After we have the rtt data to calculate beta, we'd still prefer to wait one | 196 | /* |
197 | * After we have the rtt data to calculate beta, we'd still prefer to wait one | ||
189 | * rtt before we adjust our beta to ensure we are working from a consistent | 198 | * rtt before we adjust our beta to ensure we are working from a consistent |
190 | * data. | 199 | * data. |
191 | * | 200 | * |
@@ -202,15 +211,16 @@ static void htcp_param_update(struct sock *sk) | |||
202 | htcp_beta_update(ca, minRTT, maxRTT); | 211 | htcp_beta_update(ca, minRTT, maxRTT); |
203 | htcp_alpha_update(ca); | 212 | htcp_alpha_update(ca); |
204 | 213 | ||
205 | /* add slowly fading memory for maxRTT to accommodate routing changes etc */ | 214 | /* add slowly fading memory for maxRTT to accommodate routing changes */ |
206 | if (minRTT > 0 && maxRTT > minRTT) | 215 | if (minRTT > 0 && maxRTT > minRTT) |
207 | ca->maxRTT = minRTT + ((maxRTT-minRTT)*95)/100; | 216 | ca->maxRTT = minRTT + ((maxRTT - minRTT) * 95) / 100; |
208 | } | 217 | } |
209 | 218 | ||
210 | static u32 htcp_recalc_ssthresh(struct sock *sk) | 219 | static u32 htcp_recalc_ssthresh(struct sock *sk) |
211 | { | 220 | { |
212 | const struct tcp_sock *tp = tcp_sk(sk); | 221 | const struct tcp_sock *tp = tcp_sk(sk); |
213 | const struct htcp *ca = inet_csk_ca(sk); | 222 | const struct htcp *ca = inet_csk_ca(sk); |
223 | |||
214 | htcp_param_update(sk); | 224 | htcp_param_update(sk); |
215 | return max((tp->snd_cwnd * ca->beta) >> 7, 2U); | 225 | return max((tp->snd_cwnd * ca->beta) >> 7, 2U); |
216 | } | 226 | } |
@@ -227,7 +237,6 @@ static void htcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt, | |||
227 | if (tp->snd_cwnd <= tp->snd_ssthresh) | 237 | if (tp->snd_cwnd <= tp->snd_ssthresh) |
228 | tcp_slow_start(tp); | 238 | tcp_slow_start(tp); |
229 | else { | 239 | else { |
230 | |||
231 | measure_rtt(sk); | 240 | measure_rtt(sk); |
232 | 241 | ||
233 | /* In dangerous area, increase slowly. | 242 | /* In dangerous area, increase slowly. |