1 |
commit: c7c74e3aa504834b4e6e357236858fd1b8f6d636 |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sat Oct 13 16:35:22 2018 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Nov 21 15:01:44 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c7c74e3a |
7 |
|
8 |
Linux patch 4.4.161 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1160_linux-4.4.161.patch | 1482 ++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 1486 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 8c70f7e..d7ad776 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -683,6 +683,10 @@ Patch: 1159_linux-4.4.160.patch |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 4.4.160 |
23 |
|
24 |
+Patch: 1160_linux-4.4.161.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 4.4.161 |
27 |
+ |
28 |
Patch: 1500_XATTR_USER_PREFIX.patch |
29 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
30 |
Desc: Support for namespace user.pax.* on tmpfs. |
31 |
|
32 |
diff --git a/1160_linux-4.4.161.patch b/1160_linux-4.4.161.patch |
33 |
new file mode 100644 |
34 |
index 0000000..2268044 |
35 |
--- /dev/null |
36 |
+++ b/1160_linux-4.4.161.patch |
37 |
@@ -0,0 +1,1482 @@ |
38 |
+diff --git a/Makefile b/Makefile |
39 |
+index 607394a56036..57e4ff1a8b96 100644 |
40 |
+--- a/Makefile |
41 |
++++ b/Makefile |
42 |
+@@ -1,6 +1,6 @@ |
43 |
+ VERSION = 4 |
44 |
+ PATCHLEVEL = 4 |
45 |
+-SUBLEVEL = 160 |
46 |
++SUBLEVEL = 161 |
47 |
+ EXTRAVERSION = |
48 |
+ NAME = Blurry Fish Butt |
49 |
+ |
50 |
+diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c |
51 |
+index a3f750e76b68..8f40c6c5d77e 100644 |
52 |
+--- a/arch/arc/kernel/process.c |
53 |
++++ b/arch/arc/kernel/process.c |
54 |
+@@ -153,6 +153,26 @@ int copy_thread(unsigned long clone_flags, |
55 |
+ task_thread_info(current)->thr_ptr; |
56 |
+ } |
57 |
+ |
58 |
++ |
59 |
++ /* |
60 |
++ * setup usermode thread pointer #1: |
61 |
++ * when child is picked by scheduler, __switch_to() uses @c_callee to |
62 |
++ * populate usermode callee regs: this works (despite being in a kernel |
63 |
++ * function) since special return path for child @ret_from_fork() |
64 |
++ * ensures those regs are not clobbered all the way to RTIE to usermode |
65 |
++ */ |
66 |
++ c_callee->r25 = task_thread_info(p)->thr_ptr; |
67 |
++ |
68 |
++#ifdef CONFIG_ARC_CURR_IN_REG |
69 |
++ /* |
70 |
++ * setup usermode thread pointer #2: |
71 |
++ * however for this special use of r25 in kernel, __switch_to() sets |
72 |
++ * r25 for kernel needs and only in the final return path is usermode |
73 |
++ * r25 setup, from pt_regs->user_r25. So set that up as well |
74 |
++ */ |
75 |
++ c_regs->user_r25 = c_callee->r25; |
76 |
++#endif |
77 |
++ |
78 |
+ return 0; |
79 |
+ } |
80 |
+ |
81 |
+diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c |
82 |
+index c3c835290131..ca3ad5ebcd41 100644 |
83 |
+--- a/arch/powerpc/kernel/fadump.c |
84 |
++++ b/arch/powerpc/kernel/fadump.c |
85 |
+@@ -360,9 +360,9 @@ static int __init early_fadump_reserve_mem(char *p) |
86 |
+ } |
87 |
+ early_param("fadump_reserve_mem", early_fadump_reserve_mem); |
88 |
+ |
89 |
+-static void register_fw_dump(struct fadump_mem_struct *fdm) |
90 |
++static int register_fw_dump(struct fadump_mem_struct *fdm) |
91 |
+ { |
92 |
+- int rc; |
93 |
++ int rc, err; |
94 |
+ unsigned int wait_time; |
95 |
+ |
96 |
+ pr_debug("Registering for firmware-assisted kernel dump...\n"); |
97 |
+@@ -379,7 +379,11 @@ static void register_fw_dump(struct fadump_mem_struct *fdm) |
98 |
+ |
99 |
+ } while (wait_time); |
100 |
+ |
101 |
++ err = -EIO; |
102 |
+ switch (rc) { |
103 |
++ default: |
104 |
++ pr_err("Failed to register. Unknown Error(%d).\n", rc); |
105 |
++ break; |
106 |
+ case -1: |
107 |
+ printk(KERN_ERR "Failed to register firmware-assisted kernel" |
108 |
+ " dump. Hardware Error(%d).\n", rc); |
109 |
+@@ -387,18 +391,22 @@ static void register_fw_dump(struct fadump_mem_struct *fdm) |
110 |
+ case -3: |
111 |
+ printk(KERN_ERR "Failed to register firmware-assisted kernel" |
112 |
+ " dump. Parameter Error(%d).\n", rc); |
113 |
++ err = -EINVAL; |
114 |
+ break; |
115 |
+ case -9: |
116 |
+ printk(KERN_ERR "firmware-assisted kernel dump is already " |
117 |
+ " registered."); |
118 |
+ fw_dump.dump_registered = 1; |
119 |
++ err = -EEXIST; |
120 |
+ break; |
121 |
+ case 0: |
122 |
+ printk(KERN_INFO "firmware-assisted kernel dump registration" |
123 |
+ " is successful\n"); |
124 |
+ fw_dump.dump_registered = 1; |
125 |
++ err = 0; |
126 |
+ break; |
127 |
+ } |
128 |
++ return err; |
129 |
+ } |
130 |
+ |
131 |
+ void crash_fadump(struct pt_regs *regs, const char *str) |
132 |
+@@ -997,7 +1005,7 @@ static unsigned long init_fadump_header(unsigned long addr) |
133 |
+ return addr; |
134 |
+ } |
135 |
+ |
136 |
+-static void register_fadump(void) |
137 |
++static int register_fadump(void) |
138 |
+ { |
139 |
+ unsigned long addr; |
140 |
+ void *vaddr; |
141 |
+@@ -1008,7 +1016,7 @@ static void register_fadump(void) |
142 |
+ * assisted dump. |
143 |
+ */ |
144 |
+ if (!fw_dump.reserve_dump_area_size) |
145 |
+- return; |
146 |
++ return -ENODEV; |
147 |
+ |
148 |
+ ret = fadump_setup_crash_memory_ranges(); |
149 |
+ if (ret) |
150 |
+@@ -1023,7 +1031,7 @@ static void register_fadump(void) |
151 |
+ fadump_create_elfcore_headers(vaddr); |
152 |
+ |
153 |
+ /* register the future kernel dump with firmware. */ |
154 |
+- register_fw_dump(&fdm); |
155 |
++ return register_fw_dump(&fdm); |
156 |
+ } |
157 |
+ |
158 |
+ static int fadump_unregister_dump(struct fadump_mem_struct *fdm) |
159 |
+@@ -1208,7 +1216,6 @@ static ssize_t fadump_register_store(struct kobject *kobj, |
160 |
+ switch (buf[0]) { |
161 |
+ case '0': |
162 |
+ if (fw_dump.dump_registered == 0) { |
163 |
+- ret = -EINVAL; |
164 |
+ goto unlock_out; |
165 |
+ } |
166 |
+ /* Un-register Firmware-assisted dump */ |
167 |
+@@ -1216,11 +1223,11 @@ static ssize_t fadump_register_store(struct kobject *kobj, |
168 |
+ break; |
169 |
+ case '1': |
170 |
+ if (fw_dump.dump_registered == 1) { |
171 |
+- ret = -EINVAL; |
172 |
++ ret = -EEXIST; |
173 |
+ goto unlock_out; |
174 |
+ } |
175 |
+ /* Register Firmware-assisted dump */ |
176 |
+- register_fadump(); |
177 |
++ ret = register_fadump(); |
178 |
+ break; |
179 |
+ default: |
180 |
+ ret = -EINVAL; |
181 |
+diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c |
182 |
+index 5dd363d54348..049327ee8868 100644 |
183 |
+--- a/arch/x86/entry/vdso/vclock_gettime.c |
184 |
++++ b/arch/x86/entry/vdso/vclock_gettime.c |
185 |
+@@ -51,8 +51,9 @@ extern u8 pvclock_page |
186 |
+ notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) |
187 |
+ { |
188 |
+ long ret; |
189 |
+- asm("syscall" : "=a" (ret) : |
190 |
+- "0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory"); |
191 |
++ asm ("syscall" : "=a" (ret), "=m" (*ts) : |
192 |
++ "0" (__NR_clock_gettime), "D" (clock), "S" (ts) : |
193 |
++ "memory", "rcx", "r11"); |
194 |
+ return ret; |
195 |
+ } |
196 |
+ |
197 |
+@@ -60,8 +61,9 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz) |
198 |
+ { |
199 |
+ long ret; |
200 |
+ |
201 |
+- asm("syscall" : "=a" (ret) : |
202 |
+- "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory"); |
203 |
++ asm ("syscall" : "=a" (ret), "=m" (*tv), "=m" (*tz) : |
204 |
++ "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : |
205 |
++ "memory", "rcx", "r11"); |
206 |
+ return ret; |
207 |
+ } |
208 |
+ |
209 |
+@@ -143,13 +145,13 @@ notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) |
210 |
+ { |
211 |
+ long ret; |
212 |
+ |
213 |
+- asm( |
214 |
++ asm ( |
215 |
+ "mov %%ebx, %%edx \n" |
216 |
+- "mov %2, %%ebx \n" |
217 |
++ "mov %[clock], %%ebx \n" |
218 |
+ "call __kernel_vsyscall \n" |
219 |
+ "mov %%edx, %%ebx \n" |
220 |
+- : "=a" (ret) |
221 |
+- : "0" (__NR_clock_gettime), "g" (clock), "c" (ts) |
222 |
++ : "=a" (ret), "=m" (*ts) |
223 |
++ : "0" (__NR_clock_gettime), [clock] "g" (clock), "c" (ts) |
224 |
+ : "memory", "edx"); |
225 |
+ return ret; |
226 |
+ } |
227 |
+@@ -158,13 +160,13 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz) |
228 |
+ { |
229 |
+ long ret; |
230 |
+ |
231 |
+- asm( |
232 |
++ asm ( |
233 |
+ "mov %%ebx, %%edx \n" |
234 |
+- "mov %2, %%ebx \n" |
235 |
++ "mov %[tv], %%ebx \n" |
236 |
+ "call __kernel_vsyscall \n" |
237 |
+ "mov %%edx, %%ebx \n" |
238 |
+- : "=a" (ret) |
239 |
+- : "0" (__NR_gettimeofday), "g" (tv), "c" (tz) |
240 |
++ : "=a" (ret), "=m" (*tv), "=m" (*tz) |
241 |
++ : "0" (__NR_gettimeofday), [tv] "g" (tv), "c" (tz) |
242 |
+ : "memory", "edx"); |
243 |
+ return ret; |
244 |
+ } |
245 |
+diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c |
246 |
+index e9b713675c7c..05409141ec07 100644 |
247 |
+--- a/drivers/base/power/main.c |
248 |
++++ b/drivers/base/power/main.c |
249 |
+@@ -1355,8 +1355,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) |
250 |
+ |
251 |
+ dpm_wait_for_children(dev, async); |
252 |
+ |
253 |
+- if (async_error) |
254 |
++ if (async_error) { |
255 |
++ dev->power.direct_complete = false; |
256 |
+ goto Complete; |
257 |
++ } |
258 |
+ |
259 |
+ /* |
260 |
+ * If a device configured to wake up the system from sleep states |
261 |
+@@ -1368,6 +1370,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) |
262 |
+ pm_wakeup_event(dev, 0); |
263 |
+ |
264 |
+ if (pm_wakeup_pending()) { |
265 |
++ dev->power.direct_complete = false; |
266 |
+ async_error = -EBUSY; |
267 |
+ goto Complete; |
268 |
+ } |
269 |
+diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c |
270 |
+index 9712a63957e1..7525e9f6949e 100644 |
271 |
+--- a/drivers/infiniband/core/ucma.c |
272 |
++++ b/drivers/infiniband/core/ucma.c |
273 |
+@@ -1709,6 +1709,8 @@ static int ucma_close(struct inode *inode, struct file *filp) |
274 |
+ mutex_lock(&mut); |
275 |
+ if (!ctx->closing) { |
276 |
+ mutex_unlock(&mut); |
277 |
++ ucma_put_ctx(ctx); |
278 |
++ wait_for_completion(&ctx->comp); |
279 |
+ /* rdma_destroy_id ensures that no event handlers are |
280 |
+ * inflight for that id before releasing it. |
281 |
+ */ |
282 |
+diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c |
283 |
+index b59615ddf6ba..531d6f3a786e 100644 |
284 |
+--- a/drivers/md/dm-cache-target.c |
285 |
++++ b/drivers/md/dm-cache-target.c |
286 |
+@@ -3391,8 +3391,13 @@ static dm_cblock_t get_cache_dev_size(struct cache *cache) |
287 |
+ |
288 |
+ static bool can_resize(struct cache *cache, dm_cblock_t new_size) |
289 |
+ { |
290 |
+- if (from_cblock(new_size) > from_cblock(cache->cache_size)) |
291 |
+- return true; |
292 |
++ if (from_cblock(new_size) > from_cblock(cache->cache_size)) { |
293 |
++ if (cache->sized) { |
294 |
++ DMERR("%s: unable to extend cache due to missing cache table reload", |
295 |
++ cache_device_name(cache)); |
296 |
++ return false; |
297 |
++ } |
298 |
++ } |
299 |
+ |
300 |
+ /* |
301 |
+ * We can't drop a dirty block when shrinking the cache. |
302 |
+diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h |
303 |
+index 71bdb368813d..0194bebbdbf7 100644 |
304 |
+--- a/drivers/net/wireless/ath/ath10k/trace.h |
305 |
++++ b/drivers/net/wireless/ath/ath10k/trace.h |
306 |
+@@ -152,10 +152,9 @@ TRACE_EVENT(ath10k_log_dbg_dump, |
307 |
+ ); |
308 |
+ |
309 |
+ TRACE_EVENT(ath10k_wmi_cmd, |
310 |
+- TP_PROTO(struct ath10k *ar, int id, const void *buf, size_t buf_len, |
311 |
+- int ret), |
312 |
++ TP_PROTO(struct ath10k *ar, int id, const void *buf, size_t buf_len), |
313 |
+ |
314 |
+- TP_ARGS(ar, id, buf, buf_len, ret), |
315 |
++ TP_ARGS(ar, id, buf, buf_len), |
316 |
+ |
317 |
+ TP_STRUCT__entry( |
318 |
+ __string(device, dev_name(ar->dev)) |
319 |
+@@ -163,7 +162,6 @@ TRACE_EVENT(ath10k_wmi_cmd, |
320 |
+ __field(unsigned int, id) |
321 |
+ __field(size_t, buf_len) |
322 |
+ __dynamic_array(u8, buf, buf_len) |
323 |
+- __field(int, ret) |
324 |
+ ), |
325 |
+ |
326 |
+ TP_fast_assign( |
327 |
+@@ -171,17 +169,15 @@ TRACE_EVENT(ath10k_wmi_cmd, |
328 |
+ __assign_str(driver, dev_driver_string(ar->dev)); |
329 |
+ __entry->id = id; |
330 |
+ __entry->buf_len = buf_len; |
331 |
+- __entry->ret = ret; |
332 |
+ memcpy(__get_dynamic_array(buf), buf, buf_len); |
333 |
+ ), |
334 |
+ |
335 |
+ TP_printk( |
336 |
+- "%s %s id %d len %zu ret %d", |
337 |
++ "%s %s id %d len %zu", |
338 |
+ __get_str(driver), |
339 |
+ __get_str(device), |
340 |
+ __entry->id, |
341 |
+- __entry->buf_len, |
342 |
+- __entry->ret |
343 |
++ __entry->buf_len |
344 |
+ ) |
345 |
+ ); |
346 |
+ |
347 |
+diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c |
348 |
+index c72eb4464de9..c27fff39ddae 100644 |
349 |
+--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c |
350 |
++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c |
351 |
+@@ -1459,10 +1459,10 @@ ath10k_wmi_tlv_op_gen_start_scan(struct ath10k *ar, |
352 |
+ bssid_len = arg->n_bssids * sizeof(struct wmi_mac_addr); |
353 |
+ ie_len = roundup(arg->ie_len, 4); |
354 |
+ len = (sizeof(*tlv) + sizeof(*cmd)) + |
355 |
+- (arg->n_channels ? sizeof(*tlv) + chan_len : 0) + |
356 |
+- (arg->n_ssids ? sizeof(*tlv) + ssid_len : 0) + |
357 |
+- (arg->n_bssids ? sizeof(*tlv) + bssid_len : 0) + |
358 |
+- (arg->ie_len ? sizeof(*tlv) + ie_len : 0); |
359 |
++ sizeof(*tlv) + chan_len + |
360 |
++ sizeof(*tlv) + ssid_len + |
361 |
++ sizeof(*tlv) + bssid_len + |
362 |
++ sizeof(*tlv) + ie_len; |
363 |
+ |
364 |
+ skb = ath10k_wmi_alloc_skb(ar, len); |
365 |
+ if (!skb) |
366 |
+diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c |
367 |
+index 7569db0f69b5..5bb1be478954 100644 |
368 |
+--- a/drivers/net/wireless/ath/ath10k/wmi.c |
369 |
++++ b/drivers/net/wireless/ath/ath10k/wmi.c |
370 |
+@@ -1642,8 +1642,8 @@ int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, |
371 |
+ cmd_hdr->cmd_id = __cpu_to_le32(cmd); |
372 |
+ |
373 |
+ memset(skb_cb, 0, sizeof(*skb_cb)); |
374 |
++ trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len); |
375 |
+ ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); |
376 |
+- trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len, ret); |
377 |
+ |
378 |
+ if (ret) |
379 |
+ goto err_pull; |
380 |
+diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c |
381 |
+index 2a547ca3d443..2eac3df7dd29 100644 |
382 |
+--- a/drivers/of/unittest.c |
383 |
++++ b/drivers/of/unittest.c |
384 |
+@@ -553,6 +553,9 @@ static void __init of_unittest_parse_interrupts(void) |
385 |
+ struct of_phandle_args args; |
386 |
+ int i, rc; |
387 |
+ |
388 |
++ if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) |
389 |
++ return; |
390 |
++ |
391 |
+ np = of_find_node_by_path("/testcase-data/interrupts/interrupts0"); |
392 |
+ if (!np) { |
393 |
+ pr_err("missing testcase data\n"); |
394 |
+@@ -627,6 +630,9 @@ static void __init of_unittest_parse_interrupts_extended(void) |
395 |
+ struct of_phandle_args args; |
396 |
+ int i, rc; |
397 |
+ |
398 |
++ if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) |
399 |
++ return; |
400 |
++ |
401 |
+ np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0"); |
402 |
+ if (!np) { |
403 |
+ pr_err("missing testcase data\n"); |
404 |
+@@ -778,15 +784,19 @@ static void __init of_unittest_platform_populate(void) |
405 |
+ pdev = of_find_device_by_node(np); |
406 |
+ unittest(pdev, "device 1 creation failed\n"); |
407 |
+ |
408 |
+- irq = platform_get_irq(pdev, 0); |
409 |
+- unittest(irq == -EPROBE_DEFER, "device deferred probe failed - %d\n", irq); |
410 |
+- |
411 |
+- /* Test that a parsing failure does not return -EPROBE_DEFER */ |
412 |
+- np = of_find_node_by_path("/testcase-data/testcase-device2"); |
413 |
+- pdev = of_find_device_by_node(np); |
414 |
+- unittest(pdev, "device 2 creation failed\n"); |
415 |
+- irq = platform_get_irq(pdev, 0); |
416 |
+- unittest(irq < 0 && irq != -EPROBE_DEFER, "device parsing error failed - %d\n", irq); |
417 |
++ if (!(of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)) { |
418 |
++ irq = platform_get_irq(pdev, 0); |
419 |
++ unittest(irq == -EPROBE_DEFER, |
420 |
++ "device deferred probe failed - %d\n", irq); |
421 |
++ |
422 |
++ /* Test that a parsing failure does not return -EPROBE_DEFER */ |
423 |
++ np = of_find_node_by_path("/testcase-data/testcase-device2"); |
424 |
++ pdev = of_find_device_by_node(np); |
425 |
++ unittest(pdev, "device 2 creation failed\n"); |
426 |
++ irq = platform_get_irq(pdev, 0); |
427 |
++ unittest(irq < 0 && irq != -EPROBE_DEFER, |
428 |
++ "device parsing error failed - %d\n", irq); |
429 |
++ } |
430 |
+ |
431 |
+ np = of_find_node_by_path("/testcase-data/platform-tests"); |
432 |
+ unittest(np, "No testcase data in device tree\n"); |
433 |
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c |
434 |
+index 295bf1472d02..5073ab023123 100644 |
435 |
+--- a/drivers/pci/pci.c |
436 |
++++ b/drivers/pci/pci.c |
437 |
+@@ -1064,12 +1064,12 @@ int pci_save_state(struct pci_dev *dev) |
438 |
+ EXPORT_SYMBOL(pci_save_state); |
439 |
+ |
440 |
+ static void pci_restore_config_dword(struct pci_dev *pdev, int offset, |
441 |
+- u32 saved_val, int retry) |
442 |
++ u32 saved_val, int retry, bool force) |
443 |
+ { |
444 |
+ u32 val; |
445 |
+ |
446 |
+ pci_read_config_dword(pdev, offset, &val); |
447 |
+- if (val == saved_val) |
448 |
++ if (!force && val == saved_val) |
449 |
+ return; |
450 |
+ |
451 |
+ for (;;) { |
452 |
+@@ -1088,25 +1088,36 @@ static void pci_restore_config_dword(struct pci_dev *pdev, int offset, |
453 |
+ } |
454 |
+ |
455 |
+ static void pci_restore_config_space_range(struct pci_dev *pdev, |
456 |
+- int start, int end, int retry) |
457 |
++ int start, int end, int retry, |
458 |
++ bool force) |
459 |
+ { |
460 |
+ int index; |
461 |
+ |
462 |
+ for (index = end; index >= start; index--) |
463 |
+ pci_restore_config_dword(pdev, 4 * index, |
464 |
+ pdev->saved_config_space[index], |
465 |
+- retry); |
466 |
++ retry, force); |
467 |
+ } |
468 |
+ |
469 |
+ static void pci_restore_config_space(struct pci_dev *pdev) |
470 |
+ { |
471 |
+ if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) { |
472 |
+- pci_restore_config_space_range(pdev, 10, 15, 0); |
473 |
++ pci_restore_config_space_range(pdev, 10, 15, 0, false); |
474 |
+ /* Restore BARs before the command register. */ |
475 |
+- pci_restore_config_space_range(pdev, 4, 9, 10); |
476 |
+- pci_restore_config_space_range(pdev, 0, 3, 0); |
477 |
++ pci_restore_config_space_range(pdev, 4, 9, 10, false); |
478 |
++ pci_restore_config_space_range(pdev, 0, 3, 0, false); |
479 |
++ } else if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { |
480 |
++ pci_restore_config_space_range(pdev, 12, 15, 0, false); |
481 |
++ |
482 |
++ /* |
483 |
++ * Force rewriting of prefetch registers to avoid S3 resume |
484 |
++ * issues on Intel PCI bridges that occur when these |
485 |
++ * registers are not explicitly written. |
486 |
++ */ |
487 |
++ pci_restore_config_space_range(pdev, 9, 11, 0, true); |
488 |
++ pci_restore_config_space_range(pdev, 0, 8, 0, false); |
489 |
+ } else { |
490 |
+- pci_restore_config_space_range(pdev, 0, 15, 0); |
491 |
++ pci_restore_config_space_range(pdev, 0, 15, 0, false); |
492 |
+ } |
493 |
+ } |
494 |
+ |
495 |
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c |
496 |
+index cbf3be66f89c..d6e2199bcfe5 100644 |
497 |
+--- a/drivers/usb/host/xhci-pci.c |
498 |
++++ b/drivers/usb/host/xhci-pci.c |
499 |
+@@ -174,6 +174,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) |
500 |
+ } |
501 |
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL && |
502 |
+ (pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || |
503 |
++ pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || |
504 |
++ pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || |
505 |
+ pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI || |
506 |
+ pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI)) |
507 |
+ xhci->quirks |= XHCI_MISSING_CAS; |
508 |
+diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c |
509 |
+index 2674da40d9cd..6d6acf2c07c3 100644 |
510 |
+--- a/drivers/usb/serial/usb-serial-simple.c |
511 |
++++ b/drivers/usb/serial/usb-serial-simple.c |
512 |
+@@ -87,7 +87,8 @@ DEVICE(moto_modem, MOTO_IDS); |
513 |
+ |
514 |
+ /* Motorola Tetra driver */ |
515 |
+ #define MOTOROLA_TETRA_IDS() \ |
516 |
+- { USB_DEVICE(0x0cad, 0x9011) } /* Motorola Solutions TETRA PEI */ |
517 |
++ { USB_DEVICE(0x0cad, 0x9011) }, /* Motorola Solutions TETRA PEI */ \ |
518 |
++ { USB_DEVICE(0x0cad, 0x9012) } /* MTP6550 */ |
519 |
+ DEVICE(motorola_tetra, MOTOROLA_TETRA_IDS); |
520 |
+ |
521 |
+ /* Novatel Wireless GPS driver */ |
522 |
+diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c |
523 |
+index 9ddfdd63b84c..34ab4f950f0a 100644 |
524 |
+--- a/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c |
525 |
++++ b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c |
526 |
+@@ -496,6 +496,9 @@ static int omapfb_memory_read(struct fb_info *fbi, |
527 |
+ if (!access_ok(VERIFY_WRITE, mr->buffer, mr->buffer_size)) |
528 |
+ return -EFAULT; |
529 |
+ |
530 |
++ if (mr->w > 4096 || mr->h > 4096) |
531 |
++ return -EINVAL; |
532 |
++ |
533 |
+ if (mr->w * mr->h * 3 > mr->buffer_size) |
534 |
+ return -EINVAL; |
535 |
+ |
536 |
+@@ -509,7 +512,7 @@ static int omapfb_memory_read(struct fb_info *fbi, |
537 |
+ mr->x, mr->y, mr->w, mr->h); |
538 |
+ |
539 |
+ if (r > 0) { |
540 |
+- if (copy_to_user(mr->buffer, buf, mr->buffer_size)) |
541 |
++ if (copy_to_user(mr->buffer, buf, r)) |
542 |
+ r = -EFAULT; |
543 |
+ } |
544 |
+ |
545 |
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c |
546 |
+index b51bb73b06a6..d0aaf338fa9f 100644 |
547 |
+--- a/fs/ext4/xattr.c |
548 |
++++ b/fs/ext4/xattr.c |
549 |
+@@ -220,12 +220,12 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh) |
550 |
+ { |
551 |
+ int error; |
552 |
+ |
553 |
+- if (buffer_verified(bh)) |
554 |
+- return 0; |
555 |
+- |
556 |
+ if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || |
557 |
+ BHDR(bh)->h_blocks != cpu_to_le32(1)) |
558 |
+ return -EFSCORRUPTED; |
559 |
++ if (buffer_verified(bh)) |
560 |
++ return 0; |
561 |
++ |
562 |
+ if (!ext4_xattr_block_csum_verify(inode, bh->b_blocknr, BHDR(bh))) |
563 |
+ return -EFSBADCRC; |
564 |
+ error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size, |
565 |
+diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c |
566 |
+index 0bb6de356451..7968b7a5e787 100644 |
567 |
+--- a/fs/ubifs/super.c |
568 |
++++ b/fs/ubifs/super.c |
569 |
+@@ -1918,6 +1918,9 @@ static struct ubi_volume_desc *open_ubi(const char *name, int mode) |
570 |
+ int dev, vol; |
571 |
+ char *endptr; |
572 |
+ |
573 |
++ if (!name || !*name) |
574 |
++ return ERR_PTR(-EINVAL); |
575 |
++ |
576 |
+ /* First, try to open using the device node path method */ |
577 |
+ ubi = ubi_open_volume_path(name, mode); |
578 |
+ if (!IS_ERR(ubi)) |
579 |
+diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h |
580 |
+index 2ea517c7c6b9..bffd096fae3b 100644 |
581 |
+--- a/include/linux/netfilter_bridge/ebtables.h |
582 |
++++ b/include/linux/netfilter_bridge/ebtables.h |
583 |
+@@ -125,4 +125,9 @@ extern unsigned int ebt_do_table(struct sk_buff *skb, |
584 |
+ /* True if the target is not a standard target */ |
585 |
+ #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) |
586 |
+ |
587 |
++static inline bool ebt_invalid_target(int target) |
588 |
++{ |
589 |
++ return (target < -NUM_STANDARD_TARGETS || target >= 0); |
590 |
++} |
591 |
++ |
592 |
+ #endif |
593 |
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h |
594 |
+index c28bd8be290a..a490dd718654 100644 |
595 |
+--- a/include/linux/skbuff.h |
596 |
++++ b/include/linux/skbuff.h |
597 |
+@@ -2273,6 +2273,8 @@ static inline void __skb_queue_purge(struct sk_buff_head *list) |
598 |
+ kfree_skb(skb); |
599 |
+ } |
600 |
+ |
601 |
++void skb_rbtree_purge(struct rb_root *root); |
602 |
++ |
603 |
+ void *netdev_alloc_frag(unsigned int fragsz); |
604 |
+ |
605 |
+ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int length, |
606 |
+@@ -2807,6 +2809,12 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) |
607 |
+ return __pskb_trim(skb, len); |
608 |
+ } |
609 |
+ |
610 |
++#define rb_to_skb(rb) rb_entry_safe(rb, struct sk_buff, rbnode) |
611 |
++#define skb_rb_first(root) rb_to_skb(rb_first(root)) |
612 |
++#define skb_rb_last(root) rb_to_skb(rb_last(root)) |
613 |
++#define skb_rb_next(skb) rb_to_skb(rb_next(&(skb)->rbnode)) |
614 |
++#define skb_rb_prev(skb) rb_to_skb(rb_prev(&(skb)->rbnode)) |
615 |
++ |
616 |
+ #define skb_queue_walk(queue, skb) \ |
617 |
+ for (skb = (queue)->next; \ |
618 |
+ skb != (struct sk_buff *)(queue); \ |
619 |
+diff --git a/include/linux/tcp.h b/include/linux/tcp.h |
620 |
+index 5b6df1a8dc74..747404dbe506 100644 |
621 |
+--- a/include/linux/tcp.h |
622 |
++++ b/include/linux/tcp.h |
623 |
+@@ -279,10 +279,9 @@ struct tcp_sock { |
624 |
+ struct sk_buff* lost_skb_hint; |
625 |
+ struct sk_buff *retransmit_skb_hint; |
626 |
+ |
627 |
+- /* OOO segments go in this list. Note that socket lock must be held, |
628 |
+- * as we do not use sk_buff_head lock. |
629 |
+- */ |
630 |
+- struct sk_buff_head out_of_order_queue; |
631 |
++ /* OOO segments go in this rbtree. Socket lock must be held. */ |
632 |
++ struct rb_root out_of_order_queue; |
633 |
++ struct sk_buff *ooo_last_skb; /* cache rb_last(out_of_order_queue) */ |
634 |
+ |
635 |
+ /* SACKs data, these 2 need to be together (see tcp_options_write) */ |
636 |
+ struct tcp_sack_block duplicate_sack[1]; /* D-SACK block */ |
637 |
+diff --git a/include/net/sock.h b/include/net/sock.h |
638 |
+index 3d5ff7436f41..577075713ad5 100644 |
639 |
+--- a/include/net/sock.h |
640 |
++++ b/include/net/sock.h |
641 |
+@@ -2139,6 +2139,13 @@ sock_skb_set_dropcount(const struct sock *sk, struct sk_buff *skb) |
642 |
+ SOCK_SKB_CB(skb)->dropcount = atomic_read(&sk->sk_drops); |
643 |
+ } |
644 |
+ |
645 |
++static inline void sk_drops_add(struct sock *sk, const struct sk_buff *skb) |
646 |
++{ |
647 |
++ int segs = max_t(u16, 1, skb_shinfo(skb)->gso_segs); |
648 |
++ |
649 |
++ atomic_add(segs, &sk->sk_drops); |
650 |
++} |
651 |
++ |
652 |
+ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, |
653 |
+ struct sk_buff *skb); |
654 |
+ void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, |
655 |
+diff --git a/include/net/tcp.h b/include/net/tcp.h |
656 |
+index 6c89238f192e..a99f75ef6a73 100644 |
657 |
+--- a/include/net/tcp.h |
658 |
++++ b/include/net/tcp.h |
659 |
+@@ -649,7 +649,7 @@ static inline void tcp_fast_path_check(struct sock *sk) |
660 |
+ { |
661 |
+ struct tcp_sock *tp = tcp_sk(sk); |
662 |
+ |
663 |
+- if (skb_queue_empty(&tp->out_of_order_queue) && |
664 |
++ if (RB_EMPTY_ROOT(&tp->out_of_order_queue) && |
665 |
+ tp->rcv_wnd && |
666 |
+ atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf && |
667 |
+ !tp->urg_data) |
668 |
+diff --git a/kernel/cgroup.c b/kernel/cgroup.c |
669 |
+index 4cb94b678e9f..5299618d6308 100644 |
670 |
+--- a/kernel/cgroup.c |
671 |
++++ b/kernel/cgroup.c |
672 |
+@@ -4083,7 +4083,11 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) |
673 |
+ */ |
674 |
+ do { |
675 |
+ css_task_iter_start(&from->self, &it); |
676 |
+- task = css_task_iter_next(&it); |
677 |
++ |
678 |
++ do { |
679 |
++ task = css_task_iter_next(&it); |
680 |
++ } while (task && (task->flags & PF_EXITING)); |
681 |
++ |
682 |
+ if (task) |
683 |
+ get_task_struct(task); |
684 |
+ css_task_iter_end(&it); |
685 |
+diff --git a/mm/vmstat.c b/mm/vmstat.c |
686 |
+index 5712cdaae964..8895eff2d735 100644 |
687 |
+--- a/mm/vmstat.c |
688 |
++++ b/mm/vmstat.c |
689 |
+@@ -858,6 +858,9 @@ const char * const vmstat_text[] = { |
690 |
+ #ifdef CONFIG_SMP |
691 |
+ "nr_tlb_remote_flush", |
692 |
+ "nr_tlb_remote_flush_received", |
693 |
++#else |
694 |
++ "", /* nr_tlb_remote_flush */ |
695 |
++ "", /* nr_tlb_remote_flush_received */ |
696 |
+ #endif /* CONFIG_SMP */ |
697 |
+ "nr_tlb_local_flush_all", |
698 |
+ "nr_tlb_local_flush_one", |
699 |
+diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c |
700 |
+index 070cf134a22f..f2660c1b29e4 100644 |
701 |
+--- a/net/bridge/netfilter/ebt_arpreply.c |
702 |
++++ b/net/bridge/netfilter/ebt_arpreply.c |
703 |
+@@ -67,6 +67,9 @@ static int ebt_arpreply_tg_check(const struct xt_tgchk_param *par) |
704 |
+ if (e->ethproto != htons(ETH_P_ARP) || |
705 |
+ e->invflags & EBT_IPROTO) |
706 |
+ return -EINVAL; |
707 |
++ if (ebt_invalid_target(info->target)) |
708 |
++ return -EINVAL; |
709 |
++ |
710 |
+ return 0; |
711 |
+ } |
712 |
+ |
713 |
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c |
714 |
+index 55be076706e5..9703924ed071 100644 |
715 |
+--- a/net/core/skbuff.c |
716 |
++++ b/net/core/skbuff.c |
717 |
+@@ -2377,6 +2377,25 @@ void skb_queue_purge(struct sk_buff_head *list) |
718 |
+ } |
719 |
+ EXPORT_SYMBOL(skb_queue_purge); |
720 |
+ |
721 |
++/** |
722 |
++ * skb_rbtree_purge - empty a skb rbtree |
723 |
++ * @root: root of the rbtree to empty |
724 |
++ * |
725 |
++ * Delete all buffers on an &sk_buff rbtree. Each buffer is removed from |
726 |
++ * the list and one reference dropped. This function does not take |
727 |
++ * any lock. Synchronization should be handled by the caller (e.g., TCP |
728 |
++ * out-of-order queue is protected by the socket lock). |
729 |
++ */ |
730 |
++void skb_rbtree_purge(struct rb_root *root) |
731 |
++{ |
732 |
++ struct sk_buff *skb, *next; |
733 |
++ |
734 |
++ rbtree_postorder_for_each_entry_safe(skb, next, root, rbnode) |
735 |
++ kfree_skb(skb); |
736 |
++ |
737 |
++ *root = RB_ROOT; |
738 |
++} |
739 |
++ |
740 |
+ /** |
741 |
+ * skb_queue_head - queue a buffer at the list head |
742 |
+ * @list: list to use |
743 |
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c |
744 |
+index 5e162b8ab184..b7492aabe710 100644 |
745 |
+--- a/net/ipv4/tcp.c |
746 |
++++ b/net/ipv4/tcp.c |
747 |
+@@ -382,7 +382,7 @@ void tcp_init_sock(struct sock *sk) |
748 |
+ struct inet_connection_sock *icsk = inet_csk(sk); |
749 |
+ struct tcp_sock *tp = tcp_sk(sk); |
750 |
+ |
751 |
+- __skb_queue_head_init(&tp->out_of_order_queue); |
752 |
++ tp->out_of_order_queue = RB_ROOT; |
753 |
+ tcp_init_xmit_timers(sk); |
754 |
+ tcp_prequeue_init(tp); |
755 |
+ INIT_LIST_HEAD(&tp->tsq_node); |
756 |
+@@ -2240,7 +2240,7 @@ int tcp_disconnect(struct sock *sk, int flags) |
757 |
+ tcp_clear_xmit_timers(sk); |
758 |
+ __skb_queue_purge(&sk->sk_receive_queue); |
759 |
+ tcp_write_queue_purge(sk); |
760 |
+- __skb_queue_purge(&tp->out_of_order_queue); |
761 |
++ skb_rbtree_purge(&tp->out_of_order_queue); |
762 |
+ |
763 |
+ inet->inet_dport = 0; |
764 |
+ |
765 |
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c |
766 |
+index 9c4c6cd0316e..1aff93d76f24 100644 |
767 |
+--- a/net/ipv4/tcp_input.c |
768 |
++++ b/net/ipv4/tcp_input.c |
769 |
+@@ -4073,7 +4073,7 @@ static void tcp_fin(struct sock *sk) |
770 |
+ /* It _is_ possible, that we have something out-of-order _after_ FIN. |
771 |
+ * Probably, we should reset in this case. For now drop them. |
772 |
+ */ |
773 |
+- __skb_queue_purge(&tp->out_of_order_queue); |
774 |
++ skb_rbtree_purge(&tp->out_of_order_queue); |
775 |
+ if (tcp_is_sack(tp)) |
776 |
+ tcp_sack_reset(&tp->rx_opt); |
777 |
+ sk_mem_reclaim(sk); |
778 |
+@@ -4233,7 +4233,7 @@ static void tcp_sack_remove(struct tcp_sock *tp) |
779 |
+ int this_sack; |
780 |
+ |
781 |
+ /* Empty ofo queue, hence, all the SACKs are eaten. Clear. */ |
782 |
+- if (skb_queue_empty(&tp->out_of_order_queue)) { |
783 |
++ if (RB_EMPTY_ROOT(&tp->out_of_order_queue)) { |
784 |
+ tp->rx_opt.num_sacks = 0; |
785 |
+ return; |
786 |
+ } |
787 |
+@@ -4296,6 +4296,29 @@ static bool tcp_try_coalesce(struct sock *sk, |
788 |
+ return true; |
789 |
+ } |
790 |
+ |
791 |
++static bool tcp_ooo_try_coalesce(struct sock *sk, |
792 |
++ struct sk_buff *to, |
793 |
++ struct sk_buff *from, |
794 |
++ bool *fragstolen) |
795 |
++{ |
796 |
++ bool res = tcp_try_coalesce(sk, to, from, fragstolen); |
797 |
++ |
798 |
++ /* In case tcp_drop() is called later, update to->gso_segs */ |
799 |
++ if (res) { |
800 |
++ u32 gso_segs = max_t(u16, 1, skb_shinfo(to)->gso_segs) + |
801 |
++ max_t(u16, 1, skb_shinfo(from)->gso_segs); |
802 |
++ |
803 |
++ skb_shinfo(to)->gso_segs = min_t(u32, gso_segs, 0xFFFF); |
804 |
++ } |
805 |
++ return res; |
806 |
++} |
807 |
++ |
808 |
++static void tcp_drop(struct sock *sk, struct sk_buff *skb) |
809 |
++{ |
810 |
++ sk_drops_add(sk, skb); |
811 |
++ __kfree_skb(skb); |
812 |
++} |
813 |
++ |
814 |
+ /* This one checks to see if we can put data from the |
815 |
+ * out_of_order queue into the receive_queue. |
816 |
+ */ |
817 |
+@@ -4303,10 +4326,13 @@ static void tcp_ofo_queue(struct sock *sk) |
818 |
+ { |
819 |
+ struct tcp_sock *tp = tcp_sk(sk); |
820 |
+ __u32 dsack_high = tp->rcv_nxt; |
821 |
++ bool fin, fragstolen, eaten; |
822 |
+ struct sk_buff *skb, *tail; |
823 |
+- bool fragstolen, eaten; |
824 |
++ struct rb_node *p; |
825 |
+ |
826 |
+- while ((skb = skb_peek(&tp->out_of_order_queue)) != NULL) { |
827 |
++ p = rb_first(&tp->out_of_order_queue); |
828 |
++ while (p) { |
829 |
++ skb = rb_entry(p, struct sk_buff, rbnode); |
830 |
+ if (after(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) |
831 |
+ break; |
832 |
+ |
833 |
+@@ -4316,11 +4342,12 @@ static void tcp_ofo_queue(struct sock *sk) |
834 |
+ dsack_high = TCP_SKB_CB(skb)->end_seq; |
835 |
+ tcp_dsack_extend(sk, TCP_SKB_CB(skb)->seq, dsack); |
836 |
+ } |
837 |
++ p = rb_next(p); |
838 |
++ rb_erase(&skb->rbnode, &tp->out_of_order_queue); |
839 |
+ |
840 |
+- __skb_unlink(skb, &tp->out_of_order_queue); |
841 |
+- if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { |
842 |
++ if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt))) { |
843 |
+ SOCK_DEBUG(sk, "ofo packet was already received\n"); |
844 |
+- __kfree_skb(skb); |
845 |
++ tcp_drop(sk, skb); |
846 |
+ continue; |
847 |
+ } |
848 |
+ SOCK_DEBUG(sk, "ofo requeuing : rcv_next %X seq %X - %X\n", |
849 |
+@@ -4330,12 +4357,19 @@ static void tcp_ofo_queue(struct sock *sk) |
850 |
+ tail = skb_peek_tail(&sk->sk_receive_queue); |
851 |
+ eaten = tail && tcp_try_coalesce(sk, tail, skb, &fragstolen); |
852 |
+ tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); |
853 |
++ fin = TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN; |
854 |
+ if (!eaten) |
855 |
+ __skb_queue_tail(&sk->sk_receive_queue, skb); |
856 |
+- if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) |
857 |
+- tcp_fin(sk); |
858 |
+- if (eaten) |
859 |
++ else |
860 |
+ kfree_skb_partial(skb, fragstolen); |
861 |
++ |
862 |
++ if (unlikely(fin)) { |
863 |
++ tcp_fin(sk); |
864 |
++ /* tcp_fin() purges tp->out_of_order_queue, |
865 |
++ * so we must end this loop right now. |
866 |
++ */ |
867 |
++ break; |
868 |
++ } |
869 |
+ } |
870 |
+ } |
871 |
+ |
872 |
+@@ -4365,14 +4399,16 @@ static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb, |
873 |
+ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) |
874 |
+ { |
875 |
+ struct tcp_sock *tp = tcp_sk(sk); |
876 |
++ struct rb_node **p, *q, *parent; |
877 |
+ struct sk_buff *skb1; |
878 |
+ u32 seq, end_seq; |
879 |
++ bool fragstolen; |
880 |
+ |
881 |
+ tcp_ecn_check_ce(sk, skb); |
882 |
+ |
883 |
+ if (unlikely(tcp_try_rmem_schedule(sk, skb, skb->truesize))) { |
884 |
+ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFODROP); |
885 |
+- __kfree_skb(skb); |
886 |
++ tcp_drop(sk, skb); |
887 |
+ return; |
888 |
+ } |
889 |
+ |
890 |
+@@ -4381,89 +4417,89 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) |
891 |
+ inet_csk_schedule_ack(sk); |
892 |
+ |
893 |
+ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFOQUEUE); |
894 |
++ seq = TCP_SKB_CB(skb)->seq; |
895 |
++ end_seq = TCP_SKB_CB(skb)->end_seq; |
896 |
+ SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n", |
897 |
+- tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); |
898 |
++ tp->rcv_nxt, seq, end_seq); |
899 |
+ |
900 |
+- skb1 = skb_peek_tail(&tp->out_of_order_queue); |
901 |
+- if (!skb1) { |
902 |
++ p = &tp->out_of_order_queue.rb_node; |
903 |
++ if (RB_EMPTY_ROOT(&tp->out_of_order_queue)) { |
904 |
+ /* Initial out of order segment, build 1 SACK. */ |
905 |
+ if (tcp_is_sack(tp)) { |
906 |
+ tp->rx_opt.num_sacks = 1; |
907 |
+- tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq; |
908 |
+- tp->selective_acks[0].end_seq = |
909 |
+- TCP_SKB_CB(skb)->end_seq; |
910 |
+- } |
911 |
+- __skb_queue_head(&tp->out_of_order_queue, skb); |
912 |
+- goto end; |
913 |
+- } |
914 |
+- |
915 |
+- seq = TCP_SKB_CB(skb)->seq; |
916 |
+- end_seq = TCP_SKB_CB(skb)->end_seq; |
917 |
+- |
918 |
+- if (seq == TCP_SKB_CB(skb1)->end_seq) { |
919 |
+- bool fragstolen; |
920 |
+- |
921 |
+- if (!tcp_try_coalesce(sk, skb1, skb, &fragstolen)) { |
922 |
+- __skb_queue_after(&tp->out_of_order_queue, skb1, skb); |
923 |
+- } else { |
924 |
+- tcp_grow_window(sk, skb); |
925 |
+- kfree_skb_partial(skb, fragstolen); |
926 |
+- skb = NULL; |
927 |
++ tp->selective_acks[0].start_seq = seq; |
928 |
++ tp->selective_acks[0].end_seq = end_seq; |
929 |
+ } |
930 |
+- |
931 |
+- if (!tp->rx_opt.num_sacks || |
932 |
+- tp->selective_acks[0].end_seq != seq) |
933 |
+- goto add_sack; |
934 |
+- |
935 |
+- /* Common case: data arrive in order after hole. */ |
936 |
+- tp->selective_acks[0].end_seq = end_seq; |
937 |
++ rb_link_node(&skb->rbnode, NULL, p); |
938 |
++ rb_insert_color(&skb->rbnode, &tp->out_of_order_queue); |
939 |
++ tp->ooo_last_skb = skb; |
940 |
+ goto end; |
941 |
+ } |
942 |
+ |
943 |
+- /* Find place to insert this segment. */ |
944 |
+- while (1) { |
945 |
+- if (!after(TCP_SKB_CB(skb1)->seq, seq)) |
946 |
+- break; |
947 |
+- if (skb_queue_is_first(&tp->out_of_order_queue, skb1)) { |
948 |
+- skb1 = NULL; |
949 |
+- break; |
950 |
++ /* In the typical case, we are adding an skb to the end of the list. |
951 |
++ * Use of ooo_last_skb avoids the O(Log(N)) rbtree lookup. |
952 |
++ */ |
953 |
++ if (tcp_ooo_try_coalesce(sk, tp->ooo_last_skb, |
954 |
++ skb, &fragstolen)) { |
955 |
++coalesce_done: |
956 |
++ tcp_grow_window(sk, skb); |
957 |
++ kfree_skb_partial(skb, fragstolen); |
958 |
++ skb = NULL; |
959 |
++ goto add_sack; |
960 |
++ } |
961 |
++ |
962 |
++ /* Find place to insert this segment. Handle overlaps on the way. */ |
963 |
++ parent = NULL; |
964 |
++ while (*p) { |
965 |
++ parent = *p; |
966 |
++ skb1 = rb_entry(parent, struct sk_buff, rbnode); |
967 |
++ if (before(seq, TCP_SKB_CB(skb1)->seq)) { |
968 |
++ p = &parent->rb_left; |
969 |
++ continue; |
970 |
+ } |
971 |
+- skb1 = skb_queue_prev(&tp->out_of_order_queue, skb1); |
972 |
+- } |
973 |
+ |
974 |
+- /* Do skb overlap to previous one? */ |
975 |
+- if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) { |
976 |
+- if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { |
977 |
+- /* All the bits are present. Drop. */ |
978 |
+- NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFOMERGE); |
979 |
+- __kfree_skb(skb); |
980 |
+- skb = NULL; |
981 |
+- tcp_dsack_set(sk, seq, end_seq); |
982 |
+- goto add_sack; |
983 |
+- } |
984 |
+- if (after(seq, TCP_SKB_CB(skb1)->seq)) { |
985 |
+- /* Partial overlap. */ |
986 |
+- tcp_dsack_set(sk, seq, |
987 |
+- TCP_SKB_CB(skb1)->end_seq); |
988 |
+- } else { |
989 |
+- if (skb_queue_is_first(&tp->out_of_order_queue, |
990 |
+- skb1)) |
991 |
+- skb1 = NULL; |
992 |
+- else |
993 |
+- skb1 = skb_queue_prev( |
994 |
+- &tp->out_of_order_queue, |
995 |
+- skb1); |
996 |
++ if (before(seq, TCP_SKB_CB(skb1)->end_seq)) { |
997 |
++ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { |
998 |
++ /* All the bits are present. Drop. */ |
999 |
++ NET_INC_STATS(sock_net(sk), |
1000 |
++ LINUX_MIB_TCPOFOMERGE); |
1001 |
++ tcp_drop(sk, skb); |
1002 |
++ skb = NULL; |
1003 |
++ tcp_dsack_set(sk, seq, end_seq); |
1004 |
++ goto add_sack; |
1005 |
++ } |
1006 |
++ if (after(seq, TCP_SKB_CB(skb1)->seq)) { |
1007 |
++ /* Partial overlap. */ |
1008 |
++ tcp_dsack_set(sk, seq, TCP_SKB_CB(skb1)->end_seq); |
1009 |
++ } else { |
1010 |
++ /* skb's seq == skb1's seq and skb covers skb1. |
1011 |
++ * Replace skb1 with skb. |
1012 |
++ */ |
1013 |
++ rb_replace_node(&skb1->rbnode, &skb->rbnode, |
1014 |
++ &tp->out_of_order_queue); |
1015 |
++ tcp_dsack_extend(sk, |
1016 |
++ TCP_SKB_CB(skb1)->seq, |
1017 |
++ TCP_SKB_CB(skb1)->end_seq); |
1018 |
++ NET_INC_STATS(sock_net(sk), |
1019 |
++ LINUX_MIB_TCPOFOMERGE); |
1020 |
++ tcp_drop(sk, skb1); |
1021 |
++ goto merge_right; |
1022 |
++ } |
1023 |
++ } else if (tcp_ooo_try_coalesce(sk, skb1, |
1024 |
++ skb, &fragstolen)) { |
1025 |
++ goto coalesce_done; |
1026 |
+ } |
1027 |
++ p = &parent->rb_right; |
1028 |
+ } |
1029 |
+- if (!skb1) |
1030 |
+- __skb_queue_head(&tp->out_of_order_queue, skb); |
1031 |
+- else |
1032 |
+- __skb_queue_after(&tp->out_of_order_queue, skb1, skb); |
1033 |
+ |
1034 |
+- /* And clean segments covered by new one as whole. */ |
1035 |
+- while (!skb_queue_is_last(&tp->out_of_order_queue, skb)) { |
1036 |
+- skb1 = skb_queue_next(&tp->out_of_order_queue, skb); |
1037 |
++ /* Insert segment into RB tree. */ |
1038 |
++ rb_link_node(&skb->rbnode, parent, p); |
1039 |
++ rb_insert_color(&skb->rbnode, &tp->out_of_order_queue); |
1040 |
+ |
1041 |
++merge_right: |
1042 |
++ /* Remove other segments covered by skb. */ |
1043 |
++ while ((q = rb_next(&skb->rbnode)) != NULL) { |
1044 |
++ skb1 = rb_entry(q, struct sk_buff, rbnode); |
1045 |
+ if (!after(end_seq, TCP_SKB_CB(skb1)->seq)) |
1046 |
+ break; |
1047 |
+ if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) { |
1048 |
+@@ -4471,12 +4507,15 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) |
1049 |
+ end_seq); |
1050 |
+ break; |
1051 |
+ } |
1052 |
+- __skb_unlink(skb1, &tp->out_of_order_queue); |
1053 |
++ rb_erase(&skb1->rbnode, &tp->out_of_order_queue); |
1054 |
+ tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, |
1055 |
+ TCP_SKB_CB(skb1)->end_seq); |
1056 |
+ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFOMERGE); |
1057 |
+- __kfree_skb(skb1); |
1058 |
++ tcp_drop(sk, skb1); |
1059 |
+ } |
1060 |
++ /* If there is no skb after us, we are the last_skb ! */ |
1061 |
++ if (!q) |
1062 |
++ tp->ooo_last_skb = skb; |
1063 |
+ |
1064 |
+ add_sack: |
1065 |
+ if (tcp_is_sack(tp)) |
1066 |
+@@ -4558,12 +4597,13 @@ err: |
1067 |
+ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) |
1068 |
+ { |
1069 |
+ struct tcp_sock *tp = tcp_sk(sk); |
1070 |
+- int eaten = -1; |
1071 |
+ bool fragstolen = false; |
1072 |
++ int eaten = -1; |
1073 |
+ |
1074 |
+- if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) |
1075 |
+- goto drop; |
1076 |
+- |
1077 |
++ if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { |
1078 |
++ __kfree_skb(skb); |
1079 |
++ return; |
1080 |
++ } |
1081 |
+ skb_dst_drop(skb); |
1082 |
+ __skb_pull(skb, tcp_hdr(skb)->doff * 4); |
1083 |
+ |
1084 |
+@@ -4614,13 +4654,13 @@ queue_and_out: |
1085 |
+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) |
1086 |
+ tcp_fin(sk); |
1087 |
+ |
1088 |
+- if (!skb_queue_empty(&tp->out_of_order_queue)) { |
1089 |
++ if (!RB_EMPTY_ROOT(&tp->out_of_order_queue)) { |
1090 |
+ tcp_ofo_queue(sk); |
1091 |
+ |
1092 |
+ /* RFC2581. 4.2. SHOULD send immediate ACK, when |
1093 |
+ * gap in queue is filled. |
1094 |
+ */ |
1095 |
+- if (skb_queue_empty(&tp->out_of_order_queue)) |
1096 |
++ if (RB_EMPTY_ROOT(&tp->out_of_order_queue)) |
1097 |
+ inet_csk(sk)->icsk_ack.pingpong = 0; |
1098 |
+ } |
1099 |
+ |
1100 |
+@@ -4645,7 +4685,7 @@ out_of_window: |
1101 |
+ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); |
1102 |
+ inet_csk_schedule_ack(sk); |
1103 |
+ drop: |
1104 |
+- __kfree_skb(skb); |
1105 |
++ tcp_drop(sk, skb); |
1106 |
+ return; |
1107 |
+ } |
1108 |
+ |
1109 |
+@@ -4672,48 +4712,76 @@ drop: |
1110 |
+ tcp_data_queue_ofo(sk, skb); |
1111 |
+ } |
1112 |
+ |
1113 |
++static struct sk_buff *tcp_skb_next(struct sk_buff *skb, struct sk_buff_head *list) |
1114 |
++{ |
1115 |
++ if (list) |
1116 |
++ return !skb_queue_is_last(list, skb) ? skb->next : NULL; |
1117 |
++ |
1118 |
++ return rb_entry_safe(rb_next(&skb->rbnode), struct sk_buff, rbnode); |
1119 |
++} |
1120 |
++ |
1121 |
+ static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, |
1122 |
+- struct sk_buff_head *list) |
1123 |
++ struct sk_buff_head *list, |
1124 |
++ struct rb_root *root) |
1125 |
+ { |
1126 |
+- struct sk_buff *next = NULL; |
1127 |
++ struct sk_buff *next = tcp_skb_next(skb, list); |
1128 |
+ |
1129 |
+- if (!skb_queue_is_last(list, skb)) |
1130 |
+- next = skb_queue_next(list, skb); |
1131 |
++ if (list) |
1132 |
++ __skb_unlink(skb, list); |
1133 |
++ else |
1134 |
++ rb_erase(&skb->rbnode, root); |
1135 |
+ |
1136 |
+- __skb_unlink(skb, list); |
1137 |
+ __kfree_skb(skb); |
1138 |
+ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOLLAPSED); |
1139 |
+ |
1140 |
+ return next; |
1141 |
+ } |
1142 |
+ |
1143 |
++/* Insert skb into rb tree, ordered by TCP_SKB_CB(skb)->seq */ |
1144 |
++static void tcp_rbtree_insert(struct rb_root *root, struct sk_buff *skb) |
1145 |
++{ |
1146 |
++ struct rb_node **p = &root->rb_node; |
1147 |
++ struct rb_node *parent = NULL; |
1148 |
++ struct sk_buff *skb1; |
1149 |
++ |
1150 |
++ while (*p) { |
1151 |
++ parent = *p; |
1152 |
++ skb1 = rb_entry(parent, struct sk_buff, rbnode); |
1153 |
++ if (before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb1)->seq)) |
1154 |
++ p = &parent->rb_left; |
1155 |
++ else |
1156 |
++ p = &parent->rb_right; |
1157 |
++ } |
1158 |
++ rb_link_node(&skb->rbnode, parent, p); |
1159 |
++ rb_insert_color(&skb->rbnode, root); |
1160 |
++} |
1161 |
++ |
1162 |
+ /* Collapse contiguous sequence of skbs head..tail with |
1163 |
+ * sequence numbers start..end. |
1164 |
+ * |
1165 |
+- * If tail is NULL, this means until the end of the list. |
1166 |
++ * If tail is NULL, this means until the end of the queue. |
1167 |
+ * |
1168 |
+ * Segments with FIN/SYN are not collapsed (only because this |
1169 |
+ * simplifies code) |
1170 |
+ */ |
1171 |
+ static void |
1172 |
+-tcp_collapse(struct sock *sk, struct sk_buff_head *list, |
1173 |
+- struct sk_buff *head, struct sk_buff *tail, |
1174 |
+- u32 start, u32 end) |
1175 |
++tcp_collapse(struct sock *sk, struct sk_buff_head *list, struct rb_root *root, |
1176 |
++ struct sk_buff *head, struct sk_buff *tail, u32 start, u32 end) |
1177 |
+ { |
1178 |
+- struct sk_buff *skb, *n; |
1179 |
++ struct sk_buff *skb = head, *n; |
1180 |
++ struct sk_buff_head tmp; |
1181 |
+ bool end_of_skbs; |
1182 |
+ |
1183 |
+ /* First, check that queue is collapsible and find |
1184 |
+- * the point where collapsing can be useful. */ |
1185 |
+- skb = head; |
1186 |
++ * the point where collapsing can be useful. |
1187 |
++ */ |
1188 |
+ restart: |
1189 |
+- end_of_skbs = true; |
1190 |
+- skb_queue_walk_from_safe(list, skb, n) { |
1191 |
+- if (skb == tail) |
1192 |
+- break; |
1193 |
++ for (end_of_skbs = true; skb != NULL && skb != tail; skb = n) { |
1194 |
++ n = tcp_skb_next(skb, list); |
1195 |
++ |
1196 |
+ /* No new bits? It is possible on ofo queue. */ |
1197 |
+ if (!before(start, TCP_SKB_CB(skb)->end_seq)) { |
1198 |
+- skb = tcp_collapse_one(sk, skb, list); |
1199 |
++ skb = tcp_collapse_one(sk, skb, list, root); |
1200 |
+ if (!skb) |
1201 |
+ break; |
1202 |
+ goto restart; |
1203 |
+@@ -4731,13 +4799,10 @@ restart: |
1204 |
+ break; |
1205 |
+ } |
1206 |
+ |
1207 |
+- if (!skb_queue_is_last(list, skb)) { |
1208 |
+- struct sk_buff *next = skb_queue_next(list, skb); |
1209 |
+- if (next != tail && |
1210 |
+- TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(next)->seq) { |
1211 |
+- end_of_skbs = false; |
1212 |
+- break; |
1213 |
+- } |
1214 |
++ if (n && n != tail && |
1215 |
++ TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(n)->seq) { |
1216 |
++ end_of_skbs = false; |
1217 |
++ break; |
1218 |
+ } |
1219 |
+ |
1220 |
+ /* Decided to skip this, advance start seq. */ |
1221 |
+@@ -4747,17 +4812,22 @@ restart: |
1222 |
+ (TCP_SKB_CB(skb)->tcp_flags & (TCPHDR_SYN | TCPHDR_FIN))) |
1223 |
+ return; |
1224 |
+ |
1225 |
++ __skb_queue_head_init(&tmp); |
1226 |
++ |
1227 |
+ while (before(start, end)) { |
1228 |
+ int copy = min_t(int, SKB_MAX_ORDER(0, 0), end - start); |
1229 |
+ struct sk_buff *nskb; |
1230 |
+ |
1231 |
+ nskb = alloc_skb(copy, GFP_ATOMIC); |
1232 |
+ if (!nskb) |
1233 |
+- return; |
1234 |
++ break; |
1235 |
+ |
1236 |
+ memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); |
1237 |
+ TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start; |
1238 |
+- __skb_queue_before(list, skb, nskb); |
1239 |
++ if (list) |
1240 |
++ __skb_queue_before(list, skb, nskb); |
1241 |
++ else |
1242 |
++ __skb_queue_tail(&tmp, nskb); /* defer rbtree insertion */ |
1243 |
+ skb_set_owner_r(nskb, sk); |
1244 |
+ |
1245 |
+ /* Copy data, releasing collapsed skbs. */ |
1246 |
+@@ -4775,14 +4845,17 @@ restart: |
1247 |
+ start += size; |
1248 |
+ } |
1249 |
+ if (!before(start, TCP_SKB_CB(skb)->end_seq)) { |
1250 |
+- skb = tcp_collapse_one(sk, skb, list); |
1251 |
++ skb = tcp_collapse_one(sk, skb, list, root); |
1252 |
+ if (!skb || |
1253 |
+ skb == tail || |
1254 |
+ (TCP_SKB_CB(skb)->tcp_flags & (TCPHDR_SYN | TCPHDR_FIN))) |
1255 |
+- return; |
1256 |
++ goto end; |
1257 |
+ } |
1258 |
+ } |
1259 |
+ } |
1260 |
++end: |
1261 |
++ skb_queue_walk_safe(&tmp, skb, n) |
1262 |
++ tcp_rbtree_insert(root, skb); |
1263 |
+ } |
1264 |
+ |
1265 |
+ /* Collapse ofo queue. Algorithm: select contiguous sequence of skbs |
1266 |
+@@ -4792,34 +4865,39 @@ static void tcp_collapse_ofo_queue(struct sock *sk) |
1267 |
+ { |
1268 |
+ struct tcp_sock *tp = tcp_sk(sk); |
1269 |
+ u32 range_truesize, sum_tiny = 0; |
1270 |
+- struct sk_buff *skb = skb_peek(&tp->out_of_order_queue); |
1271 |
+- struct sk_buff *head; |
1272 |
++ struct sk_buff *skb, *head; |
1273 |
++ struct rb_node *p; |
1274 |
+ u32 start, end; |
1275 |
+ |
1276 |
+- if (!skb) |
1277 |
++ p = rb_first(&tp->out_of_order_queue); |
1278 |
++ skb = rb_entry_safe(p, struct sk_buff, rbnode); |
1279 |
++new_range: |
1280 |
++ if (!skb) { |
1281 |
++ p = rb_last(&tp->out_of_order_queue); |
1282 |
++ /* Note: This is possible p is NULL here. We do not |
1283 |
++ * use rb_entry_safe(), as ooo_last_skb is valid only |
1284 |
++ * if rbtree is not empty. |
1285 |
++ */ |
1286 |
++ tp->ooo_last_skb = rb_entry(p, struct sk_buff, rbnode); |
1287 |
+ return; |
1288 |
+- |
1289 |
++ } |
1290 |
+ start = TCP_SKB_CB(skb)->seq; |
1291 |
+ end = TCP_SKB_CB(skb)->end_seq; |
1292 |
+ range_truesize = skb->truesize; |
1293 |
+- head = skb; |
1294 |
+ |
1295 |
+- for (;;) { |
1296 |
+- struct sk_buff *next = NULL; |
1297 |
++ for (head = skb;;) { |
1298 |
++ skb = tcp_skb_next(skb, NULL); |
1299 |
+ |
1300 |
+- if (!skb_queue_is_last(&tp->out_of_order_queue, skb)) |
1301 |
+- next = skb_queue_next(&tp->out_of_order_queue, skb); |
1302 |
+- skb = next; |
1303 |
+- |
1304 |
+- /* Segment is terminated when we see gap or when |
1305 |
+- * we are at the end of all the queue. */ |
1306 |
++ /* Range is terminated when we see a gap or when |
1307 |
++ * we are at the queue end. |
1308 |
++ */ |
1309 |
+ if (!skb || |
1310 |
+ after(TCP_SKB_CB(skb)->seq, end) || |
1311 |
+ before(TCP_SKB_CB(skb)->end_seq, start)) { |
1312 |
+ /* Do not attempt collapsing tiny skbs */ |
1313 |
+ if (range_truesize != head->truesize || |
1314 |
+ end - start >= SKB_WITH_OVERHEAD(SK_MEM_QUANTUM)) { |
1315 |
+- tcp_collapse(sk, &tp->out_of_order_queue, |
1316 |
++ tcp_collapse(sk, NULL, &tp->out_of_order_queue, |
1317 |
+ head, skb, start, end); |
1318 |
+ } else { |
1319 |
+ sum_tiny += range_truesize; |
1320 |
+@@ -4827,47 +4905,60 @@ static void tcp_collapse_ofo_queue(struct sock *sk) |
1321 |
+ return; |
1322 |
+ } |
1323 |
+ |
1324 |
+- head = skb; |
1325 |
+- if (!skb) |
1326 |
+- break; |
1327 |
+- /* Start new segment */ |
1328 |
++ goto new_range; |
1329 |
++ } |
1330 |
++ |
1331 |
++ range_truesize += skb->truesize; |
1332 |
++ if (unlikely(before(TCP_SKB_CB(skb)->seq, start))) |
1333 |
+ start = TCP_SKB_CB(skb)->seq; |
1334 |
++ if (after(TCP_SKB_CB(skb)->end_seq, end)) |
1335 |
+ end = TCP_SKB_CB(skb)->end_seq; |
1336 |
+- range_truesize = skb->truesize; |
1337 |
+- } else { |
1338 |
+- range_truesize += skb->truesize; |
1339 |
+- if (before(TCP_SKB_CB(skb)->seq, start)) |
1340 |
+- start = TCP_SKB_CB(skb)->seq; |
1341 |
+- if (after(TCP_SKB_CB(skb)->end_seq, end)) |
1342 |
+- end = TCP_SKB_CB(skb)->end_seq; |
1343 |
+- } |
1344 |
+ } |
1345 |
+ } |
1346 |
+ |
1347 |
+ /* |
1348 |
+ * Purge the out-of-order queue. |
1349 |
++ * Drop at least 12.5 % of sk_rcvbuf to avoid malicious attacks. |
1350 |
+ * Return true if queue was pruned. |
1351 |
+ */ |
1352 |
+ static bool tcp_prune_ofo_queue(struct sock *sk) |
1353 |
+ { |
1354 |
+ struct tcp_sock *tp = tcp_sk(sk); |
1355 |
+- bool res = false; |
1356 |
++ struct rb_node *node, *prev; |
1357 |
++ int goal; |
1358 |
+ |
1359 |
+- if (!skb_queue_empty(&tp->out_of_order_queue)) { |
1360 |
+- NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_OFOPRUNED); |
1361 |
+- __skb_queue_purge(&tp->out_of_order_queue); |
1362 |
++ if (RB_EMPTY_ROOT(&tp->out_of_order_queue)) |
1363 |
++ return false; |
1364 |
+ |
1365 |
+- /* Reset SACK state. A conforming SACK implementation will |
1366 |
+- * do the same at a timeout based retransmit. When a connection |
1367 |
+- * is in a sad state like this, we care only about integrity |
1368 |
+- * of the connection not performance. |
1369 |
+- */ |
1370 |
+- if (tp->rx_opt.sack_ok) |
1371 |
+- tcp_sack_reset(&tp->rx_opt); |
1372 |
+- sk_mem_reclaim(sk); |
1373 |
+- res = true; |
1374 |
+- } |
1375 |
+- return res; |
1376 |
++ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_OFOPRUNED); |
1377 |
++ goal = sk->sk_rcvbuf >> 3; |
1378 |
++ node = &tp->ooo_last_skb->rbnode; |
1379 |
++ do { |
1380 |
++ prev = rb_prev(node); |
1381 |
++ rb_erase(node, &tp->out_of_order_queue); |
1382 |
++ goal -= rb_to_skb(node)->truesize; |
1383 |
++ __kfree_skb(rb_to_skb(node)); |
1384 |
++ if (!prev || goal <= 0) { |
1385 |
++ sk_mem_reclaim(sk); |
1386 |
++ if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && |
1387 |
++ !tcp_under_memory_pressure(sk)) |
1388 |
++ break; |
1389 |
++ goal = sk->sk_rcvbuf >> 3; |
1390 |
++ } |
1391 |
++ |
1392 |
++ node = prev; |
1393 |
++ } while (node); |
1394 |
++ tp->ooo_last_skb = rb_entry(prev, struct sk_buff, rbnode); |
1395 |
++ |
1396 |
++ /* Reset SACK state. A conforming SACK implementation will |
1397 |
++ * do the same at a timeout based retransmit. When a connection |
1398 |
++ * is in a sad state like this, we care only about integrity |
1399 |
++ * of the connection not performance. |
1400 |
++ */ |
1401 |
++ if (tp->rx_opt.sack_ok) |
1402 |
++ tcp_sack_reset(&tp->rx_opt); |
1403 |
++ |
1404 |
++ return true; |
1405 |
+ } |
1406 |
+ |
1407 |
+ /* Reduce allocated memory if we can, trying to get |
1408 |
+@@ -4895,7 +4986,7 @@ static int tcp_prune_queue(struct sock *sk) |
1409 |
+ |
1410 |
+ tcp_collapse_ofo_queue(sk); |
1411 |
+ if (!skb_queue_empty(&sk->sk_receive_queue)) |
1412 |
+- tcp_collapse(sk, &sk->sk_receive_queue, |
1413 |
++ tcp_collapse(sk, &sk->sk_receive_queue, NULL, |
1414 |
+ skb_peek(&sk->sk_receive_queue), |
1415 |
+ NULL, |
1416 |
+ tp->copied_seq, tp->rcv_nxt); |
1417 |
+@@ -5000,7 +5091,7 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible) |
1418 |
+ /* We ACK each frame or... */ |
1419 |
+ tcp_in_quickack_mode(sk) || |
1420 |
+ /* We have out of order data. */ |
1421 |
+- (ofo_possible && skb_peek(&tp->out_of_order_queue))) { |
1422 |
++ (ofo_possible && !RB_EMPTY_ROOT(&tp->out_of_order_queue))) { |
1423 |
+ /* Then ack it now */ |
1424 |
+ tcp_send_ack(sk); |
1425 |
+ } else { |
1426 |
+@@ -5236,7 +5327,7 @@ syn_challenge: |
1427 |
+ return true; |
1428 |
+ |
1429 |
+ discard: |
1430 |
+- __kfree_skb(skb); |
1431 |
++ tcp_drop(sk, skb); |
1432 |
+ return false; |
1433 |
+ } |
1434 |
+ |
1435 |
+@@ -5454,7 +5545,7 @@ csum_error: |
1436 |
+ TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); |
1437 |
+ |
1438 |
+ discard: |
1439 |
+- __kfree_skb(skb); |
1440 |
++ tcp_drop(sk, skb); |
1441 |
+ } |
1442 |
+ EXPORT_SYMBOL(tcp_rcv_established); |
1443 |
+ |
1444 |
+@@ -5684,7 +5775,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, |
1445 |
+ TCP_DELACK_MAX, TCP_RTO_MAX); |
1446 |
+ |
1447 |
+ discard: |
1448 |
+- __kfree_skb(skb); |
1449 |
++ tcp_drop(sk, skb); |
1450 |
+ return 0; |
1451 |
+ } else { |
1452 |
+ tcp_send_ack(sk); |
1453 |
+@@ -6041,7 +6132,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) |
1454 |
+ |
1455 |
+ if (!queued) { |
1456 |
+ discard: |
1457 |
+- __kfree_skb(skb); |
1458 |
++ tcp_drop(sk, skb); |
1459 |
+ } |
1460 |
+ return 0; |
1461 |
+ } |
1462 |
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c |
1463 |
+index eeda67c3dd11..ee8399f11fd0 100644 |
1464 |
+--- a/net/ipv4/tcp_ipv4.c |
1465 |
++++ b/net/ipv4/tcp_ipv4.c |
1466 |
+@@ -1716,6 +1716,7 @@ discard_it: |
1467 |
+ return 0; |
1468 |
+ |
1469 |
+ discard_and_relse: |
1470 |
++ sk_drops_add(sk, skb); |
1471 |
+ sock_put(sk); |
1472 |
+ goto discard_it; |
1473 |
+ |
1474 |
+@@ -1829,7 +1830,7 @@ void tcp_v4_destroy_sock(struct sock *sk) |
1475 |
+ tcp_write_queue_purge(sk); |
1476 |
+ |
1477 |
+ /* Cleans up our, hopefully empty, out_of_order_queue. */ |
1478 |
+- __skb_queue_purge(&tp->out_of_order_queue); |
1479 |
++ skb_rbtree_purge(&tp->out_of_order_queue); |
1480 |
+ |
1481 |
+ #ifdef CONFIG_TCP_MD5SIG |
1482 |
+ /* Clean up the MD5 key list, if any */ |
1483 |
+diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c |
1484 |
+index d270870bf492..a48846d81b41 100644 |
1485 |
+--- a/net/ipv4/tcp_minisocks.c |
1486 |
++++ b/net/ipv4/tcp_minisocks.c |
1487 |
+@@ -496,7 +496,6 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, |
1488 |
+ newtp->snd_cwnd_cnt = 0; |
1489 |
+ |
1490 |
+ tcp_init_xmit_timers(newsk); |
1491 |
+- __skb_queue_head_init(&newtp->out_of_order_queue); |
1492 |
+ newtp->write_seq = newtp->pushed_seq = treq->snt_isn + 1; |
1493 |
+ |
1494 |
+ newtp->rx_opt.saw_tstamp = 0; |
1495 |
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c |
1496 |
+index 90abe88e1b40..d6c191158e07 100644 |
1497 |
+--- a/net/ipv6/tcp_ipv6.c |
1498 |
++++ b/net/ipv6/tcp_ipv6.c |
1499 |
+@@ -1505,6 +1505,7 @@ discard_it: |
1500 |
+ return 0; |
1501 |
+ |
1502 |
+ discard_and_relse: |
1503 |
++ sk_drops_add(sk, skb); |
1504 |
+ sock_put(sk); |
1505 |
+ goto discard_it; |
1506 |
+ |
1507 |
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c |
1508 |
+index 1f930032253a..67348d8ac35d 100644 |
1509 |
+--- a/net/mac80211/cfg.c |
1510 |
++++ b/net/mac80211/cfg.c |
1511 |
+@@ -219,7 +219,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, |
1512 |
+ case NL80211_IFTYPE_AP: |
1513 |
+ case NL80211_IFTYPE_AP_VLAN: |
1514 |
+ /* Keys without a station are used for TX only */ |
1515 |
+- if (key->sta && test_sta_flag(key->sta, WLAN_STA_MFP)) |
1516 |
++ if (sta && test_sta_flag(sta, WLAN_STA_MFP)) |
1517 |
+ key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; |
1518 |
+ break; |
1519 |
+ case NL80211_IFTYPE_ADHOC: |