1 |
commit: 3c8127d4ebd36a23547beb8064cbedc12447d782 |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sat Nov 29 18:11:33 2014 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Sat Nov 29 18:11:33 2014 +0000 |
6 |
URL: http://sources.gentoo.org/gitweb/?p=proj/linux-patches.git;a=commit;h=3c8127d4 |
7 |
|
8 |
Update multipath patch |
9 |
|
10 |
--- |
11 |
0000_README | 2 +- |
12 |
... => 5010_multipath-tcp-v3.16-075df3a63833.patch | 328 +++++++++++++++++++-- |
13 |
2 files changed, 312 insertions(+), 18 deletions(-) |
14 |
|
15 |
diff --git a/0000_README b/0000_README |
16 |
index 0ab3968..8719a11 100644 |
17 |
--- a/0000_README |
18 |
+++ b/0000_README |
19 |
@@ -118,7 +118,7 @@ Patch: 5003_BFQ-3-block-add-Early-Queue-Merge-EQM-v7r6-for-3.16.0.patch |
20 |
From: http://algo.ing.unimo.it/people/paolo/disk_sched/ |
21 |
Desc: BFQ v7r6 patch 3 for 3.16: Early Queue Merge (EQM) |
22 |
|
23 |
-Patch: 5010_multipath-tcp-v3.16-872d7f6c6f4e.patch |
24 |
+Patch: 5010_multipath-tcp-v3.16-075df3a63833.patch |
25 |
From: http://multipath-tcp.org/ |
26 |
Desc: Patch for simultaneous use of several IP-addresses/interfaces in TCP for better resource utilization, better throughput and smoother reaction to failures. |
27 |
|
28 |
|
29 |
diff --git a/5010_multipath-tcp-v3.16-872d7f6c6f4e.patch b/5010_multipath-tcp-v3.16-075df3a63833.patch |
30 |
similarity index 98% |
31 |
rename from 5010_multipath-tcp-v3.16-872d7f6c6f4e.patch |
32 |
rename to 5010_multipath-tcp-v3.16-075df3a63833.patch |
33 |
index 3000da3..7520b4a 100644 |
34 |
--- a/5010_multipath-tcp-v3.16-872d7f6c6f4e.patch |
35 |
+++ b/5010_multipath-tcp-v3.16-075df3a63833.patch |
36 |
@@ -2572,10 +2572,10 @@ index 4db3c2a1679c..04cb17d4b0ce 100644 |
37 |
goto drop; |
38 |
|
39 |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig |
40 |
-index 05c57f0fcabe..630434db0085 100644 |
41 |
+index 05c57f0fcabe..811286a6aa9c 100644 |
42 |
--- a/net/ipv4/Kconfig |
43 |
+++ b/net/ipv4/Kconfig |
44 |
-@@ -556,6 +556,30 @@ config TCP_CONG_ILLINOIS |
45 |
+@@ -556,6 +556,38 @@ config TCP_CONG_ILLINOIS |
46 |
For further details see: |
47 |
http://www.ews.uiuc.edu/~shaoliu/tcpillinois/index.html |
48 |
|
49 |
@@ -2603,10 +2603,18 @@ index 05c57f0fcabe..630434db0085 100644 |
50 |
+ wVegas congestion control for MPTCP |
51 |
+ To enable it, just put 'wvegas' in tcp_congestion_control |
52 |
+ |
53 |
++config TCP_CONG_BALIA |
54 |
++ tristate "MPTCP BALIA CONGESTION CONTROL" |
55 |
++ depends on MPTCP |
56 |
++ default n |
57 |
++ ---help--- |
58 |
++ Multipath TCP Balanced Linked Adaptation Congestion Control |
59 |
++ To enable it, just put 'balia' in tcp_congestion_control |
60 |
++ |
61 |
choice |
62 |
prompt "Default TCP congestion control" |
63 |
default DEFAULT_CUBIC |
64 |
-@@ -584,6 +608,15 @@ choice |
65 |
+@@ -584,6 +616,18 @@ choice |
66 |
config DEFAULT_WESTWOOD |
67 |
bool "Westwood" if TCP_CONG_WESTWOOD=y |
68 |
|
69 |
@@ -2619,15 +2627,19 @@ index 05c57f0fcabe..630434db0085 100644 |
70 |
+ config DEFAULT_WVEGAS |
71 |
+ bool "Wvegas" if TCP_CONG_WVEGAS=y |
72 |
+ |
73 |
++ config DEFAULT_BALIA |
74 |
++ bool "Balia" if TCP_CONG_BALIA=y |
75 |
++ |
76 |
config DEFAULT_RENO |
77 |
bool "Reno" |
78 |
|
79 |
-@@ -605,6 +638,8 @@ config DEFAULT_TCP_CONG |
80 |
+@@ -605,6 +649,9 @@ config DEFAULT_TCP_CONG |
81 |
default "vegas" if DEFAULT_VEGAS |
82 |
default "westwood" if DEFAULT_WESTWOOD |
83 |
default "veno" if DEFAULT_VENO |
84 |
+ default "coupled" if DEFAULT_COUPLED |
85 |
+ default "wvegas" if DEFAULT_WVEGAS |
86 |
++ default "balia" if DEFAULT_BALIA |
87 |
default "reno" if DEFAULT_RENO |
88 |
default "cubic" |
89 |
|
90 |
@@ -7087,10 +7099,10 @@ index 000000000000..cdfc03adabf8 |
91 |
+ |
92 |
diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile |
93 |
new file mode 100644 |
94 |
-index 000000000000..35561a7012e3 |
95 |
+index 000000000000..2feb3e873206 |
96 |
--- /dev/null |
97 |
+++ b/net/mptcp/Makefile |
98 |
-@@ -0,0 +1,20 @@ |
99 |
+@@ -0,0 +1,21 @@ |
100 |
+# |
101 |
+## Makefile for MultiPath TCP support code. |
102 |
+# |
103 |
@@ -7104,6 +7116,7 @@ index 000000000000..35561a7012e3 |
104 |
+obj-$(CONFIG_TCP_CONG_COUPLED) += mptcp_coupled.o |
105 |
+obj-$(CONFIG_TCP_CONG_OLIA) += mptcp_olia.o |
106 |
+obj-$(CONFIG_TCP_CONG_WVEGAS) += mptcp_wvegas.o |
107 |
++obj-$(CONFIG_TCP_CONG_BALIA) += mptcp_balia.o |
108 |
+obj-$(CONFIG_MPTCP_FULLMESH) += mptcp_fullmesh.o |
109 |
+obj-$(CONFIG_MPTCP_NDIFFPORTS) += mptcp_ndiffports.o |
110 |
+obj-$(CONFIG_MPTCP_BINDER) += mptcp_binder.o |
111 |
@@ -7111,6 +7124,279 @@ index 000000000000..35561a7012e3 |
112 |
+ |
113 |
+mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o |
114 |
+ |
115 |
+diff --git a/net/mptcp/mptcp_balia.c b/net/mptcp/mptcp_balia.c |
116 |
+new file mode 100644 |
117 |
+index 000000000000..5cc224d80b01 |
118 |
+--- /dev/null |
119 |
++++ b/net/mptcp/mptcp_balia.c |
120 |
+@@ -0,0 +1,267 @@ |
121 |
++/* |
122 |
++ * MPTCP implementation - Balia Congestion Control |
123 |
++ * (Balanced Linked Adaptation Algorithm) |
124 |
++ * |
125 |
++ * Analysis, Design and Implementation: |
126 |
++ * Qiuyu Peng <qpeng@×××××××.edu> |
127 |
++ * Anwar Walid <anwar@××××××××××××××××××.com> |
128 |
++ * Jaehyun Hwang <jh.hwang@××××××××××××××.com> |
129 |
++ * Steven H. Low <slow@×××××××.edu> |
130 |
++ * |
131 |
++ * This program is free software; you can redistribute it and/or |
132 |
++ * modify it under the terms of the GNU General Public License |
133 |
++ * as published by the Free Software Foundation; either version |
134 |
++ * 2 of the License, or (at your option) any later version. |
135 |
++ */ |
136 |
++ |
137 |
++#include <net/tcp.h> |
138 |
++#include <net/mptcp.h> |
139 |
++ |
140 |
++#include <linux/module.h> |
141 |
++ |
142 |
++/* The variable 'rate' (i.e., x_r) will be scaled down |
143 |
++ * e.g., from B/s to KB/s, MB/s, or GB/s |
144 |
++ * if max_rate > 2^rate_scale_limit |
145 |
++ */ |
146 |
++ |
147 |
++static int rate_scale_limit = 30; |
148 |
++static int scale_num = 10; |
149 |
++ |
150 |
++struct mptcp_balia { |
151 |
++ u64 ai; |
152 |
++ u64 md; |
153 |
++ bool forced_update; |
154 |
++}; |
155 |
++ |
156 |
++static inline int mptcp_balia_sk_can_send(const struct sock *sk) |
157 |
++{ |
158 |
++ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; |
159 |
++} |
160 |
++ |
161 |
++static inline u64 mptcp_get_ai(const struct sock *meta_sk) |
162 |
++{ |
163 |
++ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai; |
164 |
++} |
165 |
++ |
166 |
++static inline void mptcp_set_ai(const struct sock *meta_sk, u64 ai) |
167 |
++{ |
168 |
++ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai = ai; |
169 |
++} |
170 |
++ |
171 |
++static inline u64 mptcp_get_md(const struct sock *meta_sk) |
172 |
++{ |
173 |
++ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md; |
174 |
++} |
175 |
++ |
176 |
++static inline void mptcp_set_md(const struct sock *meta_sk, u64 md) |
177 |
++{ |
178 |
++ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md = md; |
179 |
++} |
180 |
++ |
181 |
++static inline u64 mptcp_balia_scale(u64 val, int scale) |
182 |
++{ |
183 |
++ return (u64) val << scale; |
184 |
++} |
185 |
++ |
186 |
++static inline bool mptcp_get_forced(const struct sock *meta_sk) |
187 |
++{ |
188 |
++ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update; |
189 |
++} |
190 |
++ |
191 |
++static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) |
192 |
++{ |
193 |
++ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update = force; |
194 |
++} |
195 |
++ |
196 |
++static void mptcp_balia_recalc_ai(const struct sock *sk) |
197 |
++{ |
198 |
++ const struct tcp_sock *tp = tcp_sk(sk); |
199 |
++ const struct mptcp_cb *mpcb = tp->mpcb; |
200 |
++ const struct sock *sub_sk; |
201 |
++ int can_send = 0; |
202 |
++ u64 max_rate = 0, rate = 0, sum_rate = 0; |
203 |
++ u64 alpha = 0, ai = 0, md = 0; |
204 |
++ int num_scale_down = 0; |
205 |
++ |
206 |
++ if (!mpcb) |
207 |
++ return; |
208 |
++ |
209 |
++ /* Only one subflow left - fall back to normal reno-behavior */ |
210 |
++ if (mpcb->cnt_established <= 1) |
211 |
++ goto exit; |
212 |
++ |
213 |
++ /* Find max_rate first */ |
214 |
++ mptcp_for_each_sk(mpcb, sub_sk) { |
215 |
++ struct tcp_sock *sub_tp = tcp_sk(sub_sk); |
216 |
++ u64 tmp; |
217 |
++ |
218 |
++ if (!mptcp_balia_sk_can_send(sub_sk)) |
219 |
++ continue; |
220 |
++ |
221 |
++ can_send++; |
222 |
++ |
223 |
++ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd |
224 |
++ * (USEC_PER_SEC << 3), sub_tp->srtt_us); |
225 |
++ sum_rate += tmp; |
226 |
++ |
227 |
++ if (tmp >= max_rate) |
228 |
++ max_rate = tmp; |
229 |
++ } |
230 |
++ |
231 |
++ /* No subflow is able to send - we don't care anymore */ |
232 |
++ if (unlikely(!can_send)) |
233 |
++ goto exit; |
234 |
++ |
235 |
++ rate = div_u64((u64)tp->mss_cache * tp->snd_cwnd * |
236 |
++ (USEC_PER_SEC << 3), tp->srtt_us); |
237 |
++ alpha = div64_u64(max_rate, rate); |
238 |
++ |
239 |
++ /* Scale down max_rate from B/s to KB/s, MB/s, or GB/s |
240 |
++ * if max_rate is too high (i.e., >2^30) |
241 |
++ */ |
242 |
++ while (max_rate > mptcp_balia_scale(1, rate_scale_limit)) { |
243 |
++ max_rate >>= scale_num; |
244 |
++ num_scale_down++; |
245 |
++ } |
246 |
++ |
247 |
++ if (num_scale_down) { |
248 |
++ sum_rate = 0; |
249 |
++ mptcp_for_each_sk(mpcb, sub_sk) { |
250 |
++ struct tcp_sock *sub_tp = tcp_sk(sub_sk); |
251 |
++ u64 tmp; |
252 |
++ |
253 |
++ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd |
254 |
++ * (USEC_PER_SEC << 3), sub_tp->srtt_us); |
255 |
++ tmp >>= (scale_num * num_scale_down); |
256 |
++ |
257 |
++ sum_rate += tmp; |
258 |
++ } |
259 |
++ rate >>= (scale_num * num_scale_down); |
260 |
++ } |
261 |
++ |
262 |
++ /* (sum_rate)^2 * 10 * w_r |
263 |
++ * ai = ------------------------------------ |
264 |
++ * (x_r + max_rate) * (4x_r + max_rate) |
265 |
++ */ |
266 |
++ sum_rate *= sum_rate; |
267 |
++ |
268 |
++ ai = div64_u64(sum_rate * 10, rate + max_rate); |
269 |
++ ai = div64_u64(ai * tp->snd_cwnd, (rate << 2) + max_rate); |
270 |
++ |
271 |
++ if (unlikely(!ai)) |
272 |
++ ai = tp->snd_cwnd; |
273 |
++ |
274 |
++ md = ((tp->snd_cwnd >> 1) * min(mptcp_balia_scale(alpha, scale_num), |
275 |
++ mptcp_balia_scale(3, scale_num) >> 1)) |
276 |
++ >> scale_num; |
277 |
++ |
278 |
++exit: |
279 |
++ mptcp_set_ai(sk, ai); |
280 |
++ mptcp_set_md(sk, md); |
281 |
++} |
282 |
++ |
283 |
++static void mptcp_balia_init(struct sock *sk) |
284 |
++{ |
285 |
++ if (mptcp(tcp_sk(sk))) { |
286 |
++ mptcp_set_forced(sk, 0); |
287 |
++ mptcp_set_ai(sk, 0); |
288 |
++ mptcp_set_md(sk, 0); |
289 |
++ } |
290 |
++} |
291 |
++ |
292 |
++static void mptcp_balia_cwnd_event(struct sock *sk, enum tcp_ca_event event) |
293 |
++{ |
294 |
++ if (event == CA_EVENT_COMPLETE_CWR || event == CA_EVENT_LOSS) |
295 |
++ mptcp_balia_recalc_ai(sk); |
296 |
++} |
297 |
++ |
298 |
++static void mptcp_balia_set_state(struct sock *sk, u8 ca_state) |
299 |
++{ |
300 |
++ if (!mptcp(tcp_sk(sk))) |
301 |
++ return; |
302 |
++ |
303 |
++ mptcp_set_forced(sk, 1); |
304 |
++} |
305 |
++ |
306 |
++static void mptcp_balia_cong_avoid(struct sock *sk, u32 ack, u32 acked) |
307 |
++{ |
308 |
++ struct tcp_sock *tp = tcp_sk(sk); |
309 |
++ const struct mptcp_cb *mpcb = tp->mpcb; |
310 |
++ int snd_cwnd; |
311 |
++ |
312 |
++ if (!mptcp(tp)) { |
313 |
++ tcp_reno_cong_avoid(sk, ack, acked); |
314 |
++ return; |
315 |
++ } |
316 |
++ |
317 |
++ if (!tcp_is_cwnd_limited(sk)) |
318 |
++ return; |
319 |
++ |
320 |
++ if (tp->snd_cwnd <= tp->snd_ssthresh) { |
321 |
++ /* In "safe" area, increase. */ |
322 |
++ tcp_slow_start(tp, acked); |
323 |
++ mptcp_balia_recalc_ai(sk); |
324 |
++ return; |
325 |
++ } |
326 |
++ |
327 |
++ if (mptcp_get_forced(mptcp_meta_sk(sk))) { |
328 |
++ mptcp_balia_recalc_ai(sk); |
329 |
++ mptcp_set_forced(sk, 0); |
330 |
++ } |
331 |
++ |
332 |
++ if (mpcb->cnt_established > 1) |
333 |
++ snd_cwnd = (int) mptcp_get_ai(sk); |
334 |
++ else |
335 |
++ snd_cwnd = tp->snd_cwnd; |
336 |
++ |
337 |
++ if (tp->snd_cwnd_cnt >= snd_cwnd) { |
338 |
++ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { |
339 |
++ tp->snd_cwnd++; |
340 |
++ mptcp_balia_recalc_ai(sk); |
341 |
++ } |
342 |
++ |
343 |
++ tp->snd_cwnd_cnt = 0; |
344 |
++ } else { |
345 |
++ tp->snd_cwnd_cnt++; |
346 |
++ } |
347 |
++} |
348 |
++ |
349 |
++static u32 mptcp_balia_ssthresh(struct sock *sk) |
350 |
++{ |
351 |
++ const struct tcp_sock *tp = tcp_sk(sk); |
352 |
++ const struct mptcp_cb *mpcb = tp->mpcb; |
353 |
++ |
354 |
++ if (unlikely(!mptcp(tp) || mpcb->cnt_established <= 1)) |
355 |
++ return tcp_reno_ssthresh(sk); |
356 |
++ else |
357 |
++ return max((u32)(tp->snd_cwnd - mptcp_get_md(sk)), 1U); |
358 |
++} |
359 |
++ |
360 |
++static struct tcp_congestion_ops mptcp_balia = { |
361 |
++ .init = mptcp_balia_init, |
362 |
++ .ssthresh = mptcp_balia_ssthresh, |
363 |
++ .cong_avoid = mptcp_balia_cong_avoid, |
364 |
++ .cwnd_event = mptcp_balia_cwnd_event, |
365 |
++ .set_state = mptcp_balia_set_state, |
366 |
++ .owner = THIS_MODULE, |
367 |
++ .name = "balia", |
368 |
++}; |
369 |
++ |
370 |
++static int __init mptcp_balia_register(void) |
371 |
++{ |
372 |
++ BUILD_BUG_ON(sizeof(struct mptcp_balia) > ICSK_CA_PRIV_SIZE); |
373 |
++ return tcp_register_congestion_control(&mptcp_balia); |
374 |
++} |
375 |
++ |
376 |
++static void __exit mptcp_balia_unregister(void) |
377 |
++{ |
378 |
++ tcp_unregister_congestion_control(&mptcp_balia); |
379 |
++} |
380 |
++ |
381 |
++module_init(mptcp_balia_register); |
382 |
++module_exit(mptcp_balia_unregister); |
383 |
++ |
384 |
++MODULE_AUTHOR("Jaehyun Hwang, Anwar Walid, Qiuyu Peng, Steven H. Low"); |
385 |
++MODULE_LICENSE("GPL"); |
386 |
++MODULE_DESCRIPTION("MPTCP BALIA CONGESTION CONTROL ALGORITHM"); |
387 |
++MODULE_VERSION("0.1"); |
388 |
diff --git a/net/mptcp/mptcp_binder.c b/net/mptcp/mptcp_binder.c |
389 |
new file mode 100644 |
390 |
index 000000000000..95d8da560715 |
391 |
@@ -10289,10 +10575,10 @@ index 000000000000..28dfa0479f5e |
392 |
+} |
393 |
diff --git a/net/mptcp/mptcp_fullmesh.c b/net/mptcp/mptcp_fullmesh.c |
394 |
new file mode 100644 |
395 |
-index 000000000000..3a54413ce25b |
396 |
+index 000000000000..2e4895c9e49c |
397 |
--- /dev/null |
398 |
+++ b/net/mptcp/mptcp_fullmesh.c |
399 |
-@@ -0,0 +1,1722 @@ |
400 |
+@@ -0,0 +1,1730 @@ |
401 |
+#include <linux/module.h> |
402 |
+ |
403 |
+#include <net/mptcp.h> |
404 |
@@ -11282,10 +11568,10 @@ index 000000000000..3a54413ce25b |
405 |
+static int inet6_addr_event(struct notifier_block *this, |
406 |
+ unsigned long event, void *ptr); |
407 |
+ |
408 |
-+static int ipv6_is_in_dad_state(const struct inet6_ifaddr *ifa) |
409 |
++static bool ipv6_dad_finished(const struct inet6_ifaddr *ifa) |
410 |
+{ |
411 |
-+ return (ifa->flags & IFA_F_TENTATIVE) && |
412 |
-+ ifa->state == INET6_IFADDR_STATE_DAD; |
413 |
++ return !(ifa->flags & IFA_F_TENTATIVE) || |
414 |
++ ifa->state > INET6_IFADDR_STATE_DAD; |
415 |
+} |
416 |
+ |
417 |
+static void dad_init_timer(struct mptcp_dad_data *data, |
418 |
@@ -11304,14 +11590,22 @@ index 000000000000..3a54413ce25b |
419 |
+{ |
420 |
+ struct mptcp_dad_data *data = (struct mptcp_dad_data *)arg; |
421 |
+ |
422 |
-+ if (ipv6_is_in_dad_state(data->ifa)) { |
423 |
++ /* DAD failed or IP brought down? */ |
424 |
++ if (data->ifa->state == INET6_IFADDR_STATE_ERRDAD || |
425 |
++ data->ifa->state == INET6_IFADDR_STATE_DEAD) |
426 |
++ goto exit; |
427 |
++ |
428 |
++ if (!ipv6_dad_finished(data->ifa)) { |
429 |
+ dad_init_timer(data, data->ifa); |
430 |
+ add_timer(&data->timer); |
431 |
-+ } else { |
432 |
-+ inet6_addr_event(NULL, NETDEV_UP, data->ifa); |
433 |
-+ in6_ifa_put(data->ifa); |
434 |
-+ kfree(data); |
435 |
++ return; |
436 |
+ } |
437 |
++ |
438 |
++ inet6_addr_event(NULL, NETDEV_UP, data->ifa); |
439 |
++ |
440 |
++exit: |
441 |
++ in6_ifa_put(data->ifa); |
442 |
++ kfree(data); |
443 |
+} |
444 |
+ |
445 |
+static inline void dad_setup_timer(struct inet6_ifaddr *ifa) |
446 |
@@ -11376,7 +11670,7 @@ index 000000000000..3a54413ce25b |
447 |
+ event == NETDEV_CHANGE)) |
448 |
+ return NOTIFY_DONE; |
449 |
+ |
450 |
-+ if (ipv6_is_in_dad_state(ifa6)) |
451 |
++ if (!ipv6_dad_finished(ifa6)) |
452 |
+ dad_setup_timer(ifa6); |
453 |
+ else |
454 |
+ addr6_event_handler(ifa6, event, net); |