Contents of /trunk/kernel-magellan/patches-4.11/0103-4.11.4-all-fixes.patch
Parent Directory | Revision Log
Revision 2943 -
(show annotations)
(download)
Mon Jun 19 08:31:58 2017 UTC (7 years, 3 months ago) by niro
File size: 168541 byte(s)
Mon Jun 19 08:31:58 2017 UTC (7 years, 3 months ago) by niro
File size: 168541 byte(s)
-linux-4.11.4
1 | diff --git a/Documentation/acpi/acpi-lid.txt b/Documentation/acpi/acpi-lid.txt |
2 | index 22cb3091f297..effe7af3a5af 100644 |
3 | --- a/Documentation/acpi/acpi-lid.txt |
4 | +++ b/Documentation/acpi/acpi-lid.txt |
5 | @@ -59,20 +59,28 @@ button driver uses the following 3 modes in order not to trigger issues. |
6 | If the userspace hasn't been prepared to ignore the unreliable "opened" |
7 | events and the unreliable initial state notification, Linux users can use |
8 | the following kernel parameters to handle the possible issues: |
9 | -A. button.lid_init_state=open: |
10 | +A. button.lid_init_state=method: |
11 | + When this option is specified, the ACPI button driver reports the |
12 | + initial lid state using the returning value of the _LID control method |
13 | + and whether the "opened"/"closed" events are paired fully relies on the |
14 | + firmware implementation. |
15 | + This option can be used to fix some platforms where the returning value |
16 | + of the _LID control method is reliable but the initial lid state |
17 | + notification is missing. |
18 | + This option is the default behavior during the period the userspace |
19 | + isn't ready to handle the buggy AML tables. |
20 | +B. button.lid_init_state=open: |
21 | When this option is specified, the ACPI button driver always reports the |
22 | initial lid state as "opened" and whether the "opened"/"closed" events |
23 | are paired fully relies on the firmware implementation. |
24 | This may fix some platforms where the returning value of the _LID |
25 | control method is not reliable and the initial lid state notification is |
26 | missing. |
27 | - This option is the default behavior during the period the userspace |
28 | - isn't ready to handle the buggy AML tables. |
29 | |
30 | If the userspace has been prepared to ignore the unreliable "opened" events |
31 | and the unreliable initial state notification, Linux users should always |
32 | use the following kernel parameter: |
33 | -B. button.lid_init_state=ignore: |
34 | +C. button.lid_init_state=ignore: |
35 | When this option is specified, the ACPI button driver never reports the |
36 | initial lid state and there is a compensation mechanism implemented to |
37 | ensure that the reliable "closed" notifications can always be delievered |
38 | diff --git a/Makefile b/Makefile |
39 | index 7bab1279d0b5..741814dca844 100644 |
40 | --- a/Makefile |
41 | +++ b/Makefile |
42 | @@ -1,6 +1,6 @@ |
43 | VERSION = 4 |
44 | PATCHLEVEL = 11 |
45 | -SUBLEVEL = 3 |
46 | +SUBLEVEL = 4 |
47 | EXTRAVERSION = |
48 | NAME = Fearless Coyote |
49 | |
50 | diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c |
51 | index ce8ab0409deb..4b0e0eda698b 100644 |
52 | --- a/arch/arm64/net/bpf_jit_comp.c |
53 | +++ b/arch/arm64/net/bpf_jit_comp.c |
54 | @@ -252,8 +252,9 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx) |
55 | */ |
56 | off = offsetof(struct bpf_array, ptrs); |
57 | emit_a64_mov_i64(tmp, off, ctx); |
58 | - emit(A64_LDR64(tmp, r2, tmp), ctx); |
59 | - emit(A64_LDR64(prg, tmp, r3), ctx); |
60 | + emit(A64_ADD(1, tmp, r2, tmp), ctx); |
61 | + emit(A64_LSL(1, prg, r3, 3), ctx); |
62 | + emit(A64_LDR64(prg, tmp, prg), ctx); |
63 | emit(A64_CBZ(1, prg, jmp_offset), ctx); |
64 | |
65 | /* goto *(prog->bpf_func + prologue_size); */ |
66 | diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c |
67 | index f5d399e46193..8d2d98f9ad02 100644 |
68 | --- a/arch/powerpc/kernel/prom.c |
69 | +++ b/arch/powerpc/kernel/prom.c |
70 | @@ -161,7 +161,9 @@ static struct ibm_pa_feature { |
71 | { .pabyte = 0, .pabit = 3, .cpu_features = CPU_FTR_CTRL }, |
72 | { .pabyte = 0, .pabit = 6, .cpu_features = CPU_FTR_NOEXECUTE }, |
73 | { .pabyte = 1, .pabit = 2, .mmu_features = MMU_FTR_CI_LARGE_PAGE }, |
74 | +#ifdef CONFIG_PPC_RADIX_MMU |
75 | { .pabyte = 40, .pabit = 0, .mmu_features = MMU_FTR_TYPE_RADIX }, |
76 | +#endif |
77 | { .pabyte = 1, .pabit = 1, .invert = 1, .cpu_features = CPU_FTR_NODSISRALIGN }, |
78 | { .pabyte = 5, .pabit = 0, .cpu_features = CPU_FTR_REAL_LE, |
79 | .cpu_user_ftrs = PPC_FEATURE_TRUE_LE }, |
80 | diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c |
81 | index 96c2b8a40630..0c45cdbac4cf 100644 |
82 | --- a/arch/powerpc/platforms/cell/spu_base.c |
83 | +++ b/arch/powerpc/platforms/cell/spu_base.c |
84 | @@ -197,7 +197,9 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) |
85 | (REGION_ID(ea) != USER_REGION_ID)) { |
86 | |
87 | spin_unlock(&spu->register_lock); |
88 | - ret = hash_page(ea, _PAGE_PRESENT | _PAGE_READ, 0x300, dsisr); |
89 | + ret = hash_page(ea, |
90 | + _PAGE_PRESENT | _PAGE_READ | _PAGE_PRIVILEGED, |
91 | + 0x300, dsisr); |
92 | spin_lock(&spu->register_lock); |
93 | |
94 | if (!ret) { |
95 | diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h |
96 | index dcbf985ab243..d1f837dc77a4 100644 |
97 | --- a/arch/sparc/include/asm/hugetlb.h |
98 | +++ b/arch/sparc/include/asm/hugetlb.h |
99 | @@ -24,9 +24,11 @@ static inline int is_hugepage_only_range(struct mm_struct *mm, |
100 | static inline int prepare_hugepage_range(struct file *file, |
101 | unsigned long addr, unsigned long len) |
102 | { |
103 | - if (len & ~HPAGE_MASK) |
104 | + struct hstate *h = hstate_file(file); |
105 | + |
106 | + if (len & ~huge_page_mask(h)) |
107 | return -EINVAL; |
108 | - if (addr & ~HPAGE_MASK) |
109 | + if (addr & ~huge_page_mask(h)) |
110 | return -EINVAL; |
111 | return 0; |
112 | } |
113 | diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h |
114 | index ce6f56980aef..cf190728360b 100644 |
115 | --- a/arch/sparc/include/asm/pgtable_32.h |
116 | +++ b/arch/sparc/include/asm/pgtable_32.h |
117 | @@ -91,9 +91,9 @@ extern unsigned long pfn_base; |
118 | * ZERO_PAGE is a global shared page that is always zero: used |
119 | * for zero-mapped memory areas etc.. |
120 | */ |
121 | -extern unsigned long empty_zero_page; |
122 | +extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; |
123 | |
124 | -#define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page)) |
125 | +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) |
126 | |
127 | /* |
128 | * In general all page table modifications should use the V8 atomic |
129 | diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h |
130 | index 478bf6bb4598..3fae200dd251 100644 |
131 | --- a/arch/sparc/include/asm/setup.h |
132 | +++ b/arch/sparc/include/asm/setup.h |
133 | @@ -16,7 +16,7 @@ extern char reboot_command[]; |
134 | */ |
135 | extern unsigned char boot_cpu_id; |
136 | |
137 | -extern unsigned long empty_zero_page; |
138 | +extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; |
139 | |
140 | extern int serial_console; |
141 | static inline int con_is_present(void) |
142 | diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c |
143 | index 6bcff698069b..cec54dc4ab81 100644 |
144 | --- a/arch/sparc/kernel/ftrace.c |
145 | +++ b/arch/sparc/kernel/ftrace.c |
146 | @@ -130,17 +130,16 @@ unsigned long prepare_ftrace_return(unsigned long parent, |
147 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) |
148 | return parent + 8UL; |
149 | |
150 | - if (ftrace_push_return_trace(parent, self_addr, &trace.depth, |
151 | - frame_pointer, NULL) == -EBUSY) |
152 | - return parent + 8UL; |
153 | - |
154 | trace.func = self_addr; |
155 | + trace.depth = current->curr_ret_stack + 1; |
156 | |
157 | /* Only trace if the calling function expects to */ |
158 | - if (!ftrace_graph_entry(&trace)) { |
159 | - current->curr_ret_stack--; |
160 | + if (!ftrace_graph_entry(&trace)) |
161 | + return parent + 8UL; |
162 | + |
163 | + if (ftrace_push_return_trace(parent, self_addr, &trace.depth, |
164 | + frame_pointer, NULL) == -EBUSY) |
165 | return parent + 8UL; |
166 | - } |
167 | |
168 | return return_hooker; |
169 | } |
170 | diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c |
171 | index c6afe98de4d9..3bd0d513bddb 100644 |
172 | --- a/arch/sparc/mm/init_32.c |
173 | +++ b/arch/sparc/mm/init_32.c |
174 | @@ -290,7 +290,7 @@ void __init mem_init(void) |
175 | |
176 | |
177 | /* Saves us work later. */ |
178 | - memset((void *)&empty_zero_page, 0, PAGE_SIZE); |
179 | + memset((void *)empty_zero_page, 0, PAGE_SIZE); |
180 | |
181 | i = last_valid_pfn >> ((20 - PAGE_SHIFT) + 5); |
182 | i += 1; |
183 | diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile |
184 | index 44163e8c3868..2c860ad4fe06 100644 |
185 | --- a/arch/x86/boot/compressed/Makefile |
186 | +++ b/arch/x86/boot/compressed/Makefile |
187 | @@ -94,7 +94,7 @@ vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o |
188 | quiet_cmd_check_data_rel = DATAREL $@ |
189 | define cmd_check_data_rel |
190 | for obj in $(filter %.o,$^); do \ |
191 | - readelf -S $$obj | grep -qF .rel.local && { \ |
192 | + ${CROSS_COMPILE}readelf -S $$obj | grep -qF .rel.local && { \ |
193 | echo "error: $$obj has data relocations!" >&2; \ |
194 | exit 1; \ |
195 | } || true; \ |
196 | diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h |
197 | index e63873683d4a..f1f68c720675 100644 |
198 | --- a/arch/x86/include/asm/mce.h |
199 | +++ b/arch/x86/include/asm/mce.h |
200 | @@ -264,6 +264,7 @@ static inline int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *s |
201 | #endif |
202 | |
203 | int mce_available(struct cpuinfo_x86 *c); |
204 | +bool mce_is_memory_error(struct mce *m); |
205 | |
206 | DECLARE_PER_CPU(unsigned, mce_exception_count); |
207 | DECLARE_PER_CPU(unsigned, mce_poll_count); |
208 | diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c |
209 | index af44ebeb593f..104cda1f9073 100644 |
210 | --- a/arch/x86/kernel/cpu/mcheck/mce.c |
211 | +++ b/arch/x86/kernel/cpu/mcheck/mce.c |
212 | @@ -643,16 +643,14 @@ static void mce_read_aux(struct mce *m, int i) |
213 | } |
214 | } |
215 | |
216 | -static bool memory_error(struct mce *m) |
217 | +bool mce_is_memory_error(struct mce *m) |
218 | { |
219 | - struct cpuinfo_x86 *c = &boot_cpu_data; |
220 | - |
221 | - if (c->x86_vendor == X86_VENDOR_AMD) { |
222 | + if (m->cpuvendor == X86_VENDOR_AMD) { |
223 | /* ErrCodeExt[20:16] */ |
224 | u8 xec = (m->status >> 16) & 0x1f; |
225 | |
226 | return (xec == 0x0 || xec == 0x8); |
227 | - } else if (c->x86_vendor == X86_VENDOR_INTEL) { |
228 | + } else if (m->cpuvendor == X86_VENDOR_INTEL) { |
229 | /* |
230 | * Intel SDM Volume 3B - 15.9.2 Compound Error Codes |
231 | * |
232 | @@ -673,6 +671,7 @@ static bool memory_error(struct mce *m) |
233 | |
234 | return false; |
235 | } |
236 | +EXPORT_SYMBOL_GPL(mce_is_memory_error); |
237 | |
238 | DEFINE_PER_CPU(unsigned, mce_poll_count); |
239 | |
240 | @@ -734,7 +733,7 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b) |
241 | |
242 | severity = mce_severity(&m, mca_cfg.tolerant, NULL, false); |
243 | |
244 | - if (severity == MCE_DEFERRED_SEVERITY && memory_error(&m)) |
245 | + if (severity == MCE_DEFERRED_SEVERITY && mce_is_memory_error(&m)) |
246 | if (m.status & MCI_STATUS_ADDRV) |
247 | m.severity = severity; |
248 | |
249 | diff --git a/crypto/skcipher.c b/crypto/skcipher.c |
250 | index 014af741fc6a..4faa0fd53b0c 100644 |
251 | --- a/crypto/skcipher.c |
252 | +++ b/crypto/skcipher.c |
253 | @@ -764,6 +764,44 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm) |
254 | return 0; |
255 | } |
256 | |
257 | +static int skcipher_setkey_unaligned(struct crypto_skcipher *tfm, |
258 | + const u8 *key, unsigned int keylen) |
259 | +{ |
260 | + unsigned long alignmask = crypto_skcipher_alignmask(tfm); |
261 | + struct skcipher_alg *cipher = crypto_skcipher_alg(tfm); |
262 | + u8 *buffer, *alignbuffer; |
263 | + unsigned long absize; |
264 | + int ret; |
265 | + |
266 | + absize = keylen + alignmask; |
267 | + buffer = kmalloc(absize, GFP_ATOMIC); |
268 | + if (!buffer) |
269 | + return -ENOMEM; |
270 | + |
271 | + alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); |
272 | + memcpy(alignbuffer, key, keylen); |
273 | + ret = cipher->setkey(tfm, alignbuffer, keylen); |
274 | + kzfree(buffer); |
275 | + return ret; |
276 | +} |
277 | + |
278 | +static int skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, |
279 | + unsigned int keylen) |
280 | +{ |
281 | + struct skcipher_alg *cipher = crypto_skcipher_alg(tfm); |
282 | + unsigned long alignmask = crypto_skcipher_alignmask(tfm); |
283 | + |
284 | + if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) { |
285 | + crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); |
286 | + return -EINVAL; |
287 | + } |
288 | + |
289 | + if ((unsigned long)key & alignmask) |
290 | + return skcipher_setkey_unaligned(tfm, key, keylen); |
291 | + |
292 | + return cipher->setkey(tfm, key, keylen); |
293 | +} |
294 | + |
295 | static void crypto_skcipher_exit_tfm(struct crypto_tfm *tfm) |
296 | { |
297 | struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm); |
298 | @@ -784,7 +822,7 @@ static int crypto_skcipher_init_tfm(struct crypto_tfm *tfm) |
299 | tfm->__crt_alg->cra_type == &crypto_givcipher_type) |
300 | return crypto_init_skcipher_ops_ablkcipher(tfm); |
301 | |
302 | - skcipher->setkey = alg->setkey; |
303 | + skcipher->setkey = skcipher_setkey; |
304 | skcipher->encrypt = alg->encrypt; |
305 | skcipher->decrypt = alg->decrypt; |
306 | skcipher->ivsize = alg->ivsize; |
307 | diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c |
308 | index 5a968a78652b..7abe66505739 100644 |
309 | --- a/drivers/acpi/acpica/tbutils.c |
310 | +++ b/drivers/acpi/acpica/tbutils.c |
311 | @@ -418,11 +418,7 @@ acpi_tb_get_table(struct acpi_table_desc *table_desc, |
312 | |
313 | table_desc->validation_count++; |
314 | if (table_desc->validation_count == 0) { |
315 | - ACPI_ERROR((AE_INFO, |
316 | - "Table %p, Validation count is zero after increment\n", |
317 | - table_desc)); |
318 | table_desc->validation_count--; |
319 | - return_ACPI_STATUS(AE_LIMIT); |
320 | } |
321 | |
322 | *out_table = table_desc->pointer; |
323 | diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c |
324 | index 668137e4a069..e19f530f1083 100644 |
325 | --- a/drivers/acpi/button.c |
326 | +++ b/drivers/acpi/button.c |
327 | @@ -57,6 +57,7 @@ |
328 | |
329 | #define ACPI_BUTTON_LID_INIT_IGNORE 0x00 |
330 | #define ACPI_BUTTON_LID_INIT_OPEN 0x01 |
331 | +#define ACPI_BUTTON_LID_INIT_METHOD 0x02 |
332 | |
333 | #define _COMPONENT ACPI_BUTTON_COMPONENT |
334 | ACPI_MODULE_NAME("button"); |
335 | @@ -112,7 +113,7 @@ struct acpi_button { |
336 | |
337 | static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); |
338 | static struct acpi_device *lid_device; |
339 | -static u8 lid_init_state = ACPI_BUTTON_LID_INIT_OPEN; |
340 | +static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; |
341 | |
342 | static unsigned long lid_report_interval __read_mostly = 500; |
343 | module_param(lid_report_interval, ulong, 0644); |
344 | @@ -376,6 +377,9 @@ static void acpi_lid_initialize_state(struct acpi_device *device) |
345 | case ACPI_BUTTON_LID_INIT_OPEN: |
346 | (void)acpi_lid_notify_state(device, 1); |
347 | break; |
348 | + case ACPI_BUTTON_LID_INIT_METHOD: |
349 | + (void)acpi_lid_update_state(device); |
350 | + break; |
351 | case ACPI_BUTTON_LID_INIT_IGNORE: |
352 | default: |
353 | break; |
354 | @@ -559,6 +563,9 @@ static int param_set_lid_init_state(const char *val, struct kernel_param *kp) |
355 | if (!strncmp(val, "open", sizeof("open") - 1)) { |
356 | lid_init_state = ACPI_BUTTON_LID_INIT_OPEN; |
357 | pr_info("Notify initial lid state as open\n"); |
358 | + } else if (!strncmp(val, "method", sizeof("method") - 1)) { |
359 | + lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; |
360 | + pr_info("Notify initial lid state with _LID return value\n"); |
361 | } else if (!strncmp(val, "ignore", sizeof("ignore") - 1)) { |
362 | lid_init_state = ACPI_BUTTON_LID_INIT_IGNORE; |
363 | pr_info("Do not notify initial lid state\n"); |
364 | @@ -572,6 +579,8 @@ static int param_get_lid_init_state(char *buffer, struct kernel_param *kp) |
365 | switch (lid_init_state) { |
366 | case ACPI_BUTTON_LID_INIT_OPEN: |
367 | return sprintf(buffer, "open"); |
368 | + case ACPI_BUTTON_LID_INIT_METHOD: |
369 | + return sprintf(buffer, "method"); |
370 | case ACPI_BUTTON_LID_INIT_IGNORE: |
371 | return sprintf(buffer, "ignore"); |
372 | default: |
373 | diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c |
374 | index 3ba1c3472cf9..fd86bec98dea 100644 |
375 | --- a/drivers/acpi/nfit/mce.c |
376 | +++ b/drivers/acpi/nfit/mce.c |
377 | @@ -26,7 +26,7 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val, |
378 | struct nfit_spa *nfit_spa; |
379 | |
380 | /* We only care about memory errors */ |
381 | - if (!(mce->status & MCACOD)) |
382 | + if (!mce_is_memory_error(mce)) |
383 | return NOTIFY_DONE; |
384 | |
385 | /* |
386 | diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c |
387 | index cf05ae973381..5180fef9eb49 100644 |
388 | --- a/drivers/acpi/sysfs.c |
389 | +++ b/drivers/acpi/sysfs.c |
390 | @@ -333,14 +333,17 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, |
391 | container_of(bin_attr, struct acpi_table_attr, attr); |
392 | struct acpi_table_header *table_header = NULL; |
393 | acpi_status status; |
394 | + ssize_t rc; |
395 | |
396 | status = acpi_get_table(table_attr->name, table_attr->instance, |
397 | &table_header); |
398 | if (ACPI_FAILURE(status)) |
399 | return -ENODEV; |
400 | |
401 | - return memory_read_from_buffer(buf, count, &offset, |
402 | - table_header, table_header->length); |
403 | + rc = memory_read_from_buffer(buf, count, &offset, table_header, |
404 | + table_header->length); |
405 | + acpi_put_table(table_header); |
406 | + return rc; |
407 | } |
408 | |
409 | static int acpi_table_attr_init(struct kobject *tables_obj, |
410 | diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c |
411 | index d4dbd8d8e524..382c864814d9 100644 |
412 | --- a/drivers/char/pcmcia/cm4040_cs.c |
413 | +++ b/drivers/char/pcmcia/cm4040_cs.c |
414 | @@ -374,7 +374,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf, |
415 | |
416 | rc = write_sync_reg(SCR_HOST_TO_READER_START, dev); |
417 | if (rc <= 0) { |
418 | - DEBUGP(5, dev, "write_sync_reg c=%.2Zx\n", rc); |
419 | + DEBUGP(5, dev, "write_sync_reg c=%.2zx\n", rc); |
420 | DEBUGP(2, dev, "<- cm4040_write (failed)\n"); |
421 | if (rc == -ERESTARTSYS) |
422 | return rc; |
423 | @@ -387,7 +387,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf, |
424 | for (i = 0; i < bytes_to_write; i++) { |
425 | rc = wait_for_bulk_out_ready(dev); |
426 | if (rc <= 0) { |
427 | - DEBUGP(5, dev, "wait_for_bulk_out_ready rc=%.2Zx\n", |
428 | + DEBUGP(5, dev, "wait_for_bulk_out_ready rc=%.2zx\n", |
429 | rc); |
430 | DEBUGP(2, dev, "<- cm4040_write (failed)\n"); |
431 | if (rc == -ERESTARTSYS) |
432 | @@ -403,7 +403,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf, |
433 | rc = write_sync_reg(SCR_HOST_TO_READER_DONE, dev); |
434 | |
435 | if (rc <= 0) { |
436 | - DEBUGP(5, dev, "write_sync_reg c=%.2Zx\n", rc); |
437 | + DEBUGP(5, dev, "write_sync_reg c=%.2zx\n", rc); |
438 | DEBUGP(2, dev, "<- cm4040_write (failed)\n"); |
439 | if (rc == -ERESTARTSYS) |
440 | return rc; |
441 | diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c |
442 | index f75ee33ec5bb..98bfa5e41e3b 100644 |
443 | --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c |
444 | +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c |
445 | @@ -2656,6 +2656,28 @@ static int smu7_get_power_state_size(struct pp_hwmgr *hwmgr) |
446 | return sizeof(struct smu7_power_state); |
447 | } |
448 | |
449 | +static int smu7_vblank_too_short(struct pp_hwmgr *hwmgr, |
450 | + uint32_t vblank_time_us) |
451 | +{ |
452 | + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); |
453 | + uint32_t switch_limit_us; |
454 | + |
455 | + switch (hwmgr->chip_id) { |
456 | + case CHIP_POLARIS10: |
457 | + case CHIP_POLARIS11: |
458 | + case CHIP_POLARIS12: |
459 | + switch_limit_us = data->is_memory_gddr5 ? 190 : 150; |
460 | + break; |
461 | + default: |
462 | + switch_limit_us = data->is_memory_gddr5 ? 450 : 150; |
463 | + break; |
464 | + } |
465 | + |
466 | + if (vblank_time_us < switch_limit_us) |
467 | + return true; |
468 | + else |
469 | + return false; |
470 | +} |
471 | |
472 | static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, |
473 | struct pp_power_state *request_ps, |
474 | @@ -2670,6 +2692,7 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, |
475 | bool disable_mclk_switching; |
476 | bool disable_mclk_switching_for_frame_lock; |
477 | struct cgs_display_info info = {0}; |
478 | + struct cgs_mode_info mode_info = {0}; |
479 | const struct phm_clock_and_voltage_limits *max_limits; |
480 | uint32_t i; |
481 | struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); |
482 | @@ -2678,6 +2701,7 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, |
483 | int32_t count; |
484 | int32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0; |
485 | |
486 | + info.mode_info = &mode_info; |
487 | data->battery_state = (PP_StateUILabel_Battery == |
488 | request_ps->classification.ui_label); |
489 | |
490 | @@ -2704,8 +2728,6 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, |
491 | |
492 | cgs_get_active_displays_info(hwmgr->device, &info); |
493 | |
494 | - /*TO DO result = PHM_CheckVBlankTime(hwmgr, &vblankTooShort);*/ |
495 | - |
496 | minimum_clocks.engineClock = hwmgr->display_config.min_core_set_clock; |
497 | minimum_clocks.memoryClock = hwmgr->display_config.min_mem_set_clock; |
498 | |
499 | @@ -2770,8 +2792,10 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, |
500 | PHM_PlatformCaps_DisableMclkSwitchingForFrameLock); |
501 | |
502 | |
503 | - disable_mclk_switching = (1 < info.display_count) || |
504 | - disable_mclk_switching_for_frame_lock; |
505 | + disable_mclk_switching = ((1 < info.display_count) || |
506 | + disable_mclk_switching_for_frame_lock || |
507 | + smu7_vblank_too_short(hwmgr, mode_info.vblank_time_us) || |
508 | + (mode_info.refresh_rate > 120)); |
509 | |
510 | sclk = smu7_ps->performance_levels[0].engine_clock; |
511 | mclk = smu7_ps->performance_levels[0].memory_clock; |
512 | diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c |
513 | index 483fdce74e39..97c444856d09 100644 |
514 | --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c |
515 | +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c |
516 | @@ -760,20 +760,23 @@ void psb_intel_lvds_init(struct drm_device *dev, |
517 | if (scan->type & DRM_MODE_TYPE_PREFERRED) { |
518 | mode_dev->panel_fixed_mode = |
519 | drm_mode_duplicate(dev, scan); |
520 | + DRM_DEBUG_KMS("Using mode from DDC\n"); |
521 | goto out; /* FIXME: check for quirks */ |
522 | } |
523 | } |
524 | |
525 | /* Failed to get EDID, what about VBT? do we need this? */ |
526 | - if (mode_dev->vbt_mode) |
527 | + if (dev_priv->lfp_lvds_vbt_mode) { |
528 | mode_dev->panel_fixed_mode = |
529 | - drm_mode_duplicate(dev, mode_dev->vbt_mode); |
530 | + drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); |
531 | |
532 | - if (!mode_dev->panel_fixed_mode) |
533 | - if (dev_priv->lfp_lvds_vbt_mode) |
534 | - mode_dev->panel_fixed_mode = |
535 | - drm_mode_duplicate(dev, |
536 | - dev_priv->lfp_lvds_vbt_mode); |
537 | + if (mode_dev->panel_fixed_mode) { |
538 | + mode_dev->panel_fixed_mode->type |= |
539 | + DRM_MODE_TYPE_PREFERRED; |
540 | + DRM_DEBUG_KMS("Using mode from VBT\n"); |
541 | + goto out; |
542 | + } |
543 | + } |
544 | |
545 | /* |
546 | * If we didn't get EDID, try checking if the panel is already turned |
547 | @@ -790,6 +793,7 @@ void psb_intel_lvds_init(struct drm_device *dev, |
548 | if (mode_dev->panel_fixed_mode) { |
549 | mode_dev->panel_fixed_mode->type |= |
550 | DRM_MODE_TYPE_PREFERRED; |
551 | + DRM_DEBUG_KMS("Using pre-programmed mode\n"); |
552 | goto out; /* FIXME: check for quirks */ |
553 | } |
554 | } |
555 | diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c |
556 | index 7ba450832e6b..ea36dc4dd5d2 100644 |
557 | --- a/drivers/gpu/drm/radeon/ci_dpm.c |
558 | +++ b/drivers/gpu/drm/radeon/ci_dpm.c |
559 | @@ -776,6 +776,12 @@ bool ci_dpm_vblank_too_short(struct radeon_device *rdev) |
560 | u32 vblank_time = r600_dpm_get_vblank_time(rdev); |
561 | u32 switch_limit = pi->mem_gddr5 ? 450 : 300; |
562 | |
563 | + /* disable mclk switching if the refresh is >120Hz, even if the |
564 | + * blanking period would allow it |
565 | + */ |
566 | + if (r600_dpm_get_vrefresh(rdev) > 120) |
567 | + return true; |
568 | + |
569 | if (vblank_time < switch_limit) |
570 | return true; |
571 | else |
572 | diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c |
573 | index f6ff41a0eed6..edee6a5f4da9 100644 |
574 | --- a/drivers/gpu/drm/radeon/cik.c |
575 | +++ b/drivers/gpu/drm/radeon/cik.c |
576 | @@ -7416,7 +7416,7 @@ static inline void cik_irq_ack(struct radeon_device *rdev) |
577 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
578 | } |
579 | if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) { |
580 | - tmp = RREG32(DC_HPD5_INT_CONTROL); |
581 | + tmp = RREG32(DC_HPD6_INT_CONTROL); |
582 | tmp |= DC_HPDx_INT_ACK; |
583 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
584 | } |
585 | @@ -7446,7 +7446,7 @@ static inline void cik_irq_ack(struct radeon_device *rdev) |
586 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
587 | } |
588 | if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { |
589 | - tmp = RREG32(DC_HPD5_INT_CONTROL); |
590 | + tmp = RREG32(DC_HPD6_INT_CONTROL); |
591 | tmp |= DC_HPDx_RX_INT_ACK; |
592 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
593 | } |
594 | diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c |
595 | index 0b6b5766216f..6068b8a01016 100644 |
596 | --- a/drivers/gpu/drm/radeon/evergreen.c |
597 | +++ b/drivers/gpu/drm/radeon/evergreen.c |
598 | @@ -4933,7 +4933,7 @@ static void evergreen_irq_ack(struct radeon_device *rdev) |
599 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
600 | } |
601 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { |
602 | - tmp = RREG32(DC_HPD5_INT_CONTROL); |
603 | + tmp = RREG32(DC_HPD6_INT_CONTROL); |
604 | tmp |= DC_HPDx_INT_ACK; |
605 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
606 | } |
607 | @@ -4964,7 +4964,7 @@ static void evergreen_irq_ack(struct radeon_device *rdev) |
608 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
609 | } |
610 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { |
611 | - tmp = RREG32(DC_HPD5_INT_CONTROL); |
612 | + tmp = RREG32(DC_HPD6_INT_CONTROL); |
613 | tmp |= DC_HPDx_RX_INT_ACK; |
614 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
615 | } |
616 | diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c |
617 | index a951881c2a50..f2eac6b6c46a 100644 |
618 | --- a/drivers/gpu/drm/radeon/r600.c |
619 | +++ b/drivers/gpu/drm/radeon/r600.c |
620 | @@ -3995,7 +3995,7 @@ static void r600_irq_ack(struct radeon_device *rdev) |
621 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
622 | } |
623 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { |
624 | - tmp = RREG32(DC_HPD5_INT_CONTROL); |
625 | + tmp = RREG32(DC_HPD6_INT_CONTROL); |
626 | tmp |= DC_HPDx_INT_ACK; |
627 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
628 | } |
629 | diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c |
630 | index 414776811e71..c8047548f8be 100644 |
631 | --- a/drivers/gpu/drm/radeon/si.c |
632 | +++ b/drivers/gpu/drm/radeon/si.c |
633 | @@ -6345,7 +6345,7 @@ static inline void si_irq_ack(struct radeon_device *rdev) |
634 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
635 | } |
636 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { |
637 | - tmp = RREG32(DC_HPD5_INT_CONTROL); |
638 | + tmp = RREG32(DC_HPD6_INT_CONTROL); |
639 | tmp |= DC_HPDx_INT_ACK; |
640 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
641 | } |
642 | @@ -6376,7 +6376,7 @@ static inline void si_irq_ack(struct radeon_device *rdev) |
643 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
644 | } |
645 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { |
646 | - tmp = RREG32(DC_HPD5_INT_CONTROL); |
647 | + tmp = RREG32(DC_HPD6_INT_CONTROL); |
648 | tmp |= DC_HPDx_RX_INT_ACK; |
649 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
650 | } |
651 | diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c |
652 | index c68ac65db7ff..4859926332c1 100644 |
653 | --- a/drivers/hid/wacom_wac.c |
654 | +++ b/drivers/hid/wacom_wac.c |
655 | @@ -1571,37 +1571,38 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) |
656 | { |
657 | unsigned char *data = wacom->data; |
658 | |
659 | - if (wacom->pen_input) |
660 | + if (wacom->pen_input) { |
661 | dev_dbg(wacom->pen_input->dev.parent, |
662 | "%s: received report #%d\n", __func__, data[0]); |
663 | - else if (wacom->touch_input) |
664 | + |
665 | + if (len == WACOM_PKGLEN_PENABLED || |
666 | + data[0] == WACOM_REPORT_PENABLED) |
667 | + return wacom_tpc_pen(wacom); |
668 | + } |
669 | + else if (wacom->touch_input) { |
670 | dev_dbg(wacom->touch_input->dev.parent, |
671 | "%s: received report #%d\n", __func__, data[0]); |
672 | |
673 | - switch (len) { |
674 | - case WACOM_PKGLEN_TPC1FG: |
675 | - return wacom_tpc_single_touch(wacom, len); |
676 | + switch (len) { |
677 | + case WACOM_PKGLEN_TPC1FG: |
678 | + return wacom_tpc_single_touch(wacom, len); |
679 | |
680 | - case WACOM_PKGLEN_TPC2FG: |
681 | - return wacom_tpc_mt_touch(wacom); |
682 | + case WACOM_PKGLEN_TPC2FG: |
683 | + return wacom_tpc_mt_touch(wacom); |
684 | |
685 | - case WACOM_PKGLEN_PENABLED: |
686 | - return wacom_tpc_pen(wacom); |
687 | + default: |
688 | + switch (data[0]) { |
689 | + case WACOM_REPORT_TPC1FG: |
690 | + case WACOM_REPORT_TPCHID: |
691 | + case WACOM_REPORT_TPCST: |
692 | + case WACOM_REPORT_TPC1FGE: |
693 | + return wacom_tpc_single_touch(wacom, len); |
694 | |
695 | - default: |
696 | - switch (data[0]) { |
697 | - case WACOM_REPORT_TPC1FG: |
698 | - case WACOM_REPORT_TPCHID: |
699 | - case WACOM_REPORT_TPCST: |
700 | - case WACOM_REPORT_TPC1FGE: |
701 | - return wacom_tpc_single_touch(wacom, len); |
702 | - |
703 | - case WACOM_REPORT_TPCMT: |
704 | - case WACOM_REPORT_TPCMT2: |
705 | - return wacom_mt_touch(wacom); |
706 | + case WACOM_REPORT_TPCMT: |
707 | + case WACOM_REPORT_TPCMT2: |
708 | + return wacom_mt_touch(wacom); |
709 | |
710 | - case WACOM_REPORT_PENABLED: |
711 | - return wacom_tpc_pen(wacom); |
712 | + } |
713 | } |
714 | } |
715 | |
716 | diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c |
717 | index 0ed77eeff31e..a2e3dd715380 100644 |
718 | --- a/drivers/i2c/busses/i2c-tiny-usb.c |
719 | +++ b/drivers/i2c/busses/i2c-tiny-usb.c |
720 | @@ -178,22 +178,39 @@ static int usb_read(struct i2c_adapter *adapter, int cmd, |
721 | int value, int index, void *data, int len) |
722 | { |
723 | struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data; |
724 | + void *dmadata = kmalloc(len, GFP_KERNEL); |
725 | + int ret; |
726 | + |
727 | + if (!dmadata) |
728 | + return -ENOMEM; |
729 | |
730 | /* do control transfer */ |
731 | - return usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0), |
732 | + ret = usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0), |
733 | cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | |
734 | - USB_DIR_IN, value, index, data, len, 2000); |
735 | + USB_DIR_IN, value, index, dmadata, len, 2000); |
736 | + |
737 | + memcpy(data, dmadata, len); |
738 | + kfree(dmadata); |
739 | + return ret; |
740 | } |
741 | |
742 | static int usb_write(struct i2c_adapter *adapter, int cmd, |
743 | int value, int index, void *data, int len) |
744 | { |
745 | struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data; |
746 | + void *dmadata = kmemdup(data, len, GFP_KERNEL); |
747 | + int ret; |
748 | + |
749 | + if (!dmadata) |
750 | + return -ENOMEM; |
751 | |
752 | /* do control transfer */ |
753 | - return usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0), |
754 | + ret = usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0), |
755 | cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
756 | - value, index, data, len, 2000); |
757 | + value, index, dmadata, len, 2000); |
758 | + |
759 | + kfree(dmadata); |
760 | + return ret; |
761 | } |
762 | |
763 | static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev) |
764 | diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c |
765 | index 7382be11afca..aa71b7384640 100644 |
766 | --- a/drivers/infiniband/hw/hfi1/rc.c |
767 | +++ b/drivers/infiniband/hw/hfi1/rc.c |
768 | @@ -2149,8 +2149,11 @@ void hfi1_rc_rcv(struct hfi1_packet *packet) |
769 | ret = hfi1_rvt_get_rwqe(qp, 1); |
770 | if (ret < 0) |
771 | goto nack_op_err; |
772 | - if (!ret) |
773 | + if (!ret) { |
774 | + /* peer will send again */ |
775 | + rvt_put_ss(&qp->r_sge); |
776 | goto rnr_nak; |
777 | + } |
778 | wc.ex.imm_data = ohdr->u.rc.imm_data; |
779 | wc.wc_flags = IB_WC_WITH_IMM; |
780 | goto send_last; |
781 | diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c |
782 | index 12658e3fe154..f7dfccf9a1e1 100644 |
783 | --- a/drivers/infiniband/hw/qib/qib_rc.c |
784 | +++ b/drivers/infiniband/hw/qib/qib_rc.c |
785 | @@ -1947,8 +1947,10 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct ib_header *hdr, |
786 | ret = qib_get_rwqe(qp, 1); |
787 | if (ret < 0) |
788 | goto nack_op_err; |
789 | - if (!ret) |
790 | + if (!ret) { |
791 | + rvt_put_ss(&qp->r_sge); |
792 | goto rnr_nak; |
793 | + } |
794 | wc.ex.imm_data = ohdr->u.rc.imm_data; |
795 | hdrsize += 4; |
796 | wc.wc_flags = IB_WC_WITH_IMM; |
797 | diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c |
798 | index cee46266f434..f6b5e14a7eab 100644 |
799 | --- a/drivers/infiniband/ulp/srp/ib_srp.c |
800 | +++ b/drivers/infiniband/ulp/srp/ib_srp.c |
801 | @@ -570,7 +570,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch) |
802 | return 0; |
803 | |
804 | err_qp: |
805 | - srp_destroy_qp(ch, qp); |
806 | + ib_destroy_qp(qp); |
807 | |
808 | err_send_cq: |
809 | ib_free_cq(send_cq); |
810 | diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c |
811 | index 3275d4995812..61666d269771 100644 |
812 | --- a/drivers/mmc/host/sdhci-iproc.c |
813 | +++ b/drivers/mmc/host/sdhci-iproc.c |
814 | @@ -187,7 +187,8 @@ static const struct sdhci_iproc_data iproc_cygnus_data = { |
815 | }; |
816 | |
817 | static const struct sdhci_pltfm_data sdhci_iproc_pltfm_data = { |
818 | - .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK, |
819 | + .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | |
820 | + SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, |
821 | .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN, |
822 | .ops = &sdhci_iproc_ops, |
823 | }; |
824 | diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c |
825 | index edc70ffad660..6dcc42d79cab 100644 |
826 | --- a/drivers/net/bonding/bond_3ad.c |
827 | +++ b/drivers/net/bonding/bond_3ad.c |
828 | @@ -2573,7 +2573,7 @@ int __bond_3ad_get_active_agg_info(struct bonding *bond, |
829 | return -1; |
830 | |
831 | ad_info->aggregator_id = aggregator->aggregator_identifier; |
832 | - ad_info->ports = aggregator->num_of_ports; |
833 | + ad_info->ports = __agg_active_ports(aggregator); |
834 | ad_info->actor_key = aggregator->actor_oper_aggregator_key; |
835 | ad_info->partner_key = aggregator->partner_oper_aggregator_key; |
836 | ether_addr_copy(ad_info->partner_system, |
837 | diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c |
838 | index 6be3b9aba8ed..ff617beb8502 100644 |
839 | --- a/drivers/net/ethernet/emulex/benet/be_main.c |
840 | +++ b/drivers/net/ethernet/emulex/benet/be_main.c |
841 | @@ -5027,9 +5027,11 @@ static netdev_features_t be_features_check(struct sk_buff *skb, |
842 | struct be_adapter *adapter = netdev_priv(dev); |
843 | u8 l4_hdr = 0; |
844 | |
845 | - /* The code below restricts offload features for some tunneled packets. |
846 | + /* The code below restricts offload features for some tunneled and |
847 | + * Q-in-Q packets. |
848 | * Offload features for normal (non tunnel) packets are unchanged. |
849 | */ |
850 | + features = vlan_features_check(skb, features); |
851 | if (!skb->encapsulation || |
852 | !(adapter->flags & BE_FLAGS_VXLAN_OFFLOADS)) |
853 | return features; |
854 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c |
855 | index a380353a78c2..f95c869c7c29 100644 |
856 | --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c |
857 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c |
858 | @@ -770,7 +770,7 @@ static void cb_timeout_handler(struct work_struct *work) |
859 | mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n", |
860 | mlx5_command_str(msg_to_opcode(ent->in)), |
861 | msg_to_opcode(ent->in)); |
862 | - mlx5_cmd_comp_handler(dev, 1UL << ent->idx); |
863 | + mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); |
864 | } |
865 | |
866 | static void cmd_work_handler(struct work_struct *work) |
867 | @@ -800,6 +800,7 @@ static void cmd_work_handler(struct work_struct *work) |
868 | } |
869 | |
870 | cmd->ent_arr[ent->idx] = ent; |
871 | + set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state); |
872 | lay = get_inst(cmd, ent->idx); |
873 | ent->lay = lay; |
874 | memset(lay, 0, sizeof(*lay)); |
875 | @@ -821,6 +822,20 @@ static void cmd_work_handler(struct work_struct *work) |
876 | if (ent->callback) |
877 | schedule_delayed_work(&ent->cb_timeout_work, cb_timeout); |
878 | |
879 | + /* Skip sending command to fw if internal error */ |
880 | + if (pci_channel_offline(dev->pdev) || |
881 | + dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { |
882 | + u8 status = 0; |
883 | + u32 drv_synd; |
884 | + |
885 | + ent->ret = mlx5_internal_err_ret_value(dev, msg_to_opcode(ent->in), &drv_synd, &status); |
886 | + MLX5_SET(mbox_out, ent->out, status, status); |
887 | + MLX5_SET(mbox_out, ent->out, syndrome, drv_synd); |
888 | + |
889 | + mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); |
890 | + return; |
891 | + } |
892 | + |
893 | /* ring doorbell after the descriptor is valid */ |
894 | mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx); |
895 | wmb(); |
896 | @@ -831,7 +846,7 @@ static void cmd_work_handler(struct work_struct *work) |
897 | poll_timeout(ent); |
898 | /* make sure we read the descriptor after ownership is SW */ |
899 | rmb(); |
900 | - mlx5_cmd_comp_handler(dev, 1UL << ent->idx); |
901 | + mlx5_cmd_comp_handler(dev, 1UL << ent->idx, (ent->ret == -ETIMEDOUT)); |
902 | } |
903 | } |
904 | |
905 | @@ -875,7 +890,7 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent) |
906 | wait_for_completion(&ent->done); |
907 | } else if (!wait_for_completion_timeout(&ent->done, timeout)) { |
908 | ent->ret = -ETIMEDOUT; |
909 | - mlx5_cmd_comp_handler(dev, 1UL << ent->idx); |
910 | + mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); |
911 | } |
912 | |
913 | err = ent->ret; |
914 | @@ -1371,7 +1386,7 @@ static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg) |
915 | } |
916 | } |
917 | |
918 | -void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec) |
919 | +void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced) |
920 | { |
921 | struct mlx5_cmd *cmd = &dev->cmd; |
922 | struct mlx5_cmd_work_ent *ent; |
923 | @@ -1391,6 +1406,19 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec) |
924 | struct semaphore *sem; |
925 | |
926 | ent = cmd->ent_arr[i]; |
927 | + |
928 | + /* if we already completed the command, ignore it */ |
929 | + if (!test_and_clear_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, |
930 | + &ent->state)) { |
931 | + /* only real completion can free the cmd slot */ |
932 | + if (!forced) { |
933 | + mlx5_core_err(dev, "Command completion arrived after timeout (entry idx = %d).\n", |
934 | + ent->idx); |
935 | + free_ent(cmd, ent->idx); |
936 | + } |
937 | + continue; |
938 | + } |
939 | + |
940 | if (ent->callback) |
941 | cancel_delayed_work(&ent->cb_timeout_work); |
942 | if (ent->page_queue) |
943 | @@ -1413,7 +1441,10 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec) |
944 | mlx5_core_dbg(dev, "command completed. ret 0x%x, delivery status %s(0x%x)\n", |
945 | ent->ret, deliv_status_to_str(ent->status), ent->status); |
946 | } |
947 | - free_ent(cmd, ent->idx); |
948 | + |
949 | + /* only real completion will free the entry slot */ |
950 | + if (!forced) |
951 | + free_ent(cmd, ent->idx); |
952 | |
953 | if (ent->callback) { |
954 | ds = ent->ts2 - ent->ts1; |
955 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
956 | index a004a5a1a4c2..949fbadd7817 100644 |
957 | --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
958 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
959 | @@ -773,7 +773,6 @@ static void get_supported(u32 eth_proto_cap, |
960 | ptys2ethtool_supported_port(link_ksettings, eth_proto_cap); |
961 | ptys2ethtool_supported_link(supported, eth_proto_cap); |
962 | ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause); |
963 | - ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Asym_Pause); |
964 | } |
965 | |
966 | static void get_advertising(u32 eth_proto_cap, u8 tx_pause, |
967 | @@ -783,7 +782,7 @@ static void get_advertising(u32 eth_proto_cap, u8 tx_pause, |
968 | unsigned long *advertising = link_ksettings->link_modes.advertising; |
969 | |
970 | ptys2ethtool_adver_link(advertising, eth_proto_cap); |
971 | - if (tx_pause) |
972 | + if (rx_pause) |
973 | ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Pause); |
974 | if (tx_pause ^ rx_pause) |
975 | ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Asym_Pause); |
976 | @@ -828,6 +827,8 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev, |
977 | struct mlx5e_priv *priv = netdev_priv(netdev); |
978 | struct mlx5_core_dev *mdev = priv->mdev; |
979 | u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {0}; |
980 | + u32 rx_pause = 0; |
981 | + u32 tx_pause = 0; |
982 | u32 eth_proto_cap; |
983 | u32 eth_proto_admin; |
984 | u32 eth_proto_lp; |
985 | @@ -850,11 +851,13 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev, |
986 | an_disable_admin = MLX5_GET(ptys_reg, out, an_disable_admin); |
987 | an_status = MLX5_GET(ptys_reg, out, an_status); |
988 | |
989 | + mlx5_query_port_pause(mdev, &rx_pause, &tx_pause); |
990 | + |
991 | ethtool_link_ksettings_zero_link_mode(link_ksettings, supported); |
992 | ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising); |
993 | |
994 | get_supported(eth_proto_cap, link_ksettings); |
995 | - get_advertising(eth_proto_admin, 0, 0, link_ksettings); |
996 | + get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings); |
997 | get_speed_duplex(netdev, eth_proto_oper, link_ksettings); |
998 | |
999 | eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap; |
1000 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c |
1001 | index ea5d8d37a75c..33eae5ad2fb0 100644 |
1002 | --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c |
1003 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c |
1004 | @@ -422,7 +422,7 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr) |
1005 | break; |
1006 | |
1007 | case MLX5_EVENT_TYPE_CMD: |
1008 | - mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector)); |
1009 | + mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector), false); |
1010 | break; |
1011 | |
1012 | case MLX5_EVENT_TYPE_PORT_CHANGE: |
1013 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c |
1014 | index d0515391d33b..44f59b1d6f0f 100644 |
1015 | --- a/drivers/net/ethernet/mellanox/mlx5/core/health.c |
1016 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c |
1017 | @@ -90,7 +90,7 @@ static void trigger_cmd_completions(struct mlx5_core_dev *dev) |
1018 | spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags); |
1019 | |
1020 | mlx5_core_dbg(dev, "vector 0x%llx\n", vector); |
1021 | - mlx5_cmd_comp_handler(dev, vector); |
1022 | + mlx5_cmd_comp_handler(dev, vector, true); |
1023 | return; |
1024 | |
1025 | no_trig: |
1026 | diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c |
1027 | index dec5d563ab19..959fd12d2e67 100644 |
1028 | --- a/drivers/net/geneve.c |
1029 | +++ b/drivers/net/geneve.c |
1030 | @@ -1293,7 +1293,7 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev) |
1031 | if (nla_put_u32(skb, IFLA_GENEVE_ID, vni)) |
1032 | goto nla_put_failure; |
1033 | |
1034 | - if (ip_tunnel_info_af(info) == AF_INET) { |
1035 | + if (rtnl_dereference(geneve->sock4)) { |
1036 | if (nla_put_in_addr(skb, IFLA_GENEVE_REMOTE, |
1037 | info->key.u.ipv4.dst)) |
1038 | goto nla_put_failure; |
1039 | @@ -1302,8 +1302,10 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev) |
1040 | !!(info->key.tun_flags & TUNNEL_CSUM))) |
1041 | goto nla_put_failure; |
1042 | |
1043 | + } |
1044 | + |
1045 | #if IS_ENABLED(CONFIG_IPV6) |
1046 | - } else { |
1047 | + if (rtnl_dereference(geneve->sock6)) { |
1048 | if (nla_put_in6_addr(skb, IFLA_GENEVE_REMOTE6, |
1049 | &info->key.u.ipv6.dst)) |
1050 | goto nla_put_failure; |
1051 | @@ -1315,8 +1317,8 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev) |
1052 | if (nla_put_u8(skb, IFLA_GENEVE_UDP_ZERO_CSUM6_RX, |
1053 | !geneve->use_udp6_rx_checksums)) |
1054 | goto nla_put_failure; |
1055 | -#endif |
1056 | } |
1057 | +#endif |
1058 | |
1059 | if (nla_put_u8(skb, IFLA_GENEVE_TTL, info->key.ttl) || |
1060 | nla_put_u8(skb, IFLA_GENEVE_TOS, info->key.tos) || |
1061 | diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c |
1062 | index 272b051a0199..9097e42bec2e 100644 |
1063 | --- a/drivers/net/phy/marvell.c |
1064 | +++ b/drivers/net/phy/marvell.c |
1065 | @@ -255,34 +255,6 @@ static int marvell_config_aneg(struct phy_device *phydev) |
1066 | { |
1067 | int err; |
1068 | |
1069 | - /* The Marvell PHY has an errata which requires |
1070 | - * that certain registers get written in order |
1071 | - * to restart autonegotiation */ |
1072 | - err = phy_write(phydev, MII_BMCR, BMCR_RESET); |
1073 | - |
1074 | - if (err < 0) |
1075 | - return err; |
1076 | - |
1077 | - err = phy_write(phydev, 0x1d, 0x1f); |
1078 | - if (err < 0) |
1079 | - return err; |
1080 | - |
1081 | - err = phy_write(phydev, 0x1e, 0x200c); |
1082 | - if (err < 0) |
1083 | - return err; |
1084 | - |
1085 | - err = phy_write(phydev, 0x1d, 0x5); |
1086 | - if (err < 0) |
1087 | - return err; |
1088 | - |
1089 | - err = phy_write(phydev, 0x1e, 0); |
1090 | - if (err < 0) |
1091 | - return err; |
1092 | - |
1093 | - err = phy_write(phydev, 0x1e, 0x100); |
1094 | - if (err < 0) |
1095 | - return err; |
1096 | - |
1097 | err = marvell_set_polarity(phydev, phydev->mdix_ctrl); |
1098 | if (err < 0) |
1099 | return err; |
1100 | @@ -316,6 +288,42 @@ static int marvell_config_aneg(struct phy_device *phydev) |
1101 | return 0; |
1102 | } |
1103 | |
1104 | +static int m88e1101_config_aneg(struct phy_device *phydev) |
1105 | +{ |
1106 | + int err; |
1107 | + |
1108 | + /* This Marvell PHY has an errata which requires |
1109 | + * that certain registers get written in order |
1110 | + * to restart autonegotiation |
1111 | + */ |
1112 | + err = phy_write(phydev, MII_BMCR, BMCR_RESET); |
1113 | + |
1114 | + if (err < 0) |
1115 | + return err; |
1116 | + |
1117 | + err = phy_write(phydev, 0x1d, 0x1f); |
1118 | + if (err < 0) |
1119 | + return err; |
1120 | + |
1121 | + err = phy_write(phydev, 0x1e, 0x200c); |
1122 | + if (err < 0) |
1123 | + return err; |
1124 | + |
1125 | + err = phy_write(phydev, 0x1d, 0x5); |
1126 | + if (err < 0) |
1127 | + return err; |
1128 | + |
1129 | + err = phy_write(phydev, 0x1e, 0); |
1130 | + if (err < 0) |
1131 | + return err; |
1132 | + |
1133 | + err = phy_write(phydev, 0x1e, 0x100); |
1134 | + if (err < 0) |
1135 | + return err; |
1136 | + |
1137 | + return marvell_config_aneg(phydev); |
1138 | +} |
1139 | + |
1140 | static int m88e1111_config_aneg(struct phy_device *phydev) |
1141 | { |
1142 | int err; |
1143 | @@ -1892,7 +1900,7 @@ static struct phy_driver marvell_drivers[] = { |
1144 | .flags = PHY_HAS_INTERRUPT, |
1145 | .probe = marvell_probe, |
1146 | .config_init = &marvell_config_init, |
1147 | - .config_aneg = &marvell_config_aneg, |
1148 | + .config_aneg = &m88e1101_config_aneg, |
1149 | .read_status = &genphy_read_status, |
1150 | .ack_interrupt = &marvell_ack_interrupt, |
1151 | .config_intr = &marvell_config_intr, |
1152 | diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c |
1153 | index 4e34568db64f..87746c2bc3d3 100644 |
1154 | --- a/drivers/net/usb/qmi_wwan.c |
1155 | +++ b/drivers/net/usb/qmi_wwan.c |
1156 | @@ -902,6 +902,8 @@ static const struct usb_device_id products[] = { |
1157 | {QMI_FIXED_INTF(0x1199, 0x9071, 10)}, /* Sierra Wireless MC74xx */ |
1158 | {QMI_FIXED_INTF(0x1199, 0x9079, 8)}, /* Sierra Wireless EM74xx */ |
1159 | {QMI_FIXED_INTF(0x1199, 0x9079, 10)}, /* Sierra Wireless EM74xx */ |
1160 | + {QMI_FIXED_INTF(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */ |
1161 | + {QMI_FIXED_INTF(0x1199, 0x907b, 10)}, /* Sierra Wireless EM74xx */ |
1162 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
1163 | {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ |
1164 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
1165 | diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c |
1166 | index f36584616e7d..d9d8f4f43f90 100644 |
1167 | --- a/drivers/net/virtio_net.c |
1168 | +++ b/drivers/net/virtio_net.c |
1169 | @@ -1894,6 +1894,7 @@ static const struct net_device_ops virtnet_netdev = { |
1170 | .ndo_poll_controller = virtnet_netpoll, |
1171 | #endif |
1172 | .ndo_xdp = virtnet_xdp, |
1173 | + .ndo_features_check = passthru_features_check, |
1174 | }; |
1175 | |
1176 | static void virtnet_config_changed_work(struct work_struct *work) |
1177 | diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c |
1178 | index 7d909c8183e9..df74efcf237b 100644 |
1179 | --- a/drivers/net/vrf.c |
1180 | +++ b/drivers/net/vrf.c |
1181 | @@ -851,6 +851,7 @@ static u32 vrf_fib_table(const struct net_device *dev) |
1182 | |
1183 | static int vrf_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) |
1184 | { |
1185 | + kfree_skb(skb); |
1186 | return 0; |
1187 | } |
1188 | |
1189 | @@ -860,7 +861,7 @@ static struct sk_buff *vrf_rcv_nfhook(u8 pf, unsigned int hook, |
1190 | { |
1191 | struct net *net = dev_net(dev); |
1192 | |
1193 | - if (NF_HOOK(pf, hook, net, NULL, skb, dev, NULL, vrf_rcv_finish) < 0) |
1194 | + if (nf_hook(pf, hook, net, NULL, skb, dev, NULL, vrf_rcv_finish) != 1) |
1195 | skb = NULL; /* kfree_skb(skb) handled by nf code */ |
1196 | |
1197 | return skb; |
1198 | diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c |
1199 | index eeb409c287b8..b3d3c5c2c92f 100644 |
1200 | --- a/drivers/nvme/host/core.c |
1201 | +++ b/drivers/nvme/host/core.c |
1202 | @@ -2006,7 +2006,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) |
1203 | if (ns->ndev) |
1204 | nvme_nvm_unregister_sysfs(ns); |
1205 | del_gendisk(ns->disk); |
1206 | - blk_mq_abort_requeue_list(ns->queue); |
1207 | blk_cleanup_queue(ns->queue); |
1208 | } |
1209 | |
1210 | @@ -2344,8 +2343,16 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl) |
1211 | continue; |
1212 | revalidate_disk(ns->disk); |
1213 | blk_set_queue_dying(ns->queue); |
1214 | - blk_mq_abort_requeue_list(ns->queue); |
1215 | - blk_mq_start_stopped_hw_queues(ns->queue, true); |
1216 | + |
1217 | + /* |
1218 | + * Forcibly start all queues to avoid having stuck requests. |
1219 | + * Note that we must ensure the queues are not stopped |
1220 | + * when the final removal happens. |
1221 | + */ |
1222 | + blk_mq_start_hw_queues(ns->queue); |
1223 | + |
1224 | + /* draining requests in requeue list */ |
1225 | + blk_mq_kick_requeue_list(ns->queue); |
1226 | } |
1227 | mutex_unlock(&ctrl->namespaces_mutex); |
1228 | } |
1229 | diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c |
1230 | index 16f84eb0b95e..0aba367ae465 100644 |
1231 | --- a/drivers/nvme/host/rdma.c |
1232 | +++ b/drivers/nvme/host/rdma.c |
1233 | @@ -1029,6 +1029,19 @@ static void nvme_rdma_send_done(struct ib_cq *cq, struct ib_wc *wc) |
1234 | nvme_rdma_wr_error(cq, wc, "SEND"); |
1235 | } |
1236 | |
1237 | +static inline int nvme_rdma_queue_sig_limit(struct nvme_rdma_queue *queue) |
1238 | +{ |
1239 | + int sig_limit; |
1240 | + |
1241 | + /* |
1242 | + * We signal completion every queue depth/2 and also handle the |
1243 | + * degenerated case of a device with queue_depth=1, where we |
1244 | + * would need to signal every message. |
1245 | + */ |
1246 | + sig_limit = max(queue->queue_size / 2, 1); |
1247 | + return (++queue->sig_count % sig_limit) == 0; |
1248 | +} |
1249 | + |
1250 | static int nvme_rdma_post_send(struct nvme_rdma_queue *queue, |
1251 | struct nvme_rdma_qe *qe, struct ib_sge *sge, u32 num_sge, |
1252 | struct ib_send_wr *first, bool flush) |
1253 | @@ -1056,9 +1069,6 @@ static int nvme_rdma_post_send(struct nvme_rdma_queue *queue, |
1254 | * Would have been way to obvious to handle this in hardware or |
1255 | * at least the RDMA stack.. |
1256 | * |
1257 | - * This messy and racy code sniplet is copy and pasted from the iSER |
1258 | - * initiator, and the magic '32' comes from there as well. |
1259 | - * |
1260 | * Always signal the flushes. The magic request used for the flush |
1261 | * sequencer is not allocated in our driver's tagset and it's |
1262 | * triggered to be freed by blk_cleanup_queue(). So we need to |
1263 | @@ -1066,7 +1076,7 @@ static int nvme_rdma_post_send(struct nvme_rdma_queue *queue, |
1264 | * embedded in request's payload, is not freed when __ib_process_cq() |
1265 | * calls wr_cqe->done(). |
1266 | */ |
1267 | - if ((++queue->sig_count % 32) == 0 || flush) |
1268 | + if (nvme_rdma_queue_sig_limit(queue) || flush) |
1269 | wr.send_flags |= IB_SEND_SIGNALED; |
1270 | |
1271 | if (first) |
1272 | diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h |
1273 | index d9561e39c3b2..a26b7e8c0d10 100644 |
1274 | --- a/drivers/s390/net/qeth_core.h |
1275 | +++ b/drivers/s390/net/qeth_core.h |
1276 | @@ -714,6 +714,7 @@ enum qeth_discipline_id { |
1277 | }; |
1278 | |
1279 | struct qeth_discipline { |
1280 | + const struct device_type *devtype; |
1281 | void (*start_poll)(struct ccw_device *, int, unsigned long); |
1282 | qdio_handler_t *input_handler; |
1283 | qdio_handler_t *output_handler; |
1284 | @@ -889,6 +890,9 @@ extern struct qeth_discipline qeth_l2_discipline; |
1285 | extern struct qeth_discipline qeth_l3_discipline; |
1286 | extern const struct attribute_group *qeth_generic_attr_groups[]; |
1287 | extern const struct attribute_group *qeth_osn_attr_groups[]; |
1288 | +extern const struct attribute_group qeth_device_attr_group; |
1289 | +extern const struct attribute_group qeth_device_blkt_group; |
1290 | +extern const struct device_type qeth_generic_devtype; |
1291 | extern struct workqueue_struct *qeth_wq; |
1292 | |
1293 | int qeth_card_hw_is_reachable(struct qeth_card *); |
1294 | diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c |
1295 | index 9a5f99ccb122..3a8ff756a025 100644 |
1296 | --- a/drivers/s390/net/qeth_core_main.c |
1297 | +++ b/drivers/s390/net/qeth_core_main.c |
1298 | @@ -5460,10 +5460,12 @@ void qeth_core_free_discipline(struct qeth_card *card) |
1299 | card->discipline = NULL; |
1300 | } |
1301 | |
1302 | -static const struct device_type qeth_generic_devtype = { |
1303 | +const struct device_type qeth_generic_devtype = { |
1304 | .name = "qeth_generic", |
1305 | .groups = qeth_generic_attr_groups, |
1306 | }; |
1307 | +EXPORT_SYMBOL_GPL(qeth_generic_devtype); |
1308 | + |
1309 | static const struct device_type qeth_osn_devtype = { |
1310 | .name = "qeth_osn", |
1311 | .groups = qeth_osn_attr_groups, |
1312 | @@ -5589,23 +5591,22 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) |
1313 | goto err_card; |
1314 | } |
1315 | |
1316 | - if (card->info.type == QETH_CARD_TYPE_OSN) |
1317 | - gdev->dev.type = &qeth_osn_devtype; |
1318 | - else |
1319 | - gdev->dev.type = &qeth_generic_devtype; |
1320 | - |
1321 | switch (card->info.type) { |
1322 | case QETH_CARD_TYPE_OSN: |
1323 | case QETH_CARD_TYPE_OSM: |
1324 | rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); |
1325 | if (rc) |
1326 | goto err_card; |
1327 | + |
1328 | + gdev->dev.type = (card->info.type != QETH_CARD_TYPE_OSN) |
1329 | + ? card->discipline->devtype |
1330 | + : &qeth_osn_devtype; |
1331 | rc = card->discipline->setup(card->gdev); |
1332 | if (rc) |
1333 | goto err_disc; |
1334 | - case QETH_CARD_TYPE_OSD: |
1335 | - case QETH_CARD_TYPE_OSX: |
1336 | + break; |
1337 | default: |
1338 | + gdev->dev.type = &qeth_generic_devtype; |
1339 | break; |
1340 | } |
1341 | |
1342 | @@ -5661,8 +5662,10 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) |
1343 | if (rc) |
1344 | goto err; |
1345 | rc = card->discipline->setup(card->gdev); |
1346 | - if (rc) |
1347 | + if (rc) { |
1348 | + qeth_core_free_discipline(card); |
1349 | goto err; |
1350 | + } |
1351 | } |
1352 | rc = card->discipline->set_online(gdev); |
1353 | err: |
1354 | diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c |
1355 | index 75b29fd2fcf4..db6a285d41e0 100644 |
1356 | --- a/drivers/s390/net/qeth_core_sys.c |
1357 | +++ b/drivers/s390/net/qeth_core_sys.c |
1358 | @@ -413,12 +413,16 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, |
1359 | |
1360 | if (card->options.layer2 == newdis) |
1361 | goto out; |
1362 | - else { |
1363 | - card->info.mac_bits = 0; |
1364 | - if (card->discipline) { |
1365 | - card->discipline->remove(card->gdev); |
1366 | - qeth_core_free_discipline(card); |
1367 | - } |
1368 | + if (card->info.type == QETH_CARD_TYPE_OSM) { |
1369 | + /* fixed layer, can't switch */ |
1370 | + rc = -EOPNOTSUPP; |
1371 | + goto out; |
1372 | + } |
1373 | + |
1374 | + card->info.mac_bits = 0; |
1375 | + if (card->discipline) { |
1376 | + card->discipline->remove(card->gdev); |
1377 | + qeth_core_free_discipline(card); |
1378 | } |
1379 | |
1380 | rc = qeth_core_load_discipline(card, newdis); |
1381 | @@ -426,6 +430,8 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, |
1382 | goto out; |
1383 | |
1384 | rc = card->discipline->setup(card->gdev); |
1385 | + if (rc) |
1386 | + qeth_core_free_discipline(card); |
1387 | out: |
1388 | mutex_unlock(&card->discipline_mutex); |
1389 | return rc ? rc : count; |
1390 | @@ -703,10 +709,11 @@ static struct attribute *qeth_blkt_device_attrs[] = { |
1391 | &dev_attr_inter_jumbo.attr, |
1392 | NULL, |
1393 | }; |
1394 | -static struct attribute_group qeth_device_blkt_group = { |
1395 | +const struct attribute_group qeth_device_blkt_group = { |
1396 | .name = "blkt", |
1397 | .attrs = qeth_blkt_device_attrs, |
1398 | }; |
1399 | +EXPORT_SYMBOL_GPL(qeth_device_blkt_group); |
1400 | |
1401 | static struct attribute *qeth_device_attrs[] = { |
1402 | &dev_attr_state.attr, |
1403 | @@ -726,9 +733,10 @@ static struct attribute *qeth_device_attrs[] = { |
1404 | &dev_attr_switch_attrs.attr, |
1405 | NULL, |
1406 | }; |
1407 | -static struct attribute_group qeth_device_attr_group = { |
1408 | +const struct attribute_group qeth_device_attr_group = { |
1409 | .attrs = qeth_device_attrs, |
1410 | }; |
1411 | +EXPORT_SYMBOL_GPL(qeth_device_attr_group); |
1412 | |
1413 | const struct attribute_group *qeth_generic_attr_groups[] = { |
1414 | &qeth_device_attr_group, |
1415 | diff --git a/drivers/s390/net/qeth_l2.h b/drivers/s390/net/qeth_l2.h |
1416 | index 29d9fb3890ad..0d59f9a45ea9 100644 |
1417 | --- a/drivers/s390/net/qeth_l2.h |
1418 | +++ b/drivers/s390/net/qeth_l2.h |
1419 | @@ -8,6 +8,8 @@ |
1420 | |
1421 | #include "qeth_core.h" |
1422 | |
1423 | +extern const struct attribute_group *qeth_l2_attr_groups[]; |
1424 | + |
1425 | int qeth_l2_create_device_attributes(struct device *); |
1426 | void qeth_l2_remove_device_attributes(struct device *); |
1427 | void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card); |
1428 | diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c |
1429 | index af4e6a639fec..a2bb77d7e5bb 100644 |
1430 | --- a/drivers/s390/net/qeth_l2_main.c |
1431 | +++ b/drivers/s390/net/qeth_l2_main.c |
1432 | @@ -1006,11 +1006,21 @@ static int qeth_l2_stop(struct net_device *dev) |
1433 | return 0; |
1434 | } |
1435 | |
1436 | +static const struct device_type qeth_l2_devtype = { |
1437 | + .name = "qeth_layer2", |
1438 | + .groups = qeth_l2_attr_groups, |
1439 | +}; |
1440 | + |
1441 | static int qeth_l2_probe_device(struct ccwgroup_device *gdev) |
1442 | { |
1443 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
1444 | + int rc; |
1445 | |
1446 | - qeth_l2_create_device_attributes(&gdev->dev); |
1447 | + if (gdev->dev.type == &qeth_generic_devtype) { |
1448 | + rc = qeth_l2_create_device_attributes(&gdev->dev); |
1449 | + if (rc) |
1450 | + return rc; |
1451 | + } |
1452 | INIT_LIST_HEAD(&card->vid_list); |
1453 | hash_init(card->mac_htable); |
1454 | card->options.layer2 = 1; |
1455 | @@ -1022,7 +1032,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) |
1456 | { |
1457 | struct qeth_card *card = dev_get_drvdata(&cgdev->dev); |
1458 | |
1459 | - qeth_l2_remove_device_attributes(&cgdev->dev); |
1460 | + if (cgdev->dev.type == &qeth_generic_devtype) |
1461 | + qeth_l2_remove_device_attributes(&cgdev->dev); |
1462 | qeth_set_allowed_threads(card, 0, 1); |
1463 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); |
1464 | |
1465 | @@ -1080,7 +1091,6 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) |
1466 | case QETH_CARD_TYPE_OSN: |
1467 | card->dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN, |
1468 | ether_setup); |
1469 | - card->dev->flags |= IFF_NOARP; |
1470 | break; |
1471 | default: |
1472 | card->dev = alloc_etherdev(0); |
1473 | @@ -1095,9 +1105,12 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) |
1474 | card->dev->min_mtu = 64; |
1475 | card->dev->max_mtu = ETH_MAX_MTU; |
1476 | card->dev->netdev_ops = &qeth_l2_netdev_ops; |
1477 | - card->dev->ethtool_ops = |
1478 | - (card->info.type != QETH_CARD_TYPE_OSN) ? |
1479 | - &qeth_l2_ethtool_ops : &qeth_l2_osn_ops; |
1480 | + if (card->info.type == QETH_CARD_TYPE_OSN) { |
1481 | + card->dev->ethtool_ops = &qeth_l2_osn_ops; |
1482 | + card->dev->flags |= IFF_NOARP; |
1483 | + } else { |
1484 | + card->dev->ethtool_ops = &qeth_l2_ethtool_ops; |
1485 | + } |
1486 | card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; |
1487 | if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) { |
1488 | card->dev->hw_features = NETIF_F_SG; |
1489 | @@ -1406,6 +1419,7 @@ static int qeth_l2_control_event(struct qeth_card *card, |
1490 | } |
1491 | |
1492 | struct qeth_discipline qeth_l2_discipline = { |
1493 | + .devtype = &qeth_l2_devtype, |
1494 | .start_poll = qeth_qdio_start_poll, |
1495 | .input_handler = (qdio_handler_t *) qeth_qdio_input_handler, |
1496 | .output_handler = (qdio_handler_t *) qeth_qdio_output_handler, |
1497 | diff --git a/drivers/s390/net/qeth_l2_sys.c b/drivers/s390/net/qeth_l2_sys.c |
1498 | index 692db49e3d2a..a48ed9e7e168 100644 |
1499 | --- a/drivers/s390/net/qeth_l2_sys.c |
1500 | +++ b/drivers/s390/net/qeth_l2_sys.c |
1501 | @@ -272,3 +272,11 @@ void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card) |
1502 | } else |
1503 | qeth_bridgeport_an_set(card, 0); |
1504 | } |
1505 | + |
1506 | +const struct attribute_group *qeth_l2_attr_groups[] = { |
1507 | + &qeth_device_attr_group, |
1508 | + &qeth_device_blkt_group, |
1509 | + /* l2 specific, see l2_{create,remove}_device_attributes(): */ |
1510 | + &qeth_l2_bridgeport_attr_group, |
1511 | + NULL, |
1512 | +}; |
1513 | diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c |
1514 | index 653f0fb76573..d2fb50fd03dc 100644 |
1515 | --- a/drivers/s390/net/qeth_l3_main.c |
1516 | +++ b/drivers/s390/net/qeth_l3_main.c |
1517 | @@ -3153,8 +3153,13 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) |
1518 | static int qeth_l3_probe_device(struct ccwgroup_device *gdev) |
1519 | { |
1520 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
1521 | + int rc; |
1522 | |
1523 | - qeth_l3_create_device_attributes(&gdev->dev); |
1524 | + rc = qeth_l3_create_device_attributes(&gdev->dev); |
1525 | + if (rc) |
1526 | + return rc; |
1527 | + hash_init(card->ip_htable); |
1528 | + hash_init(card->ip_mc_htable); |
1529 | card->options.layer2 = 0; |
1530 | card->info.hwtrap = 0; |
1531 | return 0; |
1532 | @@ -3431,6 +3436,7 @@ static int qeth_l3_control_event(struct qeth_card *card, |
1533 | } |
1534 | |
1535 | struct qeth_discipline qeth_l3_discipline = { |
1536 | + .devtype = &qeth_generic_devtype, |
1537 | .start_poll = qeth_qdio_start_poll, |
1538 | .input_handler = (qdio_handler_t *) qeth_qdio_input_handler, |
1539 | .output_handler = (qdio_handler_t *) qeth_qdio_output_handler, |
1540 | diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c |
1541 | index 3cbab8710e58..2ceff585f189 100644 |
1542 | --- a/drivers/scsi/device_handler/scsi_dh_rdac.c |
1543 | +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c |
1544 | @@ -265,18 +265,16 @@ static unsigned int rdac_failover_get(struct rdac_controller *ctlr, |
1545 | struct list_head *list, |
1546 | unsigned char *cdb) |
1547 | { |
1548 | - struct scsi_device *sdev = ctlr->ms_sdev; |
1549 | - struct rdac_dh_data *h = sdev->handler_data; |
1550 | struct rdac_mode_common *common; |
1551 | unsigned data_size; |
1552 | struct rdac_queue_data *qdata; |
1553 | u8 *lun_table; |
1554 | |
1555 | - if (h->ctlr->use_ms10) { |
1556 | + if (ctlr->use_ms10) { |
1557 | struct rdac_pg_expanded *rdac_pg; |
1558 | |
1559 | data_size = sizeof(struct rdac_pg_expanded); |
1560 | - rdac_pg = &h->ctlr->mode_select.expanded; |
1561 | + rdac_pg = &ctlr->mode_select.expanded; |
1562 | memset(rdac_pg, 0, data_size); |
1563 | common = &rdac_pg->common; |
1564 | rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER + 0x40; |
1565 | @@ -288,7 +286,7 @@ static unsigned int rdac_failover_get(struct rdac_controller *ctlr, |
1566 | struct rdac_pg_legacy *rdac_pg; |
1567 | |
1568 | data_size = sizeof(struct rdac_pg_legacy); |
1569 | - rdac_pg = &h->ctlr->mode_select.legacy; |
1570 | + rdac_pg = &ctlr->mode_select.legacy; |
1571 | memset(rdac_pg, 0, data_size); |
1572 | common = &rdac_pg->common; |
1573 | rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER; |
1574 | @@ -304,7 +302,7 @@ static unsigned int rdac_failover_get(struct rdac_controller *ctlr, |
1575 | } |
1576 | |
1577 | /* Prepare the command. */ |
1578 | - if (h->ctlr->use_ms10) { |
1579 | + if (ctlr->use_ms10) { |
1580 | cdb[0] = MODE_SELECT_10; |
1581 | cdb[7] = data_size >> 8; |
1582 | cdb[8] = data_size & 0xff; |
1583 | diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |
1584 | index d390325c99ec..abf6026645dd 100644 |
1585 | --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |
1586 | +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |
1587 | @@ -1170,6 +1170,8 @@ static struct ibmvscsis_cmd *ibmvscsis_get_free_cmd(struct scsi_info *vscsi) |
1588 | cmd = list_first_entry_or_null(&vscsi->free_cmd, |
1589 | struct ibmvscsis_cmd, list); |
1590 | if (cmd) { |
1591 | + if (cmd->abort_cmd) |
1592 | + cmd->abort_cmd = NULL; |
1593 | cmd->flags &= ~(DELAY_SEND); |
1594 | list_del(&cmd->list); |
1595 | cmd->iue = iue; |
1596 | @@ -1774,6 +1776,7 @@ static void ibmvscsis_send_messages(struct scsi_info *vscsi) |
1597 | if (cmd->abort_cmd) { |
1598 | retry = true; |
1599 | cmd->abort_cmd->flags &= ~(DELAY_SEND); |
1600 | + cmd->abort_cmd = NULL; |
1601 | } |
1602 | |
1603 | /* |
1604 | @@ -1788,6 +1791,25 @@ static void ibmvscsis_send_messages(struct scsi_info *vscsi) |
1605 | list_del(&cmd->list); |
1606 | ibmvscsis_free_cmd_resources(vscsi, |
1607 | cmd); |
1608 | + /* |
1609 | + * With a successfully aborted op |
1610 | + * through LIO we want to increment the |
1611 | + * the vscsi credit so that when we dont |
1612 | + * send a rsp to the original scsi abort |
1613 | + * op (h_send_crq), but the tm rsp to |
1614 | + * the abort is sent, the credit is |
1615 | + * correctly sent with the abort tm rsp. |
1616 | + * We would need 1 for the abort tm rsp |
1617 | + * and 1 credit for the aborted scsi op. |
1618 | + * Thus we need to increment here. |
1619 | + * Also we want to increment the credit |
1620 | + * here because we want to make sure |
1621 | + * cmd is actually released first |
1622 | + * otherwise the client will think it |
1623 | + * it can send a new cmd, and we could |
1624 | + * find ourselves short of cmd elements. |
1625 | + */ |
1626 | + vscsi->credit += 1; |
1627 | } else { |
1628 | iue = cmd->iue; |
1629 | |
1630 | @@ -2962,10 +2984,7 @@ static long srp_build_response(struct scsi_info *vscsi, |
1631 | |
1632 | rsp->opcode = SRP_RSP; |
1633 | |
1634 | - if (vscsi->credit > 0 && vscsi->state == SRP_PROCESSING) |
1635 | - rsp->req_lim_delta = cpu_to_be32(vscsi->credit); |
1636 | - else |
1637 | - rsp->req_lim_delta = cpu_to_be32(1 + vscsi->credit); |
1638 | + rsp->req_lim_delta = cpu_to_be32(1 + vscsi->credit); |
1639 | rsp->tag = cmd->rsp.tag; |
1640 | rsp->flags = 0; |
1641 | |
1642 | diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c |
1643 | index 15c9fe766071..464e7a989cc5 100644 |
1644 | --- a/drivers/scsi/scsi_lib.c |
1645 | +++ b/drivers/scsi/scsi_lib.c |
1646 | @@ -1850,7 +1850,7 @@ static int scsi_mq_prep_fn(struct request *req) |
1647 | |
1648 | /* zero out the cmd, except for the embedded scsi_request */ |
1649 | memset((char *)cmd + sizeof(cmd->req), 0, |
1650 | - sizeof(*cmd) - sizeof(cmd->req)); |
1651 | + sizeof(*cmd) - sizeof(cmd->req) + shost->hostt->cmd_size); |
1652 | |
1653 | req->special = cmd; |
1654 | |
1655 | diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c |
1656 | index 8beed3451346..fd45b48480cb 100644 |
1657 | --- a/drivers/target/iscsi/iscsi_target.c |
1658 | +++ b/drivers/target/iscsi/iscsi_target.c |
1659 | @@ -3810,6 +3810,8 @@ int iscsi_target_tx_thread(void *arg) |
1660 | { |
1661 | int ret = 0; |
1662 | struct iscsi_conn *conn = arg; |
1663 | + bool conn_freed = false; |
1664 | + |
1665 | /* |
1666 | * Allow ourselves to be interrupted by SIGINT so that a |
1667 | * connection recovery / failure event can be triggered externally. |
1668 | @@ -3835,12 +3837,14 @@ int iscsi_target_tx_thread(void *arg) |
1669 | goto transport_err; |
1670 | |
1671 | ret = iscsit_handle_response_queue(conn); |
1672 | - if (ret == 1) |
1673 | + if (ret == 1) { |
1674 | goto get_immediate; |
1675 | - else if (ret == -ECONNRESET) |
1676 | + } else if (ret == -ECONNRESET) { |
1677 | + conn_freed = true; |
1678 | goto out; |
1679 | - else if (ret < 0) |
1680 | + } else if (ret < 0) { |
1681 | goto transport_err; |
1682 | + } |
1683 | } |
1684 | |
1685 | transport_err: |
1686 | @@ -3850,8 +3854,13 @@ int iscsi_target_tx_thread(void *arg) |
1687 | * responsible for cleaning up the early connection failure. |
1688 | */ |
1689 | if (conn->conn_state != TARG_CONN_STATE_IN_LOGIN) |
1690 | - iscsit_take_action_for_connection_exit(conn); |
1691 | + iscsit_take_action_for_connection_exit(conn, &conn_freed); |
1692 | out: |
1693 | + if (!conn_freed) { |
1694 | + while (!kthread_should_stop()) { |
1695 | + msleep(100); |
1696 | + } |
1697 | + } |
1698 | return 0; |
1699 | } |
1700 | |
1701 | @@ -4024,6 +4033,7 @@ int iscsi_target_rx_thread(void *arg) |
1702 | { |
1703 | int rc; |
1704 | struct iscsi_conn *conn = arg; |
1705 | + bool conn_freed = false; |
1706 | |
1707 | /* |
1708 | * Allow ourselves to be interrupted by SIGINT so that a |
1709 | @@ -4036,7 +4046,7 @@ int iscsi_target_rx_thread(void *arg) |
1710 | */ |
1711 | rc = wait_for_completion_interruptible(&conn->rx_login_comp); |
1712 | if (rc < 0 || iscsi_target_check_conn_state(conn)) |
1713 | - return 0; |
1714 | + goto out; |
1715 | |
1716 | if (!conn->conn_transport->iscsit_get_rx_pdu) |
1717 | return 0; |
1718 | @@ -4045,7 +4055,15 @@ int iscsi_target_rx_thread(void *arg) |
1719 | |
1720 | if (!signal_pending(current)) |
1721 | atomic_set(&conn->transport_failed, 1); |
1722 | - iscsit_take_action_for_connection_exit(conn); |
1723 | + iscsit_take_action_for_connection_exit(conn, &conn_freed); |
1724 | + |
1725 | +out: |
1726 | + if (!conn_freed) { |
1727 | + while (!kthread_should_stop()) { |
1728 | + msleep(100); |
1729 | + } |
1730 | + } |
1731 | + |
1732 | return 0; |
1733 | } |
1734 | |
1735 | diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c |
1736 | index 9a96e17bf7cd..7fe2aa73cff6 100644 |
1737 | --- a/drivers/target/iscsi/iscsi_target_erl0.c |
1738 | +++ b/drivers/target/iscsi/iscsi_target_erl0.c |
1739 | @@ -930,8 +930,10 @@ static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn) |
1740 | } |
1741 | } |
1742 | |
1743 | -void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) |
1744 | +void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn, bool *conn_freed) |
1745 | { |
1746 | + *conn_freed = false; |
1747 | + |
1748 | spin_lock_bh(&conn->state_lock); |
1749 | if (atomic_read(&conn->connection_exit)) { |
1750 | spin_unlock_bh(&conn->state_lock); |
1751 | @@ -942,6 +944,7 @@ void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) |
1752 | if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) { |
1753 | spin_unlock_bh(&conn->state_lock); |
1754 | iscsit_close_connection(conn); |
1755 | + *conn_freed = true; |
1756 | return; |
1757 | } |
1758 | |
1759 | @@ -955,4 +958,5 @@ void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) |
1760 | spin_unlock_bh(&conn->state_lock); |
1761 | |
1762 | iscsit_handle_connection_cleanup(conn); |
1763 | + *conn_freed = true; |
1764 | } |
1765 | diff --git a/drivers/target/iscsi/iscsi_target_erl0.h b/drivers/target/iscsi/iscsi_target_erl0.h |
1766 | index 60e69e2af6ed..3822d9cd1230 100644 |
1767 | --- a/drivers/target/iscsi/iscsi_target_erl0.h |
1768 | +++ b/drivers/target/iscsi/iscsi_target_erl0.h |
1769 | @@ -15,6 +15,6 @@ extern int iscsit_stop_time2retain_timer(struct iscsi_session *); |
1770 | extern void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *); |
1771 | extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int); |
1772 | extern void iscsit_fall_back_to_erl0(struct iscsi_session *); |
1773 | -extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *); |
1774 | +extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *, bool *); |
1775 | |
1776 | #endif /*** ISCSI_TARGET_ERL0_H ***/ |
1777 | diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c |
1778 | index 66238477137b..92b96b51d506 100644 |
1779 | --- a/drivers/target/iscsi/iscsi_target_login.c |
1780 | +++ b/drivers/target/iscsi/iscsi_target_login.c |
1781 | @@ -1464,5 +1464,9 @@ int iscsi_target_login_thread(void *arg) |
1782 | break; |
1783 | } |
1784 | |
1785 | + while (!kthread_should_stop()) { |
1786 | + msleep(100); |
1787 | + } |
1788 | + |
1789 | return 0; |
1790 | } |
1791 | diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c |
1792 | index 7ccc9c1cbfd1..6f88b31242b0 100644 |
1793 | --- a/drivers/target/iscsi/iscsi_target_nego.c |
1794 | +++ b/drivers/target/iscsi/iscsi_target_nego.c |
1795 | @@ -493,14 +493,60 @@ static void iscsi_target_restore_sock_callbacks(struct iscsi_conn *conn) |
1796 | |
1797 | static int iscsi_target_do_login(struct iscsi_conn *, struct iscsi_login *); |
1798 | |
1799 | -static bool iscsi_target_sk_state_check(struct sock *sk) |
1800 | +static bool __iscsi_target_sk_check_close(struct sock *sk) |
1801 | { |
1802 | if (sk->sk_state == TCP_CLOSE_WAIT || sk->sk_state == TCP_CLOSE) { |
1803 | - pr_debug("iscsi_target_sk_state_check: TCP_CLOSE_WAIT|TCP_CLOSE," |
1804 | + pr_debug("__iscsi_target_sk_check_close: TCP_CLOSE_WAIT|TCP_CLOSE," |
1805 | "returning FALSE\n"); |
1806 | - return false; |
1807 | + return true; |
1808 | } |
1809 | - return true; |
1810 | + return false; |
1811 | +} |
1812 | + |
1813 | +static bool iscsi_target_sk_check_close(struct iscsi_conn *conn) |
1814 | +{ |
1815 | + bool state = false; |
1816 | + |
1817 | + if (conn->sock) { |
1818 | + struct sock *sk = conn->sock->sk; |
1819 | + |
1820 | + read_lock_bh(&sk->sk_callback_lock); |
1821 | + state = (__iscsi_target_sk_check_close(sk) || |
1822 | + test_bit(LOGIN_FLAGS_CLOSED, &conn->login_flags)); |
1823 | + read_unlock_bh(&sk->sk_callback_lock); |
1824 | + } |
1825 | + return state; |
1826 | +} |
1827 | + |
1828 | +static bool iscsi_target_sk_check_flag(struct iscsi_conn *conn, unsigned int flag) |
1829 | +{ |
1830 | + bool state = false; |
1831 | + |
1832 | + if (conn->sock) { |
1833 | + struct sock *sk = conn->sock->sk; |
1834 | + |
1835 | + read_lock_bh(&sk->sk_callback_lock); |
1836 | + state = test_bit(flag, &conn->login_flags); |
1837 | + read_unlock_bh(&sk->sk_callback_lock); |
1838 | + } |
1839 | + return state; |
1840 | +} |
1841 | + |
1842 | +static bool iscsi_target_sk_check_and_clear(struct iscsi_conn *conn, unsigned int flag) |
1843 | +{ |
1844 | + bool state = false; |
1845 | + |
1846 | + if (conn->sock) { |
1847 | + struct sock *sk = conn->sock->sk; |
1848 | + |
1849 | + write_lock_bh(&sk->sk_callback_lock); |
1850 | + state = (__iscsi_target_sk_check_close(sk) || |
1851 | + test_bit(LOGIN_FLAGS_CLOSED, &conn->login_flags)); |
1852 | + if (!state) |
1853 | + clear_bit(flag, &conn->login_flags); |
1854 | + write_unlock_bh(&sk->sk_callback_lock); |
1855 | + } |
1856 | + return state; |
1857 | } |
1858 | |
1859 | static void iscsi_target_login_drop(struct iscsi_conn *conn, struct iscsi_login *login) |
1860 | @@ -540,6 +586,20 @@ static void iscsi_target_do_login_rx(struct work_struct *work) |
1861 | |
1862 | pr_debug("entering iscsi_target_do_login_rx, conn: %p, %s:%d\n", |
1863 | conn, current->comm, current->pid); |
1864 | + /* |
1865 | + * If iscsi_target_do_login_rx() has been invoked by ->sk_data_ready() |
1866 | + * before initial PDU processing in iscsi_target_start_negotiation() |
1867 | + * has completed, go ahead and retry until it's cleared. |
1868 | + * |
1869 | + * Otherwise if the TCP connection drops while this is occuring, |
1870 | + * iscsi_target_start_negotiation() will detect the failure, call |
1871 | + * cancel_delayed_work_sync(&conn->login_work), and cleanup the |
1872 | + * remaining iscsi connection resources from iscsi_np process context. |
1873 | + */ |
1874 | + if (iscsi_target_sk_check_flag(conn, LOGIN_FLAGS_INITIAL_PDU)) { |
1875 | + schedule_delayed_work(&conn->login_work, msecs_to_jiffies(10)); |
1876 | + return; |
1877 | + } |
1878 | |
1879 | spin_lock(&tpg->tpg_state_lock); |
1880 | state = (tpg->tpg_state == TPG_STATE_ACTIVE); |
1881 | @@ -547,26 +607,12 @@ static void iscsi_target_do_login_rx(struct work_struct *work) |
1882 | |
1883 | if (!state) { |
1884 | pr_debug("iscsi_target_do_login_rx: tpg_state != TPG_STATE_ACTIVE\n"); |
1885 | - iscsi_target_restore_sock_callbacks(conn); |
1886 | - iscsi_target_login_drop(conn, login); |
1887 | - iscsit_deaccess_np(np, tpg, tpg_np); |
1888 | - return; |
1889 | + goto err; |
1890 | } |
1891 | |
1892 | - if (conn->sock) { |
1893 | - struct sock *sk = conn->sock->sk; |
1894 | - |
1895 | - read_lock_bh(&sk->sk_callback_lock); |
1896 | - state = iscsi_target_sk_state_check(sk); |
1897 | - read_unlock_bh(&sk->sk_callback_lock); |
1898 | - |
1899 | - if (!state) { |
1900 | - pr_debug("iscsi_target_do_login_rx, TCP state CLOSE\n"); |
1901 | - iscsi_target_restore_sock_callbacks(conn); |
1902 | - iscsi_target_login_drop(conn, login); |
1903 | - iscsit_deaccess_np(np, tpg, tpg_np); |
1904 | - return; |
1905 | - } |
1906 | + if (iscsi_target_sk_check_close(conn)) { |
1907 | + pr_debug("iscsi_target_do_login_rx, TCP state CLOSE\n"); |
1908 | + goto err; |
1909 | } |
1910 | |
1911 | conn->login_kworker = current; |
1912 | @@ -584,34 +630,29 @@ static void iscsi_target_do_login_rx(struct work_struct *work) |
1913 | flush_signals(current); |
1914 | conn->login_kworker = NULL; |
1915 | |
1916 | - if (rc < 0) { |
1917 | - iscsi_target_restore_sock_callbacks(conn); |
1918 | - iscsi_target_login_drop(conn, login); |
1919 | - iscsit_deaccess_np(np, tpg, tpg_np); |
1920 | - return; |
1921 | - } |
1922 | + if (rc < 0) |
1923 | + goto err; |
1924 | |
1925 | pr_debug("iscsi_target_do_login_rx after rx_login_io, %p, %s:%d\n", |
1926 | conn, current->comm, current->pid); |
1927 | |
1928 | rc = iscsi_target_do_login(conn, login); |
1929 | if (rc < 0) { |
1930 | - iscsi_target_restore_sock_callbacks(conn); |
1931 | - iscsi_target_login_drop(conn, login); |
1932 | - iscsit_deaccess_np(np, tpg, tpg_np); |
1933 | + goto err; |
1934 | } else if (!rc) { |
1935 | - if (conn->sock) { |
1936 | - struct sock *sk = conn->sock->sk; |
1937 | - |
1938 | - write_lock_bh(&sk->sk_callback_lock); |
1939 | - clear_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags); |
1940 | - write_unlock_bh(&sk->sk_callback_lock); |
1941 | - } |
1942 | + if (iscsi_target_sk_check_and_clear(conn, LOGIN_FLAGS_READ_ACTIVE)) |
1943 | + goto err; |
1944 | } else if (rc == 1) { |
1945 | iscsi_target_nego_release(conn); |
1946 | iscsi_post_login_handler(np, conn, zero_tsih); |
1947 | iscsit_deaccess_np(np, tpg, tpg_np); |
1948 | } |
1949 | + return; |
1950 | + |
1951 | +err: |
1952 | + iscsi_target_restore_sock_callbacks(conn); |
1953 | + iscsi_target_login_drop(conn, login); |
1954 | + iscsit_deaccess_np(np, tpg, tpg_np); |
1955 | } |
1956 | |
1957 | static void iscsi_target_do_cleanup(struct work_struct *work) |
1958 | @@ -659,31 +700,54 @@ static void iscsi_target_sk_state_change(struct sock *sk) |
1959 | orig_state_change(sk); |
1960 | return; |
1961 | } |
1962 | + state = __iscsi_target_sk_check_close(sk); |
1963 | + pr_debug("__iscsi_target_sk_close_change: state: %d\n", state); |
1964 | + |
1965 | if (test_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags)) { |
1966 | pr_debug("Got LOGIN_FLAGS_READ_ACTIVE=1 sk_state_change" |
1967 | " conn: %p\n", conn); |
1968 | + if (state) |
1969 | + set_bit(LOGIN_FLAGS_CLOSED, &conn->login_flags); |
1970 | write_unlock_bh(&sk->sk_callback_lock); |
1971 | orig_state_change(sk); |
1972 | return; |
1973 | } |
1974 | - if (test_and_set_bit(LOGIN_FLAGS_CLOSED, &conn->login_flags)) { |
1975 | + if (test_bit(LOGIN_FLAGS_CLOSED, &conn->login_flags)) { |
1976 | pr_debug("Got LOGIN_FLAGS_CLOSED=1 sk_state_change conn: %p\n", |
1977 | conn); |
1978 | write_unlock_bh(&sk->sk_callback_lock); |
1979 | orig_state_change(sk); |
1980 | return; |
1981 | } |
1982 | + /* |
1983 | + * If the TCP connection has dropped, go ahead and set LOGIN_FLAGS_CLOSED, |
1984 | + * but only queue conn->login_work -> iscsi_target_do_login_rx() |
1985 | + * processing if LOGIN_FLAGS_INITIAL_PDU has already been cleared. |
1986 | + * |
1987 | + * When iscsi_target_do_login_rx() runs, iscsi_target_sk_check_close() |
1988 | + * will detect the dropped TCP connection from delayed workqueue context. |
1989 | + * |
1990 | + * If LOGIN_FLAGS_INITIAL_PDU is still set, which means the initial |
1991 | + * iscsi_target_start_negotiation() is running, iscsi_target_do_login() |
1992 | + * via iscsi_target_sk_check_close() or iscsi_target_start_negotiation() |
1993 | + * via iscsi_target_sk_check_and_clear() is responsible for detecting the |
1994 | + * dropped TCP connection in iscsi_np process context, and cleaning up |
1995 | + * the remaining iscsi connection resources. |
1996 | + */ |
1997 | + if (state) { |
1998 | + pr_debug("iscsi_target_sk_state_change got failed state\n"); |
1999 | + set_bit(LOGIN_FLAGS_CLOSED, &conn->login_flags); |
2000 | + state = test_bit(LOGIN_FLAGS_INITIAL_PDU, &conn->login_flags); |
2001 | + write_unlock_bh(&sk->sk_callback_lock); |
2002 | |
2003 | - state = iscsi_target_sk_state_check(sk); |
2004 | - write_unlock_bh(&sk->sk_callback_lock); |
2005 | - |
2006 | - pr_debug("iscsi_target_sk_state_change: state: %d\n", state); |
2007 | + orig_state_change(sk); |
2008 | |
2009 | - if (!state) { |
2010 | - pr_debug("iscsi_target_sk_state_change got failed state\n"); |
2011 | - schedule_delayed_work(&conn->login_cleanup_work, 0); |
2012 | + if (!state) |
2013 | + schedule_delayed_work(&conn->login_work, 0); |
2014 | return; |
2015 | } |
2016 | + write_unlock_bh(&sk->sk_callback_lock); |
2017 | + |
2018 | orig_state_change(sk); |
2019 | } |
2020 | |
2021 | @@ -946,6 +1010,15 @@ static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *lo |
2022 | if (iscsi_target_handle_csg_one(conn, login) < 0) |
2023 | return -1; |
2024 | if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) { |
2025 | + /* |
2026 | + * Check to make sure the TCP connection has not |
2027 | + * dropped asynchronously while session reinstatement |
2028 | + * was occuring in this kthread context, before |
2029 | + * transitioning to full feature phase operation. |
2030 | + */ |
2031 | + if (iscsi_target_sk_check_close(conn)) |
2032 | + return -1; |
2033 | + |
2034 | login->tsih = conn->sess->tsih; |
2035 | login->login_complete = 1; |
2036 | iscsi_target_restore_sock_callbacks(conn); |
2037 | @@ -972,21 +1045,6 @@ static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *lo |
2038 | break; |
2039 | } |
2040 | |
2041 | - if (conn->sock) { |
2042 | - struct sock *sk = conn->sock->sk; |
2043 | - bool state; |
2044 | - |
2045 | - read_lock_bh(&sk->sk_callback_lock); |
2046 | - state = iscsi_target_sk_state_check(sk); |
2047 | - read_unlock_bh(&sk->sk_callback_lock); |
2048 | - |
2049 | - if (!state) { |
2050 | - pr_debug("iscsi_target_do_login() failed state for" |
2051 | - " conn: %p\n", conn); |
2052 | - return -1; |
2053 | - } |
2054 | - } |
2055 | - |
2056 | return 0; |
2057 | } |
2058 | |
2059 | @@ -1255,10 +1313,22 @@ int iscsi_target_start_negotiation( |
2060 | |
2061 | write_lock_bh(&sk->sk_callback_lock); |
2062 | set_bit(LOGIN_FLAGS_READY, &conn->login_flags); |
2063 | + set_bit(LOGIN_FLAGS_INITIAL_PDU, &conn->login_flags); |
2064 | write_unlock_bh(&sk->sk_callback_lock); |
2065 | } |
2066 | - |
2067 | + /* |
2068 | + * If iscsi_target_do_login returns zero to signal more PDU |
2069 | + * exchanges are required to complete the login, go ahead and |
2070 | + * clear LOGIN_FLAGS_INITIAL_PDU but only if the TCP connection |
2071 | + * is still active. |
2072 | + * |
2073 | + * Otherwise if TCP connection dropped asynchronously, go ahead |
2074 | + * and perform connection cleanup now. |
2075 | + */ |
2076 | ret = iscsi_target_do_login(conn, login); |
2077 | + if (!ret && iscsi_target_sk_check_and_clear(conn, LOGIN_FLAGS_INITIAL_PDU)) |
2078 | + ret = -1; |
2079 | + |
2080 | if (ret < 0) { |
2081 | cancel_delayed_work_sync(&conn->login_work); |
2082 | cancel_delayed_work_sync(&conn->login_cleanup_work); |
2083 | diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c |
2084 | index d05393594f15..06e17faa6dfb 100644 |
2085 | --- a/drivers/tty/serdev/serdev-ttyport.c |
2086 | +++ b/drivers/tty/serdev/serdev-ttyport.c |
2087 | @@ -101,9 +101,6 @@ static int ttyport_open(struct serdev_controller *ctrl) |
2088 | return PTR_ERR(tty); |
2089 | serport->tty = tty; |
2090 | |
2091 | - serport->port->client_ops = &client_ops; |
2092 | - serport->port->client_data = ctrl; |
2093 | - |
2094 | if (tty->ops->open) |
2095 | tty->ops->open(serport->tty, NULL); |
2096 | else |
2097 | @@ -181,6 +178,7 @@ struct device *serdev_tty_port_register(struct tty_port *port, |
2098 | struct device *parent, |
2099 | struct tty_driver *drv, int idx) |
2100 | { |
2101 | + const struct tty_port_client_operations *old_ops; |
2102 | struct serdev_controller *ctrl; |
2103 | struct serport *serport; |
2104 | int ret; |
2105 | @@ -199,15 +197,22 @@ struct device *serdev_tty_port_register(struct tty_port *port, |
2106 | |
2107 | ctrl->ops = &ctrl_ops; |
2108 | |
2109 | + old_ops = port->client_ops; |
2110 | + port->client_ops = &client_ops; |
2111 | + port->client_data = ctrl; |
2112 | + |
2113 | ret = serdev_controller_add(ctrl); |
2114 | if (ret) |
2115 | - goto err_controller_put; |
2116 | + goto err_reset_data; |
2117 | |
2118 | dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx); |
2119 | return &ctrl->dev; |
2120 | |
2121 | -err_controller_put: |
2122 | +err_reset_data: |
2123 | + port->client_data = NULL; |
2124 | + port->client_ops = old_ops; |
2125 | serdev_controller_put(ctrl); |
2126 | + |
2127 | return ERR_PTR(ret); |
2128 | } |
2129 | |
2130 | diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c |
2131 | index 6119516ef5fc..4c26d15ad7d9 100644 |
2132 | --- a/drivers/tty/serial/8250/8250_port.c |
2133 | +++ b/drivers/tty/serial/8250/8250_port.c |
2134 | @@ -1337,7 +1337,7 @@ static void autoconfig(struct uart_8250_port *up) |
2135 | /* |
2136 | * Check if the device is a Fintek F81216A |
2137 | */ |
2138 | - if (port->type == PORT_16550A) |
2139 | + if (port->type == PORT_16550A && port->iotype == UPIO_PORT) |
2140 | fintek_8250_probe(up); |
2141 | |
2142 | if (up->capabilities != old_capabilities) { |
2143 | diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c |
2144 | index 1d21a9c1d33e..0c880f17d27e 100644 |
2145 | --- a/drivers/tty/tty_port.c |
2146 | +++ b/drivers/tty/tty_port.c |
2147 | @@ -16,7 +16,6 @@ |
2148 | #include <linux/bitops.h> |
2149 | #include <linux/delay.h> |
2150 | #include <linux/module.h> |
2151 | -#include <linux/serdev.h> |
2152 | |
2153 | static int tty_port_default_receive_buf(struct tty_port *port, |
2154 | const unsigned char *p, |
2155 | @@ -129,15 +128,7 @@ struct device *tty_port_register_device_attr(struct tty_port *port, |
2156 | struct device *device, void *drvdata, |
2157 | const struct attribute_group **attr_grp) |
2158 | { |
2159 | - struct device *dev; |
2160 | - |
2161 | tty_port_link_device(port, driver, index); |
2162 | - |
2163 | - dev = serdev_tty_port_register(port, device, driver, index); |
2164 | - if (PTR_ERR(dev) != -ENODEV) |
2165 | - /* Skip creating cdev if we registered a serdev device */ |
2166 | - return dev; |
2167 | - |
2168 | return tty_register_device_attr(driver, index, device, drvdata, |
2169 | attr_grp); |
2170 | } |
2171 | @@ -189,9 +180,6 @@ static void tty_port_destructor(struct kref *kref) |
2172 | /* check if last port ref was dropped before tty release */ |
2173 | if (WARN_ON(port->itty)) |
2174 | return; |
2175 | - |
2176 | - serdev_tty_port_unregister(port); |
2177 | - |
2178 | if (port->xmit_buf) |
2179 | free_page((unsigned long)port->xmit_buf); |
2180 | tty_port_destroy(port); |
2181 | diff --git a/fs/dax.c b/fs/dax.c |
2182 | index db0cc52eb22e..285f4ab6f498 100644 |
2183 | --- a/fs/dax.c |
2184 | +++ b/fs/dax.c |
2185 | @@ -1129,6 +1129,17 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, |
2186 | return dax_fault_return(PTR_ERR(entry)); |
2187 | |
2188 | /* |
2189 | + * It is possible, particularly with mixed reads & writes to private |
2190 | + * mappings, that we have raced with a PMD fault that overlaps with |
2191 | + * the PTE we need to set up. If so just return and the fault will be |
2192 | + * retried. |
2193 | + */ |
2194 | + if (pmd_trans_huge(*vmf->pmd) || pmd_devmap(*vmf->pmd)) { |
2195 | + vmf_ret = VM_FAULT_NOPAGE; |
2196 | + goto unlock_entry; |
2197 | + } |
2198 | + |
2199 | + /* |
2200 | * Note that we don't bother to use iomap_apply here: DAX required |
2201 | * the file system block size to be equal the page size, which means |
2202 | * that we never have to deal with more than a single extent here. |
2203 | @@ -1363,6 +1374,18 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, |
2204 | goto fallback; |
2205 | |
2206 | /* |
2207 | + * It is possible, particularly with mixed reads & writes to private |
2208 | + * mappings, that we have raced with a PTE fault that overlaps with |
2209 | + * the PMD we need to set up. If so just return and the fault will be |
2210 | + * retried. |
2211 | + */ |
2212 | + if (!pmd_none(*vmf->pmd) && !pmd_trans_huge(*vmf->pmd) && |
2213 | + !pmd_devmap(*vmf->pmd)) { |
2214 | + result = 0; |
2215 | + goto unlock_entry; |
2216 | + } |
2217 | + |
2218 | + /* |
2219 | * Note that we don't use iomap_apply here. We aren't doing I/O, only |
2220 | * setting up a mapping, so really we're using iomap_begin() as a way |
2221 | * to look up our filesystem block. |
2222 | diff --git a/fs/ufs/super.c b/fs/ufs/super.c |
2223 | index 131b2b77c818..29ecaf739449 100644 |
2224 | --- a/fs/ufs/super.c |
2225 | +++ b/fs/ufs/super.c |
2226 | @@ -812,9 +812,8 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) |
2227 | uspi->s_dirblksize = UFS_SECTOR_SIZE; |
2228 | super_block_offset=UFS_SBLOCK; |
2229 | |
2230 | - /* Keep 2Gig file limit. Some UFS variants need to override |
2231 | - this but as I don't know which I'll let those in the know loosen |
2232 | - the rules */ |
2233 | + sb->s_maxbytes = MAX_LFS_FILESIZE; |
2234 | + |
2235 | switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) { |
2236 | case UFS_MOUNT_UFSTYPE_44BSD: |
2237 | UFSD("ufstype=44bsd\n"); |
2238 | diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c |
2239 | index 9bd104f32908..6c68f3b888b0 100644 |
2240 | --- a/fs/xfs/libxfs/xfs_bmap.c |
2241 | +++ b/fs/xfs/libxfs/xfs_bmap.c |
2242 | @@ -2106,8 +2106,10 @@ xfs_bmap_add_extent_delay_real( |
2243 | } |
2244 | temp = xfs_bmap_worst_indlen(bma->ip, temp); |
2245 | temp2 = xfs_bmap_worst_indlen(bma->ip, temp2); |
2246 | - diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - |
2247 | - (bma->cur ? bma->cur->bc_private.b.allocated : 0)); |
2248 | + diff = (int)(temp + temp2 - |
2249 | + (startblockval(PREV.br_startblock) - |
2250 | + (bma->cur ? |
2251 | + bma->cur->bc_private.b.allocated : 0))); |
2252 | if (diff > 0) { |
2253 | error = xfs_mod_fdblocks(bma->ip->i_mount, |
2254 | -((int64_t)diff), false); |
2255 | @@ -2164,7 +2166,6 @@ xfs_bmap_add_extent_delay_real( |
2256 | temp = da_new; |
2257 | if (bma->cur) |
2258 | temp += bma->cur->bc_private.b.allocated; |
2259 | - ASSERT(temp <= da_old); |
2260 | if (temp < da_old) |
2261 | xfs_mod_fdblocks(bma->ip->i_mount, |
2262 | (int64_t)(da_old - temp), false); |
2263 | @@ -3863,7 +3864,7 @@ xfs_bmap_remap_alloc( |
2264 | { |
2265 | struct xfs_trans *tp = ap->tp; |
2266 | struct xfs_mount *mp = tp->t_mountp; |
2267 | - xfs_agblock_t bno; |
2268 | + xfs_fsblock_t bno; |
2269 | struct xfs_alloc_arg args; |
2270 | int error; |
2271 | |
2272 | diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c |
2273 | index c3decedc9455..3d0f96d159ff 100644 |
2274 | --- a/fs/xfs/libxfs/xfs_btree.c |
2275 | +++ b/fs/xfs/libxfs/xfs_btree.c |
2276 | @@ -4395,7 +4395,7 @@ xfs_btree_visit_blocks( |
2277 | xfs_btree_readahead_ptr(cur, ptr, 1); |
2278 | |
2279 | /* save for the next iteration of the loop */ |
2280 | - lptr = *ptr; |
2281 | + xfs_btree_copy_ptrs(cur, &lptr, ptr, 1); |
2282 | } |
2283 | |
2284 | /* for each buffer in the level */ |
2285 | diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c |
2286 | index b177ef33cd4c..82a38d86ebad 100644 |
2287 | --- a/fs/xfs/libxfs/xfs_refcount.c |
2288 | +++ b/fs/xfs/libxfs/xfs_refcount.c |
2289 | @@ -1629,13 +1629,28 @@ xfs_refcount_recover_cow_leftovers( |
2290 | if (mp->m_sb.sb_agblocks >= XFS_REFC_COW_START) |
2291 | return -EOPNOTSUPP; |
2292 | |
2293 | - error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); |
2294 | + INIT_LIST_HEAD(&debris); |
2295 | + |
2296 | + /* |
2297 | + * In this first part, we use an empty transaction to gather up |
2298 | + * all the leftover CoW extents so that we can subsequently |
2299 | + * delete them. The empty transaction is used to avoid |
2300 | + * a buffer lock deadlock if there happens to be a loop in the |
2301 | + * refcountbt because we're allowed to re-grab a buffer that is |
2302 | + * already attached to our transaction. When we're done |
2303 | + * recording the CoW debris we cancel the (empty) transaction |
2304 | + * and everything goes away cleanly. |
2305 | + */ |
2306 | + error = xfs_trans_alloc_empty(mp, &tp); |
2307 | if (error) |
2308 | return error; |
2309 | - cur = xfs_refcountbt_init_cursor(mp, NULL, agbp, agno, NULL); |
2310 | + |
2311 | + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); |
2312 | + if (error) |
2313 | + goto out_trans; |
2314 | + cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, NULL); |
2315 | |
2316 | /* Find all the leftover CoW staging extents. */ |
2317 | - INIT_LIST_HEAD(&debris); |
2318 | memset(&low, 0, sizeof(low)); |
2319 | memset(&high, 0, sizeof(high)); |
2320 | low.rc.rc_startblock = XFS_REFC_COW_START; |
2321 | @@ -1645,10 +1660,11 @@ xfs_refcount_recover_cow_leftovers( |
2322 | if (error) |
2323 | goto out_cursor; |
2324 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); |
2325 | - xfs_buf_relse(agbp); |
2326 | + xfs_trans_brelse(tp, agbp); |
2327 | + xfs_trans_cancel(tp); |
2328 | |
2329 | /* Now iterate the list to free the leftovers */ |
2330 | - list_for_each_entry(rr, &debris, rr_list) { |
2331 | + list_for_each_entry_safe(rr, n, &debris, rr_list) { |
2332 | /* Set up transaction. */ |
2333 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp); |
2334 | if (error) |
2335 | @@ -1676,8 +1692,16 @@ xfs_refcount_recover_cow_leftovers( |
2336 | error = xfs_trans_commit(tp); |
2337 | if (error) |
2338 | goto out_free; |
2339 | + |
2340 | + list_del(&rr->rr_list); |
2341 | + kmem_free(rr); |
2342 | } |
2343 | |
2344 | + return error; |
2345 | +out_defer: |
2346 | + xfs_defer_cancel(&dfops); |
2347 | +out_trans: |
2348 | + xfs_trans_cancel(tp); |
2349 | out_free: |
2350 | /* Free the leftover list */ |
2351 | list_for_each_entry_safe(rr, n, &debris, rr_list) { |
2352 | @@ -1688,11 +1712,6 @@ xfs_refcount_recover_cow_leftovers( |
2353 | |
2354 | out_cursor: |
2355 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); |
2356 | - xfs_buf_relse(agbp); |
2357 | - goto out_free; |
2358 | - |
2359 | -out_defer: |
2360 | - xfs_defer_cancel(&dfops); |
2361 | - xfs_trans_cancel(tp); |
2362 | - goto out_free; |
2363 | + xfs_trans_brelse(tp, agbp); |
2364 | + goto out_trans; |
2365 | } |
2366 | diff --git a/fs/xfs/libxfs/xfs_trans_space.h b/fs/xfs/libxfs/xfs_trans_space.h |
2367 | index 7917f6e44286..d787c677d2a3 100644 |
2368 | --- a/fs/xfs/libxfs/xfs_trans_space.h |
2369 | +++ b/fs/xfs/libxfs/xfs_trans_space.h |
2370 | @@ -21,8 +21,20 @@ |
2371 | /* |
2372 | * Components of space reservations. |
2373 | */ |
2374 | + |
2375 | +/* Worst case number of rmaps that can be held in a block. */ |
2376 | #define XFS_MAX_CONTIG_RMAPS_PER_BLOCK(mp) \ |
2377 | (((mp)->m_rmap_mxr[0]) - ((mp)->m_rmap_mnr[0])) |
2378 | + |
2379 | +/* Adding one rmap could split every level up to the top of the tree. */ |
2380 | +#define XFS_RMAPADD_SPACE_RES(mp) ((mp)->m_rmap_maxlevels) |
2381 | + |
2382 | +/* Blocks we might need to add "b" rmaps to a tree. */ |
2383 | +#define XFS_NRMAPADD_SPACE_RES(mp, b)\ |
2384 | + (((b + XFS_MAX_CONTIG_RMAPS_PER_BLOCK(mp) - 1) / \ |
2385 | + XFS_MAX_CONTIG_RMAPS_PER_BLOCK(mp)) * \ |
2386 | + XFS_RMAPADD_SPACE_RES(mp)) |
2387 | + |
2388 | #define XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) \ |
2389 | (((mp)->m_alloc_mxr[0]) - ((mp)->m_alloc_mnr[0])) |
2390 | #define XFS_EXTENTADD_SPACE_RES(mp,w) (XFS_BM_MAXLEVELS(mp,w) - 1) |
2391 | @@ -30,13 +42,12 @@ |
2392 | (((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \ |
2393 | XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \ |
2394 | XFS_EXTENTADD_SPACE_RES(mp,w)) |
2395 | + |
2396 | +/* Blocks we might need to add "b" mappings & rmappings to a file. */ |
2397 | #define XFS_SWAP_RMAP_SPACE_RES(mp,b,w)\ |
2398 | - (((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \ |
2399 | - XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \ |
2400 | - XFS_EXTENTADD_SPACE_RES(mp,w) + \ |
2401 | - ((b + XFS_MAX_CONTIG_RMAPS_PER_BLOCK(mp) - 1) / \ |
2402 | - XFS_MAX_CONTIG_RMAPS_PER_BLOCK(mp)) * \ |
2403 | - (mp)->m_rmap_maxlevels) |
2404 | + (XFS_NEXTENTADD_SPACE_RES((mp), (b), (w)) + \ |
2405 | + XFS_NRMAPADD_SPACE_RES((mp), (b))) |
2406 | + |
2407 | #define XFS_DAENTER_1B(mp,w) \ |
2408 | ((w) == XFS_DATA_FORK ? (mp)->m_dir_geo->fsbcount : 1) |
2409 | #define XFS_DAENTER_DBS(mp,w) \ |
2410 | diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c |
2411 | index 61494295d92f..a7645be51d87 100644 |
2412 | --- a/fs/xfs/xfs_aops.c |
2413 | +++ b/fs/xfs/xfs_aops.c |
2414 | @@ -111,11 +111,11 @@ xfs_finish_page_writeback( |
2415 | |
2416 | bsize = bh->b_size; |
2417 | do { |
2418 | + if (off > end) |
2419 | + break; |
2420 | next = bh->b_this_page; |
2421 | if (off < bvec->bv_offset) |
2422 | goto next_bh; |
2423 | - if (off > end) |
2424 | - break; |
2425 | bh->b_end_io(bh, !error); |
2426 | next_bh: |
2427 | off += bsize; |
2428 | diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c |
2429 | index 9bf57c76623b..c4b90e794e41 100644 |
2430 | --- a/fs/xfs/xfs_bmap_item.c |
2431 | +++ b/fs/xfs/xfs_bmap_item.c |
2432 | @@ -34,6 +34,8 @@ |
2433 | #include "xfs_bmap.h" |
2434 | #include "xfs_icache.h" |
2435 | #include "xfs_trace.h" |
2436 | +#include "xfs_bmap_btree.h" |
2437 | +#include "xfs_trans_space.h" |
2438 | |
2439 | |
2440 | kmem_zone_t *xfs_bui_zone; |
2441 | @@ -446,7 +448,8 @@ xfs_bui_recover( |
2442 | return -EIO; |
2443 | } |
2444 | |
2445 | - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); |
2446 | + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, |
2447 | + XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp); |
2448 | if (error) |
2449 | return error; |
2450 | budp = xfs_trans_get_bud(tp, buip); |
2451 | diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c |
2452 | index 828532ce0adc..70fbecbb2845 100644 |
2453 | --- a/fs/xfs/xfs_bmap_util.c |
2454 | +++ b/fs/xfs/xfs_bmap_util.c |
2455 | @@ -583,9 +583,13 @@ xfs_getbmap( |
2456 | } |
2457 | break; |
2458 | default: |
2459 | + /* Local format data forks report no extents. */ |
2460 | + if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { |
2461 | + bmv->bmv_entries = 0; |
2462 | + return 0; |
2463 | + } |
2464 | if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS && |
2465 | - ip->i_d.di_format != XFS_DINODE_FMT_BTREE && |
2466 | - ip->i_d.di_format != XFS_DINODE_FMT_LOCAL) |
2467 | + ip->i_d.di_format != XFS_DINODE_FMT_BTREE) |
2468 | return -EINVAL; |
2469 | |
2470 | if (xfs_get_extsz_hint(ip) || |
2471 | @@ -713,7 +717,7 @@ xfs_getbmap( |
2472 | * extents. |
2473 | */ |
2474 | if (map[i].br_startblock == DELAYSTARTBLOCK && |
2475 | - map[i].br_startoff <= XFS_B_TO_FSB(mp, XFS_ISIZE(ip))) |
2476 | + map[i].br_startoff < XFS_B_TO_FSB(mp, XFS_ISIZE(ip))) |
2477 | ASSERT((iflags & BMV_IF_DELALLOC) != 0); |
2478 | |
2479 | if (map[i].br_startblock == HOLESTARTBLOCK && |
2480 | @@ -904,9 +908,9 @@ xfs_can_free_eofblocks(struct xfs_inode *ip, bool force) |
2481 | } |
2482 | |
2483 | /* |
2484 | - * This is called by xfs_inactive to free any blocks beyond eof |
2485 | - * when the link count isn't zero and by xfs_dm_punch_hole() when |
2486 | - * punching a hole to EOF. |
2487 | + * This is called to free any blocks beyond eof. The caller must hold |
2488 | + * IOLOCK_EXCL unless we are in the inode reclaim path and have the only |
2489 | + * reference to the inode. |
2490 | */ |
2491 | int |
2492 | xfs_free_eofblocks( |
2493 | @@ -921,8 +925,6 @@ xfs_free_eofblocks( |
2494 | struct xfs_bmbt_irec imap; |
2495 | struct xfs_mount *mp = ip->i_mount; |
2496 | |
2497 | - ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); |
2498 | - |
2499 | /* |
2500 | * Figure out if there are any blocks beyond the end |
2501 | * of the file. If not, then there is nothing to do. |
2502 | diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c |
2503 | index b6208728ba39..4e19fdabac9d 100644 |
2504 | --- a/fs/xfs/xfs_buf.c |
2505 | +++ b/fs/xfs/xfs_buf.c |
2506 | @@ -97,12 +97,16 @@ static inline void |
2507 | xfs_buf_ioacct_inc( |
2508 | struct xfs_buf *bp) |
2509 | { |
2510 | - if (bp->b_flags & (XBF_NO_IOACCT|_XBF_IN_FLIGHT)) |
2511 | + if (bp->b_flags & XBF_NO_IOACCT) |
2512 | return; |
2513 | |
2514 | ASSERT(bp->b_flags & XBF_ASYNC); |
2515 | - bp->b_flags |= _XBF_IN_FLIGHT; |
2516 | - percpu_counter_inc(&bp->b_target->bt_io_count); |
2517 | + spin_lock(&bp->b_lock); |
2518 | + if (!(bp->b_state & XFS_BSTATE_IN_FLIGHT)) { |
2519 | + bp->b_state |= XFS_BSTATE_IN_FLIGHT; |
2520 | + percpu_counter_inc(&bp->b_target->bt_io_count); |
2521 | + } |
2522 | + spin_unlock(&bp->b_lock); |
2523 | } |
2524 | |
2525 | /* |
2526 | @@ -110,14 +114,24 @@ xfs_buf_ioacct_inc( |
2527 | * freed and unaccount from the buftarg. |
2528 | */ |
2529 | static inline void |
2530 | -xfs_buf_ioacct_dec( |
2531 | +__xfs_buf_ioacct_dec( |
2532 | struct xfs_buf *bp) |
2533 | { |
2534 | - if (!(bp->b_flags & _XBF_IN_FLIGHT)) |
2535 | - return; |
2536 | + ASSERT(spin_is_locked(&bp->b_lock)); |
2537 | |
2538 | - bp->b_flags &= ~_XBF_IN_FLIGHT; |
2539 | - percpu_counter_dec(&bp->b_target->bt_io_count); |
2540 | + if (bp->b_state & XFS_BSTATE_IN_FLIGHT) { |
2541 | + bp->b_state &= ~XFS_BSTATE_IN_FLIGHT; |
2542 | + percpu_counter_dec(&bp->b_target->bt_io_count); |
2543 | + } |
2544 | +} |
2545 | + |
2546 | +static inline void |
2547 | +xfs_buf_ioacct_dec( |
2548 | + struct xfs_buf *bp) |
2549 | +{ |
2550 | + spin_lock(&bp->b_lock); |
2551 | + __xfs_buf_ioacct_dec(bp); |
2552 | + spin_unlock(&bp->b_lock); |
2553 | } |
2554 | |
2555 | /* |
2556 | @@ -149,9 +163,9 @@ xfs_buf_stale( |
2557 | * unaccounted (released to LRU) before that occurs. Drop in-flight |
2558 | * status now to preserve accounting consistency. |
2559 | */ |
2560 | - xfs_buf_ioacct_dec(bp); |
2561 | - |
2562 | spin_lock(&bp->b_lock); |
2563 | + __xfs_buf_ioacct_dec(bp); |
2564 | + |
2565 | atomic_set(&bp->b_lru_ref, 0); |
2566 | if (!(bp->b_state & XFS_BSTATE_DISPOSE) && |
2567 | (list_lru_del(&bp->b_target->bt_lru, &bp->b_lru))) |
2568 | @@ -979,12 +993,12 @@ xfs_buf_rele( |
2569 | * ensures the decrement occurs only once per-buf. |
2570 | */ |
2571 | if ((atomic_read(&bp->b_hold) == 1) && !list_empty(&bp->b_lru)) |
2572 | - xfs_buf_ioacct_dec(bp); |
2573 | + __xfs_buf_ioacct_dec(bp); |
2574 | goto out_unlock; |
2575 | } |
2576 | |
2577 | /* the last reference has been dropped ... */ |
2578 | - xfs_buf_ioacct_dec(bp); |
2579 | + __xfs_buf_ioacct_dec(bp); |
2580 | if (!(bp->b_flags & XBF_STALE) && atomic_read(&bp->b_lru_ref)) { |
2581 | /* |
2582 | * If the buffer is added to the LRU take a new reference to the |
2583 | @@ -1079,6 +1093,8 @@ void |
2584 | xfs_buf_unlock( |
2585 | struct xfs_buf *bp) |
2586 | { |
2587 | + ASSERT(xfs_buf_islocked(bp)); |
2588 | + |
2589 | XB_CLEAR_OWNER(bp); |
2590 | up(&bp->b_sema); |
2591 | |
2592 | @@ -1815,6 +1831,28 @@ xfs_alloc_buftarg( |
2593 | } |
2594 | |
2595 | /* |
2596 | + * Cancel a delayed write list. |
2597 | + * |
2598 | + * Remove each buffer from the list, clear the delwri queue flag and drop the |
2599 | + * associated buffer reference. |
2600 | + */ |
2601 | +void |
2602 | +xfs_buf_delwri_cancel( |
2603 | + struct list_head *list) |
2604 | +{ |
2605 | + struct xfs_buf *bp; |
2606 | + |
2607 | + while (!list_empty(list)) { |
2608 | + bp = list_first_entry(list, struct xfs_buf, b_list); |
2609 | + |
2610 | + xfs_buf_lock(bp); |
2611 | + bp->b_flags &= ~_XBF_DELWRI_Q; |
2612 | + list_del_init(&bp->b_list); |
2613 | + xfs_buf_relse(bp); |
2614 | + } |
2615 | +} |
2616 | + |
2617 | +/* |
2618 | * Add a buffer to the delayed write list. |
2619 | * |
2620 | * This queues a buffer for writeout if it hasn't already been. Note that |
2621 | diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h |
2622 | index 3c867e5a63e1..39d9334e59ee 100644 |
2623 | --- a/fs/xfs/xfs_buf.h |
2624 | +++ b/fs/xfs/xfs_buf.h |
2625 | @@ -63,7 +63,6 @@ typedef enum { |
2626 | #define _XBF_KMEM (1 << 21)/* backed by heap memory */ |
2627 | #define _XBF_DELWRI_Q (1 << 22)/* buffer on a delwri queue */ |
2628 | #define _XBF_COMPOUND (1 << 23)/* compound buffer */ |
2629 | -#define _XBF_IN_FLIGHT (1 << 25) /* I/O in flight, for accounting purposes */ |
2630 | |
2631 | typedef unsigned int xfs_buf_flags_t; |
2632 | |
2633 | @@ -84,14 +83,14 @@ typedef unsigned int xfs_buf_flags_t; |
2634 | { _XBF_PAGES, "PAGES" }, \ |
2635 | { _XBF_KMEM, "KMEM" }, \ |
2636 | { _XBF_DELWRI_Q, "DELWRI_Q" }, \ |
2637 | - { _XBF_COMPOUND, "COMPOUND" }, \ |
2638 | - { _XBF_IN_FLIGHT, "IN_FLIGHT" } |
2639 | + { _XBF_COMPOUND, "COMPOUND" } |
2640 | |
2641 | |
2642 | /* |
2643 | * Internal state flags. |
2644 | */ |
2645 | #define XFS_BSTATE_DISPOSE (1 << 0) /* buffer being discarded */ |
2646 | +#define XFS_BSTATE_IN_FLIGHT (1 << 1) /* I/O in flight */ |
2647 | |
2648 | /* |
2649 | * The xfs_buftarg contains 2 notions of "sector size" - |
2650 | @@ -330,6 +329,7 @@ extern void *xfs_buf_offset(struct xfs_buf *, size_t); |
2651 | extern void xfs_buf_stale(struct xfs_buf *bp); |
2652 | |
2653 | /* Delayed Write Buffer Routines */ |
2654 | +extern void xfs_buf_delwri_cancel(struct list_head *); |
2655 | extern bool xfs_buf_delwri_queue(struct xfs_buf *, struct list_head *); |
2656 | extern int xfs_buf_delwri_submit(struct list_head *); |
2657 | extern int xfs_buf_delwri_submit_nowait(struct list_head *); |
2658 | diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c |
2659 | index ad9396e516f6..20b7a5c6eb2f 100644 |
2660 | --- a/fs/xfs/xfs_dir2_readdir.c |
2661 | +++ b/fs/xfs/xfs_dir2_readdir.c |
2662 | @@ -394,6 +394,7 @@ xfs_dir2_leaf_readbuf( |
2663 | |
2664 | /* |
2665 | * Do we need more readahead? |
2666 | + * Each loop tries to process 1 full dir blk; last may be partial. |
2667 | */ |
2668 | blk_start_plug(&plug); |
2669 | for (mip->ra_index = mip->ra_offset = i = 0; |
2670 | @@ -404,7 +405,8 @@ xfs_dir2_leaf_readbuf( |
2671 | * Read-ahead a contiguous directory block. |
2672 | */ |
2673 | if (i > mip->ra_current && |
2674 | - map[mip->ra_index].br_blockcount >= geo->fsbcount) { |
2675 | + (map[mip->ra_index].br_blockcount - mip->ra_offset) >= |
2676 | + geo->fsbcount) { |
2677 | xfs_dir3_data_readahead(dp, |
2678 | map[mip->ra_index].br_startoff + mip->ra_offset, |
2679 | XFS_FSB_TO_DADDR(dp->i_mount, |
2680 | @@ -425,14 +427,19 @@ xfs_dir2_leaf_readbuf( |
2681 | } |
2682 | |
2683 | /* |
2684 | - * Advance offset through the mapping table. |
2685 | + * Advance offset through the mapping table, processing a full |
2686 | + * dir block even if it is fragmented into several extents. |
2687 | + * But stop if we have consumed all valid mappings, even if |
2688 | + * it's not yet a full directory block. |
2689 | */ |
2690 | - for (j = 0; j < geo->fsbcount; j += length ) { |
2691 | + for (j = 0; |
2692 | + j < geo->fsbcount && mip->ra_index < mip->map_valid; |
2693 | + j += length ) { |
2694 | /* |
2695 | * The rest of this extent but not more than a dir |
2696 | * block. |
2697 | */ |
2698 | - length = min_t(int, geo->fsbcount, |
2699 | + length = min_t(int, geo->fsbcount - j, |
2700 | map[mip->ra_index].br_blockcount - |
2701 | mip->ra_offset); |
2702 | mip->ra_offset += length; |
2703 | diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c |
2704 | index 35703a801372..dc0e4cb7029b 100644 |
2705 | --- a/fs/xfs/xfs_file.c |
2706 | +++ b/fs/xfs/xfs_file.c |
2707 | @@ -1043,13 +1043,13 @@ xfs_find_get_desired_pgoff( |
2708 | |
2709 | index = startoff >> PAGE_SHIFT; |
2710 | endoff = XFS_FSB_TO_B(mp, map->br_startoff + map->br_blockcount); |
2711 | - end = endoff >> PAGE_SHIFT; |
2712 | + end = (endoff - 1) >> PAGE_SHIFT; |
2713 | do { |
2714 | int want; |
2715 | unsigned nr_pages; |
2716 | unsigned int i; |
2717 | |
2718 | - want = min_t(pgoff_t, end - index, PAGEVEC_SIZE); |
2719 | + want = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1; |
2720 | nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index, |
2721 | want); |
2722 | /* |
2723 | @@ -1076,17 +1076,6 @@ xfs_find_get_desired_pgoff( |
2724 | break; |
2725 | } |
2726 | |
2727 | - /* |
2728 | - * At lease we found one page. If this is the first time we |
2729 | - * step into the loop, and if the first page index offset is |
2730 | - * greater than the given search offset, a hole was found. |
2731 | - */ |
2732 | - if (type == HOLE_OFF && lastoff == startoff && |
2733 | - lastoff < page_offset(pvec.pages[0])) { |
2734 | - found = true; |
2735 | - break; |
2736 | - } |
2737 | - |
2738 | for (i = 0; i < nr_pages; i++) { |
2739 | struct page *page = pvec.pages[i]; |
2740 | loff_t b_offset; |
2741 | @@ -1098,18 +1087,18 @@ xfs_find_get_desired_pgoff( |
2742 | * file mapping. However, page->index will not change |
2743 | * because we have a reference on the page. |
2744 | * |
2745 | - * Searching done if the page index is out of range. |
2746 | - * If the current offset is not reaches the end of |
2747 | - * the specified search range, there should be a hole |
2748 | - * between them. |
2749 | + * If current page offset is beyond where we've ended, |
2750 | + * we've found a hole. |
2751 | */ |
2752 | - if (page->index > end) { |
2753 | - if (type == HOLE_OFF && lastoff < endoff) { |
2754 | - *offset = lastoff; |
2755 | - found = true; |
2756 | - } |
2757 | + if (type == HOLE_OFF && lastoff < endoff && |
2758 | + lastoff < page_offset(pvec.pages[i])) { |
2759 | + found = true; |
2760 | + *offset = lastoff; |
2761 | goto out; |
2762 | } |
2763 | + /* Searching done if the page index is out of range. */ |
2764 | + if (page->index > end) |
2765 | + goto out; |
2766 | |
2767 | lock_page(page); |
2768 | /* |
2769 | diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c |
2770 | index 3531f8f72fa5..f61c84f8e31a 100644 |
2771 | --- a/fs/xfs/xfs_icache.c |
2772 | +++ b/fs/xfs/xfs_icache.c |
2773 | @@ -262,6 +262,22 @@ xfs_inode_clear_reclaim_tag( |
2774 | xfs_perag_clear_reclaim_tag(pag); |
2775 | } |
2776 | |
2777 | +static void |
2778 | +xfs_inew_wait( |
2779 | + struct xfs_inode *ip) |
2780 | +{ |
2781 | + wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_INEW_BIT); |
2782 | + DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_INEW_BIT); |
2783 | + |
2784 | + do { |
2785 | + prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE); |
2786 | + if (!xfs_iflags_test(ip, XFS_INEW)) |
2787 | + break; |
2788 | + schedule(); |
2789 | + } while (true); |
2790 | + finish_wait(wq, &wait.wait); |
2791 | +} |
2792 | + |
2793 | /* |
2794 | * When we recycle a reclaimable inode, we need to re-initialise the VFS inode |
2795 | * part of the structure. This is made more complex by the fact we store |
2796 | @@ -366,14 +382,17 @@ xfs_iget_cache_hit( |
2797 | |
2798 | error = xfs_reinit_inode(mp, inode); |
2799 | if (error) { |
2800 | + bool wake; |
2801 | /* |
2802 | * Re-initializing the inode failed, and we are in deep |
2803 | * trouble. Try to re-add it to the reclaim list. |
2804 | */ |
2805 | rcu_read_lock(); |
2806 | spin_lock(&ip->i_flags_lock); |
2807 | - |
2808 | + wake = !!__xfs_iflags_test(ip, XFS_INEW); |
2809 | ip->i_flags &= ~(XFS_INEW | XFS_IRECLAIM); |
2810 | + if (wake) |
2811 | + wake_up_bit(&ip->i_flags, __XFS_INEW_BIT); |
2812 | ASSERT(ip->i_flags & XFS_IRECLAIMABLE); |
2813 | trace_xfs_iget_reclaim_fail(ip); |
2814 | goto out_error; |
2815 | @@ -623,9 +642,11 @@ xfs_iget( |
2816 | |
2817 | STATIC int |
2818 | xfs_inode_ag_walk_grab( |
2819 | - struct xfs_inode *ip) |
2820 | + struct xfs_inode *ip, |
2821 | + int flags) |
2822 | { |
2823 | struct inode *inode = VFS_I(ip); |
2824 | + bool newinos = !!(flags & XFS_AGITER_INEW_WAIT); |
2825 | |
2826 | ASSERT(rcu_read_lock_held()); |
2827 | |
2828 | @@ -643,7 +664,8 @@ xfs_inode_ag_walk_grab( |
2829 | goto out_unlock_noent; |
2830 | |
2831 | /* avoid new or reclaimable inodes. Leave for reclaim code to flush */ |
2832 | - if (__xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIMABLE | XFS_IRECLAIM)) |
2833 | + if ((!newinos && __xfs_iflags_test(ip, XFS_INEW)) || |
2834 | + __xfs_iflags_test(ip, XFS_IRECLAIMABLE | XFS_IRECLAIM)) |
2835 | goto out_unlock_noent; |
2836 | spin_unlock(&ip->i_flags_lock); |
2837 | |
2838 | @@ -671,7 +693,8 @@ xfs_inode_ag_walk( |
2839 | void *args), |
2840 | int flags, |
2841 | void *args, |
2842 | - int tag) |
2843 | + int tag, |
2844 | + int iter_flags) |
2845 | { |
2846 | uint32_t first_index; |
2847 | int last_error = 0; |
2848 | @@ -713,7 +736,7 @@ xfs_inode_ag_walk( |
2849 | for (i = 0; i < nr_found; i++) { |
2850 | struct xfs_inode *ip = batch[i]; |
2851 | |
2852 | - if (done || xfs_inode_ag_walk_grab(ip)) |
2853 | + if (done || xfs_inode_ag_walk_grab(ip, iter_flags)) |
2854 | batch[i] = NULL; |
2855 | |
2856 | /* |
2857 | @@ -741,6 +764,9 @@ xfs_inode_ag_walk( |
2858 | for (i = 0; i < nr_found; i++) { |
2859 | if (!batch[i]) |
2860 | continue; |
2861 | + if ((iter_flags & XFS_AGITER_INEW_WAIT) && |
2862 | + xfs_iflags_test(batch[i], XFS_INEW)) |
2863 | + xfs_inew_wait(batch[i]); |
2864 | error = execute(batch[i], flags, args); |
2865 | IRELE(batch[i]); |
2866 | if (error == -EAGAIN) { |
2867 | @@ -820,12 +846,13 @@ xfs_cowblocks_worker( |
2868 | } |
2869 | |
2870 | int |
2871 | -xfs_inode_ag_iterator( |
2872 | +xfs_inode_ag_iterator_flags( |
2873 | struct xfs_mount *mp, |
2874 | int (*execute)(struct xfs_inode *ip, int flags, |
2875 | void *args), |
2876 | int flags, |
2877 | - void *args) |
2878 | + void *args, |
2879 | + int iter_flags) |
2880 | { |
2881 | struct xfs_perag *pag; |
2882 | int error = 0; |
2883 | @@ -835,7 +862,8 @@ xfs_inode_ag_iterator( |
2884 | ag = 0; |
2885 | while ((pag = xfs_perag_get(mp, ag))) { |
2886 | ag = pag->pag_agno + 1; |
2887 | - error = xfs_inode_ag_walk(mp, pag, execute, flags, args, -1); |
2888 | + error = xfs_inode_ag_walk(mp, pag, execute, flags, args, -1, |
2889 | + iter_flags); |
2890 | xfs_perag_put(pag); |
2891 | if (error) { |
2892 | last_error = error; |
2893 | @@ -847,6 +875,17 @@ xfs_inode_ag_iterator( |
2894 | } |
2895 | |
2896 | int |
2897 | +xfs_inode_ag_iterator( |
2898 | + struct xfs_mount *mp, |
2899 | + int (*execute)(struct xfs_inode *ip, int flags, |
2900 | + void *args), |
2901 | + int flags, |
2902 | + void *args) |
2903 | +{ |
2904 | + return xfs_inode_ag_iterator_flags(mp, execute, flags, args, 0); |
2905 | +} |
2906 | + |
2907 | +int |
2908 | xfs_inode_ag_iterator_tag( |
2909 | struct xfs_mount *mp, |
2910 | int (*execute)(struct xfs_inode *ip, int flags, |
2911 | @@ -863,7 +902,8 @@ xfs_inode_ag_iterator_tag( |
2912 | ag = 0; |
2913 | while ((pag = xfs_perag_get_tag(mp, ag, tag))) { |
2914 | ag = pag->pag_agno + 1; |
2915 | - error = xfs_inode_ag_walk(mp, pag, execute, flags, args, tag); |
2916 | + error = xfs_inode_ag_walk(mp, pag, execute, flags, args, tag, |
2917 | + 0); |
2918 | xfs_perag_put(pag); |
2919 | if (error) { |
2920 | last_error = error; |
2921 | diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h |
2922 | index 8a7c849b4dea..9183f77958ef 100644 |
2923 | --- a/fs/xfs/xfs_icache.h |
2924 | +++ b/fs/xfs/xfs_icache.h |
2925 | @@ -48,6 +48,11 @@ struct xfs_eofblocks { |
2926 | #define XFS_IGET_UNTRUSTED 0x2 |
2927 | #define XFS_IGET_DONTCACHE 0x4 |
2928 | |
2929 | +/* |
2930 | + * flags for AG inode iterator |
2931 | + */ |
2932 | +#define XFS_AGITER_INEW_WAIT 0x1 /* wait on new inodes */ |
2933 | + |
2934 | int xfs_iget(struct xfs_mount *mp, struct xfs_trans *tp, xfs_ino_t ino, |
2935 | uint flags, uint lock_flags, xfs_inode_t **ipp); |
2936 | |
2937 | @@ -79,6 +84,9 @@ void xfs_cowblocks_worker(struct work_struct *); |
2938 | int xfs_inode_ag_iterator(struct xfs_mount *mp, |
2939 | int (*execute)(struct xfs_inode *ip, int flags, void *args), |
2940 | int flags, void *args); |
2941 | +int xfs_inode_ag_iterator_flags(struct xfs_mount *mp, |
2942 | + int (*execute)(struct xfs_inode *ip, int flags, void *args), |
2943 | + int flags, void *args, int iter_flags); |
2944 | int xfs_inode_ag_iterator_tag(struct xfs_mount *mp, |
2945 | int (*execute)(struct xfs_inode *ip, int flags, void *args), |
2946 | int flags, void *args, int tag); |
2947 | diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c |
2948 | index 7605d8396596..ec9826c56500 100644 |
2949 | --- a/fs/xfs/xfs_inode.c |
2950 | +++ b/fs/xfs/xfs_inode.c |
2951 | @@ -1906,12 +1906,13 @@ xfs_inactive( |
2952 | * force is true because we are evicting an inode from the |
2953 | * cache. Post-eof blocks must be freed, lest we end up with |
2954 | * broken free space accounting. |
2955 | + * |
2956 | + * Note: don't bother with iolock here since lockdep complains |
2957 | + * about acquiring it in reclaim context. We have the only |
2958 | + * reference to the inode at this point anyways. |
2959 | */ |
2960 | - if (xfs_can_free_eofblocks(ip, true)) { |
2961 | - xfs_ilock(ip, XFS_IOLOCK_EXCL); |
2962 | + if (xfs_can_free_eofblocks(ip, true)) |
2963 | xfs_free_eofblocks(ip); |
2964 | - xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
2965 | - } |
2966 | |
2967 | return; |
2968 | } |
2969 | diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h |
2970 | index 10dcf27b4c85..10e89fcb49d7 100644 |
2971 | --- a/fs/xfs/xfs_inode.h |
2972 | +++ b/fs/xfs/xfs_inode.h |
2973 | @@ -216,7 +216,8 @@ static inline bool xfs_is_reflink_inode(struct xfs_inode *ip) |
2974 | #define XFS_IRECLAIM (1 << 0) /* started reclaiming this inode */ |
2975 | #define XFS_ISTALE (1 << 1) /* inode has been staled */ |
2976 | #define XFS_IRECLAIMABLE (1 << 2) /* inode can be reclaimed */ |
2977 | -#define XFS_INEW (1 << 3) /* inode has just been allocated */ |
2978 | +#define __XFS_INEW_BIT 3 /* inode has just been allocated */ |
2979 | +#define XFS_INEW (1 << __XFS_INEW_BIT) |
2980 | #define XFS_ITRUNCATED (1 << 5) /* truncated down so flush-on-close */ |
2981 | #define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */ |
2982 | #define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */ |
2983 | @@ -464,6 +465,7 @@ static inline void xfs_finish_inode_setup(struct xfs_inode *ip) |
2984 | xfs_iflags_clear(ip, XFS_INEW); |
2985 | barrier(); |
2986 | unlock_new_inode(VFS_I(ip)); |
2987 | + wake_up_bit(&ip->i_flags, __XFS_INEW_BIT); |
2988 | } |
2989 | |
2990 | static inline void xfs_setup_existing_inode(struct xfs_inode *ip) |
2991 | diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c |
2992 | index 2fd7fdf5438f..6d30b06e79bc 100644 |
2993 | --- a/fs/xfs/xfs_ioctl.c |
2994 | +++ b/fs/xfs/xfs_ioctl.c |
2995 | @@ -1543,10 +1543,11 @@ xfs_ioc_getbmap( |
2996 | unsigned int cmd, |
2997 | void __user *arg) |
2998 | { |
2999 | - struct getbmapx bmx; |
3000 | + struct getbmapx bmx = { 0 }; |
3001 | int error; |
3002 | |
3003 | - if (copy_from_user(&bmx, arg, sizeof(struct getbmapx))) |
3004 | + /* struct getbmap is a strict subset of struct getbmapx. */ |
3005 | + if (copy_from_user(&bmx, arg, offsetof(struct getbmapx, bmv_iflags))) |
3006 | return -EFAULT; |
3007 | |
3008 | if (bmx.bmv_count < 2) |
3009 | diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c |
3010 | index 288ee5b840d7..79e6dfac3dd6 100644 |
3011 | --- a/fs/xfs/xfs_iomap.c |
3012 | +++ b/fs/xfs/xfs_iomap.c |
3013 | @@ -1170,10 +1170,10 @@ xfs_xattr_iomap_begin( |
3014 | if (XFS_FORCED_SHUTDOWN(mp)) |
3015 | return -EIO; |
3016 | |
3017 | - lockmode = xfs_ilock_data_map_shared(ip); |
3018 | + lockmode = xfs_ilock_attr_map_shared(ip); |
3019 | |
3020 | /* if there are no attribute fork or extents, return ENOENT */ |
3021 | - if (XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) { |
3022 | + if (!XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) { |
3023 | error = -ENOENT; |
3024 | goto out_unlock; |
3025 | } |
3026 | diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c |
3027 | index b1469f0a91a6..bb58cd1873c9 100644 |
3028 | --- a/fs/xfs/xfs_log.c |
3029 | +++ b/fs/xfs/xfs_log.c |
3030 | @@ -1293,7 +1293,7 @@ void |
3031 | xfs_log_work_queue( |
3032 | struct xfs_mount *mp) |
3033 | { |
3034 | - queue_delayed_work(mp->m_log_workqueue, &mp->m_log->l_work, |
3035 | + queue_delayed_work(mp->m_sync_workqueue, &mp->m_log->l_work, |
3036 | msecs_to_jiffies(xfs_syncd_centisecs * 10)); |
3037 | } |
3038 | |
3039 | diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h |
3040 | index 6db6fd6b82b0..22b2185e93a0 100644 |
3041 | --- a/fs/xfs/xfs_mount.h |
3042 | +++ b/fs/xfs/xfs_mount.h |
3043 | @@ -183,6 +183,7 @@ typedef struct xfs_mount { |
3044 | struct workqueue_struct *m_reclaim_workqueue; |
3045 | struct workqueue_struct *m_log_workqueue; |
3046 | struct workqueue_struct *m_eofblocks_workqueue; |
3047 | + struct workqueue_struct *m_sync_workqueue; |
3048 | |
3049 | /* |
3050 | * Generation of the filesysyem layout. This is incremented by each |
3051 | diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c |
3052 | index b669b123287b..8b9a9f15f022 100644 |
3053 | --- a/fs/xfs/xfs_qm.c |
3054 | +++ b/fs/xfs/xfs_qm.c |
3055 | @@ -1384,12 +1384,7 @@ xfs_qm_quotacheck( |
3056 | mp->m_qflags |= flags; |
3057 | |
3058 | error_return: |
3059 | - while (!list_empty(&buffer_list)) { |
3060 | - struct xfs_buf *bp = |
3061 | - list_first_entry(&buffer_list, struct xfs_buf, b_list); |
3062 | - list_del_init(&bp->b_list); |
3063 | - xfs_buf_relse(bp); |
3064 | - } |
3065 | + xfs_buf_delwri_cancel(&buffer_list); |
3066 | |
3067 | if (error) { |
3068 | xfs_warn(mp, |
3069 | diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c |
3070 | index 475a3882a81f..9cb5c381b01c 100644 |
3071 | --- a/fs/xfs/xfs_qm_syscalls.c |
3072 | +++ b/fs/xfs/xfs_qm_syscalls.c |
3073 | @@ -759,5 +759,6 @@ xfs_qm_dqrele_all_inodes( |
3074 | uint flags) |
3075 | { |
3076 | ASSERT(mp->m_quotainfo); |
3077 | - xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, NULL); |
3078 | + xfs_inode_ag_iterator_flags(mp, xfs_dqrele_inode, flags, NULL, |
3079 | + XFS_AGITER_INEW_WAIT); |
3080 | } |
3081 | diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c |
3082 | index 4a84c5ea266d..20c46d2ff4f5 100644 |
3083 | --- a/fs/xfs/xfs_reflink.c |
3084 | +++ b/fs/xfs/xfs_reflink.c |
3085 | @@ -709,8 +709,22 @@ xfs_reflink_end_cow( |
3086 | offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset); |
3087 | end_fsb = XFS_B_TO_FSB(ip->i_mount, offset + count); |
3088 | |
3089 | - /* Start a rolling transaction to switch the mappings */ |
3090 | - resblks = XFS_EXTENTADD_SPACE_RES(ip->i_mount, XFS_DATA_FORK); |
3091 | + /* |
3092 | + * Start a rolling transaction to switch the mappings. We're |
3093 | + * unlikely ever to have to remap 16T worth of single-block |
3094 | + * extents, so just cap the worst case extent count to 2^32-1. |
3095 | + * Stick a warning in just in case, and avoid 64-bit division. |
3096 | + */ |
3097 | + BUILD_BUG_ON(MAX_RW_COUNT > UINT_MAX); |
3098 | + if (end_fsb - offset_fsb > UINT_MAX) { |
3099 | + error = -EFSCORRUPTED; |
3100 | + xfs_force_shutdown(ip->i_mount, SHUTDOWN_CORRUPT_INCORE); |
3101 | + ASSERT(0); |
3102 | + goto out; |
3103 | + } |
3104 | + resblks = XFS_NEXTENTADD_SPACE_RES(ip->i_mount, |
3105 | + (unsigned int)(end_fsb - offset_fsb), |
3106 | + XFS_DATA_FORK); |
3107 | error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write, |
3108 | resblks, 0, 0, &tp); |
3109 | if (error) |
3110 | diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c |
3111 | index 685c042a120f..47d239dcf3f4 100644 |
3112 | --- a/fs/xfs/xfs_super.c |
3113 | +++ b/fs/xfs/xfs_super.c |
3114 | @@ -877,8 +877,15 @@ xfs_init_mount_workqueues( |
3115 | if (!mp->m_eofblocks_workqueue) |
3116 | goto out_destroy_log; |
3117 | |
3118 | + mp->m_sync_workqueue = alloc_workqueue("xfs-sync/%s", WQ_FREEZABLE, 0, |
3119 | + mp->m_fsname); |
3120 | + if (!mp->m_sync_workqueue) |
3121 | + goto out_destroy_eofb; |
3122 | + |
3123 | return 0; |
3124 | |
3125 | +out_destroy_eofb: |
3126 | + destroy_workqueue(mp->m_eofblocks_workqueue); |
3127 | out_destroy_log: |
3128 | destroy_workqueue(mp->m_log_workqueue); |
3129 | out_destroy_reclaim: |
3130 | @@ -899,6 +906,7 @@ STATIC void |
3131 | xfs_destroy_mount_workqueues( |
3132 | struct xfs_mount *mp) |
3133 | { |
3134 | + destroy_workqueue(mp->m_sync_workqueue); |
3135 | destroy_workqueue(mp->m_eofblocks_workqueue); |
3136 | destroy_workqueue(mp->m_log_workqueue); |
3137 | destroy_workqueue(mp->m_reclaim_workqueue); |
3138 | diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c |
3139 | index 70f42ea86dfb..a280e126491f 100644 |
3140 | --- a/fs/xfs/xfs_trans.c |
3141 | +++ b/fs/xfs/xfs_trans.c |
3142 | @@ -263,6 +263,28 @@ xfs_trans_alloc( |
3143 | } |
3144 | |
3145 | /* |
3146 | + * Create an empty transaction with no reservation. This is a defensive |
3147 | + * mechanism for routines that query metadata without actually modifying |
3148 | + * them -- if the metadata being queried is somehow cross-linked (think a |
3149 | + * btree block pointer that points higher in the tree), we risk deadlock. |
3150 | + * However, blocks grabbed as part of a transaction can be re-grabbed. |
3151 | + * The verifiers will notice the corrupt block and the operation will fail |
3152 | + * back to userspace without deadlocking. |
3153 | + * |
3154 | + * Note the zero-length reservation; this transaction MUST be cancelled |
3155 | + * without any dirty data. |
3156 | + */ |
3157 | +int |
3158 | +xfs_trans_alloc_empty( |
3159 | + struct xfs_mount *mp, |
3160 | + struct xfs_trans **tpp) |
3161 | +{ |
3162 | + struct xfs_trans_res resv = {0}; |
3163 | + |
3164 | + return xfs_trans_alloc(mp, &resv, 0, 0, XFS_TRANS_NO_WRITECOUNT, tpp); |
3165 | +} |
3166 | + |
3167 | +/* |
3168 | * Record the indicated change to the given field for application |
3169 | * to the file system's superblock when the transaction commits. |
3170 | * For now, just store the change in the transaction structure. |
3171 | diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h |
3172 | index 1646f659b60f..2a9292df6640 100644 |
3173 | --- a/fs/xfs/xfs_trans.h |
3174 | +++ b/fs/xfs/xfs_trans.h |
3175 | @@ -158,6 +158,8 @@ typedef struct xfs_trans { |
3176 | int xfs_trans_alloc(struct xfs_mount *mp, struct xfs_trans_res *resp, |
3177 | uint blocks, uint rtextents, uint flags, |
3178 | struct xfs_trans **tpp); |
3179 | +int xfs_trans_alloc_empty(struct xfs_mount *mp, |
3180 | + struct xfs_trans **tpp); |
3181 | void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); |
3182 | |
3183 | struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp, |
3184 | diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h |
3185 | index 8d5fcd6284ce..283dc2f5364d 100644 |
3186 | --- a/include/linux/if_vlan.h |
3187 | +++ b/include/linux/if_vlan.h |
3188 | @@ -614,14 +614,16 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb) |
3189 | static inline netdev_features_t vlan_features_check(const struct sk_buff *skb, |
3190 | netdev_features_t features) |
3191 | { |
3192 | - if (skb_vlan_tagged_multi(skb)) |
3193 | - features = netdev_intersect_features(features, |
3194 | - NETIF_F_SG | |
3195 | - NETIF_F_HIGHDMA | |
3196 | - NETIF_F_FRAGLIST | |
3197 | - NETIF_F_HW_CSUM | |
3198 | - NETIF_F_HW_VLAN_CTAG_TX | |
3199 | - NETIF_F_HW_VLAN_STAG_TX); |
3200 | + if (skb_vlan_tagged_multi(skb)) { |
3201 | + /* In the case of multi-tagged packets, use a direct mask |
3202 | + * instead of using netdev_interesect_features(), to make |
3203 | + * sure that only devices supporting NETIF_F_HW_CSUM will |
3204 | + * have checksum offloading support. |
3205 | + */ |
3206 | + features &= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | |
3207 | + NETIF_F_FRAGLIST | NETIF_F_HW_VLAN_CTAG_TX | |
3208 | + NETIF_F_HW_VLAN_STAG_TX; |
3209 | + } |
3210 | |
3211 | return features; |
3212 | } |
3213 | diff --git a/include/linux/memblock.h b/include/linux/memblock.h |
3214 | index bdfc65af4152..14dbc4fd0a92 100644 |
3215 | --- a/include/linux/memblock.h |
3216 | +++ b/include/linux/memblock.h |
3217 | @@ -423,12 +423,20 @@ static inline void early_memtest(phys_addr_t start, phys_addr_t end) |
3218 | } |
3219 | #endif |
3220 | |
3221 | +extern unsigned long memblock_reserved_memory_within(phys_addr_t start_addr, |
3222 | + phys_addr_t end_addr); |
3223 | #else |
3224 | static inline phys_addr_t memblock_alloc(phys_addr_t size, phys_addr_t align) |
3225 | { |
3226 | return 0; |
3227 | } |
3228 | |
3229 | +static inline unsigned long memblock_reserved_memory_within(phys_addr_t start_addr, |
3230 | + phys_addr_t end_addr) |
3231 | +{ |
3232 | + return 0; |
3233 | +} |
3234 | + |
3235 | #endif /* CONFIG_HAVE_MEMBLOCK */ |
3236 | |
3237 | #endif /* __KERNEL__ */ |
3238 | diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h |
3239 | index 2fcff6b4503f..c965d1165df6 100644 |
3240 | --- a/include/linux/mlx5/driver.h |
3241 | +++ b/include/linux/mlx5/driver.h |
3242 | @@ -785,7 +785,12 @@ enum { |
3243 | |
3244 | typedef void (*mlx5_cmd_cbk_t)(int status, void *context); |
3245 | |
3246 | +enum { |
3247 | + MLX5_CMD_ENT_STATE_PENDING_COMP, |
3248 | +}; |
3249 | + |
3250 | struct mlx5_cmd_work_ent { |
3251 | + unsigned long state; |
3252 | struct mlx5_cmd_msg *in; |
3253 | struct mlx5_cmd_msg *out; |
3254 | void *uout; |
3255 | @@ -979,7 +984,7 @@ void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn); |
3256 | void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type); |
3257 | void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type); |
3258 | struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn); |
3259 | -void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec); |
3260 | +void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced); |
3261 | void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type); |
3262 | int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx, |
3263 | int nent, u64 mask, const char *name, |
3264 | diff --git a/include/linux/mm.h b/include/linux/mm.h |
3265 | index 00a8fa7e366a..018b134f6427 100644 |
3266 | --- a/include/linux/mm.h |
3267 | +++ b/include/linux/mm.h |
3268 | @@ -2315,6 +2315,17 @@ static inline struct page *follow_page(struct vm_area_struct *vma, |
3269 | #define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */ |
3270 | #define FOLL_COW 0x4000 /* internal GUP flag */ |
3271 | |
3272 | +static inline int vm_fault_to_errno(int vm_fault, int foll_flags) |
3273 | +{ |
3274 | + if (vm_fault & VM_FAULT_OOM) |
3275 | + return -ENOMEM; |
3276 | + if (vm_fault & (VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)) |
3277 | + return (foll_flags & FOLL_HWPOISON) ? -EHWPOISON : -EFAULT; |
3278 | + if (vm_fault & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) |
3279 | + return -EFAULT; |
3280 | + return 0; |
3281 | +} |
3282 | + |
3283 | typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, |
3284 | void *data); |
3285 | extern int apply_to_page_range(struct mm_struct *mm, unsigned long address, |
3286 | diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h |
3287 | index d45172b559d8..a3e9b7ba2c25 100644 |
3288 | --- a/include/linux/mmzone.h |
3289 | +++ b/include/linux/mmzone.h |
3290 | @@ -672,6 +672,7 @@ typedef struct pglist_data { |
3291 | * is the first PFN that needs to be initialised. |
3292 | */ |
3293 | unsigned long first_deferred_pfn; |
3294 | + unsigned long static_init_size; |
3295 | #endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */ |
3296 | |
3297 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
3298 | diff --git a/include/net/dst.h b/include/net/dst.h |
3299 | index 049af33da3b6..cfc043784166 100644 |
3300 | --- a/include/net/dst.h |
3301 | +++ b/include/net/dst.h |
3302 | @@ -107,10 +107,16 @@ struct dst_entry { |
3303 | }; |
3304 | }; |
3305 | |
3306 | +struct dst_metrics { |
3307 | + u32 metrics[RTAX_MAX]; |
3308 | + atomic_t refcnt; |
3309 | +}; |
3310 | +extern const struct dst_metrics dst_default_metrics; |
3311 | + |
3312 | u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old); |
3313 | -extern const u32 dst_default_metrics[]; |
3314 | |
3315 | #define DST_METRICS_READ_ONLY 0x1UL |
3316 | +#define DST_METRICS_REFCOUNTED 0x2UL |
3317 | #define DST_METRICS_FLAGS 0x3UL |
3318 | #define __DST_METRICS_PTR(Y) \ |
3319 | ((u32 *)((Y) & ~DST_METRICS_FLAGS)) |
3320 | diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h |
3321 | index 368bb4024b78..892f8dccc835 100644 |
3322 | --- a/include/net/ip_fib.h |
3323 | +++ b/include/net/ip_fib.h |
3324 | @@ -114,11 +114,11 @@ struct fib_info { |
3325 | __be32 fib_prefsrc; |
3326 | u32 fib_tb_id; |
3327 | u32 fib_priority; |
3328 | - u32 *fib_metrics; |
3329 | -#define fib_mtu fib_metrics[RTAX_MTU-1] |
3330 | -#define fib_window fib_metrics[RTAX_WINDOW-1] |
3331 | -#define fib_rtt fib_metrics[RTAX_RTT-1] |
3332 | -#define fib_advmss fib_metrics[RTAX_ADVMSS-1] |
3333 | + struct dst_metrics *fib_metrics; |
3334 | +#define fib_mtu fib_metrics->metrics[RTAX_MTU-1] |
3335 | +#define fib_window fib_metrics->metrics[RTAX_WINDOW-1] |
3336 | +#define fib_rtt fib_metrics->metrics[RTAX_RTT-1] |
3337 | +#define fib_advmss fib_metrics->metrics[RTAX_ADVMSS-1] |
3338 | int fib_nhs; |
3339 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
3340 | int fib_weight; |
3341 | diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h |
3342 | index 275581d483dd..5f17fb770477 100644 |
3343 | --- a/include/target/iscsi/iscsi_target_core.h |
3344 | +++ b/include/target/iscsi/iscsi_target_core.h |
3345 | @@ -557,6 +557,7 @@ struct iscsi_conn { |
3346 | #define LOGIN_FLAGS_READ_ACTIVE 1 |
3347 | #define LOGIN_FLAGS_CLOSED 2 |
3348 | #define LOGIN_FLAGS_READY 4 |
3349 | +#define LOGIN_FLAGS_INITIAL_PDU 8 |
3350 | unsigned long login_flags; |
3351 | struct delayed_work login_work; |
3352 | struct delayed_work login_cleanup_work; |
3353 | diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c |
3354 | index 6b6f41f0b211..892f47c28377 100644 |
3355 | --- a/kernel/bpf/arraymap.c |
3356 | +++ b/kernel/bpf/arraymap.c |
3357 | @@ -83,6 +83,7 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) |
3358 | array->map.key_size = attr->key_size; |
3359 | array->map.value_size = attr->value_size; |
3360 | array->map.max_entries = attr->max_entries; |
3361 | + array->map.map_flags = attr->map_flags; |
3362 | array->elem_size = elem_size; |
3363 | |
3364 | if (!percpu) |
3365 | diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c |
3366 | index b37bd9ab7f57..7ab9e42180ab 100644 |
3367 | --- a/kernel/bpf/lpm_trie.c |
3368 | +++ b/kernel/bpf/lpm_trie.c |
3369 | @@ -432,6 +432,7 @@ static struct bpf_map *trie_alloc(union bpf_attr *attr) |
3370 | trie->map.key_size = attr->key_size; |
3371 | trie->map.value_size = attr->value_size; |
3372 | trie->map.max_entries = attr->max_entries; |
3373 | + trie->map.map_flags = attr->map_flags; |
3374 | trie->data_size = attr->key_size - |
3375 | offsetof(struct bpf_lpm_trie_key, data); |
3376 | trie->max_prefixlen = trie->data_size * 8; |
3377 | diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c |
3378 | index 22aa45cd0324..96f604317685 100644 |
3379 | --- a/kernel/bpf/stackmap.c |
3380 | +++ b/kernel/bpf/stackmap.c |
3381 | @@ -88,6 +88,7 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) |
3382 | smap->map.key_size = attr->key_size; |
3383 | smap->map.value_size = value_size; |
3384 | smap->map.max_entries = attr->max_entries; |
3385 | + smap->map.map_flags = attr->map_flags; |
3386 | smap->n_buckets = n_buckets; |
3387 | smap->map.pages = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT; |
3388 | |
3389 | diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c |
3390 | index 6fd78d4c4164..904decd32783 100644 |
3391 | --- a/kernel/bpf/verifier.c |
3392 | +++ b/kernel/bpf/verifier.c |
3393 | @@ -140,7 +140,7 @@ struct bpf_verifier_stack_elem { |
3394 | struct bpf_verifier_stack_elem *next; |
3395 | }; |
3396 | |
3397 | -#define BPF_COMPLEXITY_LIMIT_INSNS 65536 |
3398 | +#define BPF_COMPLEXITY_LIMIT_INSNS 98304 |
3399 | #define BPF_COMPLEXITY_LIMIT_STACK 1024 |
3400 | |
3401 | struct bpf_call_arg_meta { |
3402 | @@ -2546,6 +2546,7 @@ static int check_cfg(struct bpf_verifier_env *env) |
3403 | env->explored_states[t + 1] = STATE_LIST_MARK; |
3404 | } else { |
3405 | /* conditional jump with two edges */ |
3406 | + env->explored_states[t] = STATE_LIST_MARK; |
3407 | ret = push_insn(t, t + 1, FALLTHROUGH, env); |
3408 | if (ret == 1) |
3409 | goto peek_stack; |
3410 | @@ -2704,6 +2705,12 @@ static bool states_equal(struct bpf_verifier_env *env, |
3411 | rcur->type != NOT_INIT)) |
3412 | continue; |
3413 | |
3414 | + /* Don't care about the reg->id in this case. */ |
3415 | + if (rold->type == PTR_TO_MAP_VALUE_OR_NULL && |
3416 | + rcur->type == PTR_TO_MAP_VALUE_OR_NULL && |
3417 | + rold->map_ptr == rcur->map_ptr) |
3418 | + continue; |
3419 | + |
3420 | if (rold->type == PTR_TO_PACKET && rcur->type == PTR_TO_PACKET && |
3421 | compare_ptrs_to_packet(rold, rcur)) |
3422 | continue; |
3423 | @@ -2838,6 +2845,9 @@ static int do_check(struct bpf_verifier_env *env) |
3424 | goto process_bpf_exit; |
3425 | } |
3426 | |
3427 | + if (need_resched()) |
3428 | + cond_resched(); |
3429 | + |
3430 | if (log_level && do_print_state) { |
3431 | verbose("\nfrom %d to %d:", prev_insn_idx, insn_idx); |
3432 | print_verifier_state(&env->cur_state); |
3433 | diff --git a/mm/gup.c b/mm/gup.c |
3434 | index 04aa405350dc..fb87cbf37e52 100644 |
3435 | --- a/mm/gup.c |
3436 | +++ b/mm/gup.c |
3437 | @@ -407,12 +407,10 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, |
3438 | |
3439 | ret = handle_mm_fault(vma, address, fault_flags); |
3440 | if (ret & VM_FAULT_ERROR) { |
3441 | - if (ret & VM_FAULT_OOM) |
3442 | - return -ENOMEM; |
3443 | - if (ret & (VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)) |
3444 | - return *flags & FOLL_HWPOISON ? -EHWPOISON : -EFAULT; |
3445 | - if (ret & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) |
3446 | - return -EFAULT; |
3447 | + int err = vm_fault_to_errno(ret, *flags); |
3448 | + |
3449 | + if (err) |
3450 | + return err; |
3451 | BUG(); |
3452 | } |
3453 | |
3454 | @@ -723,12 +721,10 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, |
3455 | ret = handle_mm_fault(vma, address, fault_flags); |
3456 | major |= ret & VM_FAULT_MAJOR; |
3457 | if (ret & VM_FAULT_ERROR) { |
3458 | - if (ret & VM_FAULT_OOM) |
3459 | - return -ENOMEM; |
3460 | - if (ret & (VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)) |
3461 | - return -EHWPOISON; |
3462 | - if (ret & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) |
3463 | - return -EFAULT; |
3464 | + int err = vm_fault_to_errno(ret, 0); |
3465 | + |
3466 | + if (err) |
3467 | + return err; |
3468 | BUG(); |
3469 | } |
3470 | |
3471 | diff --git a/mm/hugetlb.c b/mm/hugetlb.c |
3472 | index e5828875f7bb..3eedb187e549 100644 |
3473 | --- a/mm/hugetlb.c |
3474 | +++ b/mm/hugetlb.c |
3475 | @@ -4170,6 +4170,11 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, |
3476 | } |
3477 | ret = hugetlb_fault(mm, vma, vaddr, fault_flags); |
3478 | if (ret & VM_FAULT_ERROR) { |
3479 | + int err = vm_fault_to_errno(ret, flags); |
3480 | + |
3481 | + if (err) |
3482 | + return err; |
3483 | + |
3484 | remainder = 0; |
3485 | break; |
3486 | } |
3487 | diff --git a/mm/ksm.c b/mm/ksm.c |
3488 | index 19b4f2dea7a5..11891ca81e40 100644 |
3489 | --- a/mm/ksm.c |
3490 | +++ b/mm/ksm.c |
3491 | @@ -1028,8 +1028,7 @@ static int try_to_merge_one_page(struct vm_area_struct *vma, |
3492 | goto out; |
3493 | |
3494 | if (PageTransCompound(page)) { |
3495 | - err = split_huge_page(page); |
3496 | - if (err) |
3497 | + if (split_huge_page(page)) |
3498 | goto out_unlock; |
3499 | } |
3500 | |
3501 | diff --git a/mm/memblock.c b/mm/memblock.c |
3502 | index 696f06d17c4e..a749101ed2a2 100644 |
3503 | --- a/mm/memblock.c |
3504 | +++ b/mm/memblock.c |
3505 | @@ -1713,6 +1713,29 @@ static void __init_memblock memblock_dump(struct memblock_type *type) |
3506 | } |
3507 | } |
3508 | |
3509 | +extern unsigned long __init_memblock |
3510 | +memblock_reserved_memory_within(phys_addr_t start_addr, phys_addr_t end_addr) |
3511 | +{ |
3512 | + struct memblock_region *rgn; |
3513 | + unsigned long size = 0; |
3514 | + int idx; |
3515 | + |
3516 | + for_each_memblock_type((&memblock.reserved), rgn) { |
3517 | + phys_addr_t start, end; |
3518 | + |
3519 | + if (rgn->base + rgn->size < start_addr) |
3520 | + continue; |
3521 | + if (rgn->base > end_addr) |
3522 | + continue; |
3523 | + |
3524 | + start = rgn->base; |
3525 | + end = start + rgn->size; |
3526 | + size += end - start; |
3527 | + } |
3528 | + |
3529 | + return size; |
3530 | +} |
3531 | + |
3532 | void __init_memblock __memblock_dump_all(void) |
3533 | { |
3534 | pr_info("MEMBLOCK configuration:\n"); |
3535 | diff --git a/mm/memory-failure.c b/mm/memory-failure.c |
3536 | index 27f7210e7fab..d7780dfdf541 100644 |
3537 | --- a/mm/memory-failure.c |
3538 | +++ b/mm/memory-failure.c |
3539 | @@ -1587,12 +1587,8 @@ static int soft_offline_huge_page(struct page *page, int flags) |
3540 | if (ret) { |
3541 | pr_info("soft offline: %#lx: migration failed %d, type %lx\n", |
3542 | pfn, ret, page->flags); |
3543 | - /* |
3544 | - * We know that soft_offline_huge_page() tries to migrate |
3545 | - * only one hugepage pointed to by hpage, so we need not |
3546 | - * run through the pagelist here. |
3547 | - */ |
3548 | - putback_active_hugepage(hpage); |
3549 | + if (!list_empty(&pagelist)) |
3550 | + putback_movable_pages(&pagelist); |
3551 | if (ret > 0) |
3552 | ret = -EIO; |
3553 | } else { |
3554 | diff --git a/mm/memory.c b/mm/memory.c |
3555 | index 235ba51b2fbf..2437dc08ab36 100644 |
3556 | --- a/mm/memory.c |
3557 | +++ b/mm/memory.c |
3558 | @@ -3029,6 +3029,17 @@ static int __do_fault(struct vm_fault *vmf) |
3559 | return ret; |
3560 | } |
3561 | |
3562 | +/* |
3563 | + * The ordering of these checks is important for pmds with _PAGE_DEVMAP set. |
3564 | + * If we check pmd_trans_unstable() first we will trip the bad_pmd() check |
3565 | + * inside of pmd_none_or_trans_huge_or_clear_bad(). This will end up correctly |
3566 | + * returning 1 but not before it spams dmesg with the pmd_clear_bad() output. |
3567 | + */ |
3568 | +static int pmd_devmap_trans_unstable(pmd_t *pmd) |
3569 | +{ |
3570 | + return pmd_devmap(*pmd) || pmd_trans_unstable(pmd); |
3571 | +} |
3572 | + |
3573 | static int pte_alloc_one_map(struct vm_fault *vmf) |
3574 | { |
3575 | struct vm_area_struct *vma = vmf->vma; |
3576 | @@ -3052,18 +3063,27 @@ static int pte_alloc_one_map(struct vm_fault *vmf) |
3577 | map_pte: |
3578 | /* |
3579 | * If a huge pmd materialized under us just retry later. Use |
3580 | - * pmd_trans_unstable() instead of pmd_trans_huge() to ensure the pmd |
3581 | - * didn't become pmd_trans_huge under us and then back to pmd_none, as |
3582 | - * a result of MADV_DONTNEED running immediately after a huge pmd fault |
3583 | - * in a different thread of this mm, in turn leading to a misleading |
3584 | - * pmd_trans_huge() retval. All we have to ensure is that it is a |
3585 | - * regular pmd that we can walk with pte_offset_map() and we can do that |
3586 | - * through an atomic read in C, which is what pmd_trans_unstable() |
3587 | - * provides. |
3588 | + * pmd_trans_unstable() via pmd_devmap_trans_unstable() instead of |
3589 | + * pmd_trans_huge() to ensure the pmd didn't become pmd_trans_huge |
3590 | + * under us and then back to pmd_none, as a result of MADV_DONTNEED |
3591 | + * running immediately after a huge pmd fault in a different thread of |
3592 | + * this mm, in turn leading to a misleading pmd_trans_huge() retval. |
3593 | + * All we have to ensure is that it is a regular pmd that we can walk |
3594 | + * with pte_offset_map() and we can do that through an atomic read in |
3595 | + * C, which is what pmd_trans_unstable() provides. |
3596 | */ |
3597 | - if (pmd_trans_unstable(vmf->pmd) || pmd_devmap(*vmf->pmd)) |
3598 | + if (pmd_devmap_trans_unstable(vmf->pmd)) |
3599 | return VM_FAULT_NOPAGE; |
3600 | |
3601 | + /* |
3602 | + * At this point we know that our vmf->pmd points to a page of ptes |
3603 | + * and it cannot become pmd_none(), pmd_devmap() or pmd_trans_huge() |
3604 | + * for the duration of the fault. If a racing MADV_DONTNEED runs and |
3605 | + * we zap the ptes pointed to by our vmf->pmd, the vmf->ptl will still |
3606 | + * be valid and we will re-check to make sure the vmf->pte isn't |
3607 | + * pte_none() under vmf->ptl protection when we return to |
3608 | + * alloc_set_pte(). |
3609 | + */ |
3610 | vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address, |
3611 | &vmf->ptl); |
3612 | return 0; |
3613 | @@ -3690,7 +3710,7 @@ static int handle_pte_fault(struct vm_fault *vmf) |
3614 | vmf->pte = NULL; |
3615 | } else { |
3616 | /* See comment in pte_alloc_one_map() */ |
3617 | - if (pmd_trans_unstable(vmf->pmd) || pmd_devmap(*vmf->pmd)) |
3618 | + if (pmd_devmap_trans_unstable(vmf->pmd)) |
3619 | return 0; |
3620 | /* |
3621 | * A regular pmd is established and it can't morph into a huge |
3622 | diff --git a/mm/mlock.c b/mm/mlock.c |
3623 | index 0dd9ca18e19e..721679a2c1aa 100644 |
3624 | --- a/mm/mlock.c |
3625 | +++ b/mm/mlock.c |
3626 | @@ -286,7 +286,7 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) |
3627 | { |
3628 | int i; |
3629 | int nr = pagevec_count(pvec); |
3630 | - int delta_munlocked; |
3631 | + int delta_munlocked = -nr; |
3632 | struct pagevec pvec_putback; |
3633 | int pgrescued = 0; |
3634 | |
3635 | @@ -306,6 +306,8 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) |
3636 | continue; |
3637 | else |
3638 | __munlock_isolation_failed(page); |
3639 | + } else { |
3640 | + delta_munlocked++; |
3641 | } |
3642 | |
3643 | /* |
3644 | @@ -317,7 +319,6 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) |
3645 | pagevec_add(&pvec_putback, pvec->pages[i]); |
3646 | pvec->pages[i] = NULL; |
3647 | } |
3648 | - delta_munlocked = -nr + pagevec_count(&pvec_putback); |
3649 | __mod_zone_page_state(zone, NR_MLOCK, delta_munlocked); |
3650 | spin_unlock_irq(zone_lru_lock(zone)); |
3651 | |
3652 | diff --git a/mm/page_alloc.c b/mm/page_alloc.c |
3653 | index c5fee5a0316d..a2019fc9d94d 100644 |
3654 | --- a/mm/page_alloc.c |
3655 | +++ b/mm/page_alloc.c |
3656 | @@ -291,6 +291,26 @@ int page_group_by_mobility_disabled __read_mostly; |
3657 | #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT |
3658 | static inline void reset_deferred_meminit(pg_data_t *pgdat) |
3659 | { |
3660 | + unsigned long max_initialise; |
3661 | + unsigned long reserved_lowmem; |
3662 | + |
3663 | + /* |
3664 | + * Initialise at least 2G of a node but also take into account that |
3665 | + * two large system hashes that can take up 1GB for 0.25TB/node. |
3666 | + */ |
3667 | + max_initialise = max(2UL << (30 - PAGE_SHIFT), |
3668 | + (pgdat->node_spanned_pages >> 8)); |
3669 | + |
3670 | + /* |
3671 | + * Compensate the all the memblock reservations (e.g. crash kernel) |
3672 | + * from the initial estimation to make sure we will initialize enough |
3673 | + * memory to boot. |
3674 | + */ |
3675 | + reserved_lowmem = memblock_reserved_memory_within(pgdat->node_start_pfn, |
3676 | + pgdat->node_start_pfn + max_initialise); |
3677 | + max_initialise += reserved_lowmem; |
3678 | + |
3679 | + pgdat->static_init_size = min(max_initialise, pgdat->node_spanned_pages); |
3680 | pgdat->first_deferred_pfn = ULONG_MAX; |
3681 | } |
3682 | |
3683 | @@ -313,20 +333,11 @@ static inline bool update_defer_init(pg_data_t *pgdat, |
3684 | unsigned long pfn, unsigned long zone_end, |
3685 | unsigned long *nr_initialised) |
3686 | { |
3687 | - unsigned long max_initialise; |
3688 | - |
3689 | /* Always populate low zones for address-contrained allocations */ |
3690 | if (zone_end < pgdat_end_pfn(pgdat)) |
3691 | return true; |
3692 | - /* |
3693 | - * Initialise at least 2G of a node but also take into account that |
3694 | - * two large system hashes that can take up 1GB for 0.25TB/node. |
3695 | - */ |
3696 | - max_initialise = max(2UL << (30 - PAGE_SHIFT), |
3697 | - (pgdat->node_spanned_pages >> 8)); |
3698 | - |
3699 | (*nr_initialised)++; |
3700 | - if ((*nr_initialised > max_initialise) && |
3701 | + if ((*nr_initialised > pgdat->static_init_size) && |
3702 | (pfn & (PAGES_PER_SECTION - 1)) == 0) { |
3703 | pgdat->first_deferred_pfn = pfn; |
3704 | return false; |
3705 | @@ -3834,7 +3845,9 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, |
3706 | goto got_pg; |
3707 | |
3708 | /* Avoid allocations with no watermarks from looping endlessly */ |
3709 | - if (test_thread_flag(TIF_MEMDIE)) |
3710 | + if (test_thread_flag(TIF_MEMDIE) && |
3711 | + (alloc_flags == ALLOC_NO_WATERMARKS || |
3712 | + (gfp_mask & __GFP_NOMEMALLOC))) |
3713 | goto nopage; |
3714 | |
3715 | /* Retry as long as the OOM killer is making progress */ |
3716 | @@ -6098,7 +6111,6 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size, |
3717 | /* pg_data_t should be reset to zero when it's allocated */ |
3718 | WARN_ON(pgdat->nr_zones || pgdat->kswapd_classzone_idx); |
3719 | |
3720 | - reset_deferred_meminit(pgdat); |
3721 | pgdat->node_id = nid; |
3722 | pgdat->node_start_pfn = node_start_pfn; |
3723 | pgdat->per_cpu_nodestats = NULL; |
3724 | @@ -6120,6 +6132,7 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size, |
3725 | (unsigned long)pgdat->node_mem_map); |
3726 | #endif |
3727 | |
3728 | + reset_deferred_meminit(pgdat); |
3729 | free_area_init_core(pgdat); |
3730 | } |
3731 | |
3732 | diff --git a/mm/slub.c b/mm/slub.c |
3733 | index 7f4bc7027ed5..e3863a22e10d 100644 |
3734 | --- a/mm/slub.c |
3735 | +++ b/mm/slub.c |
3736 | @@ -5512,6 +5512,7 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s) |
3737 | char mbuf[64]; |
3738 | char *buf; |
3739 | struct slab_attribute *attr = to_slab_attr(slab_attrs[i]); |
3740 | + ssize_t len; |
3741 | |
3742 | if (!attr || !attr->store || !attr->show) |
3743 | continue; |
3744 | @@ -5536,8 +5537,9 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s) |
3745 | buf = buffer; |
3746 | } |
3747 | |
3748 | - attr->show(root_cache, buf); |
3749 | - attr->store(s, buf, strlen(buf)); |
3750 | + len = attr->show(root_cache, buf); |
3751 | + if (len > 0) |
3752 | + attr->store(s, buf, len); |
3753 | } |
3754 | |
3755 | if (buffer) |
3756 | diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c |
3757 | index 225ef7d53701..0488c6735c46 100644 |
3758 | --- a/net/bridge/br_netlink.c |
3759 | +++ b/net/bridge/br_netlink.c |
3760 | @@ -828,6 +828,13 @@ static int br_validate(struct nlattr *tb[], struct nlattr *data[]) |
3761 | return -EPROTONOSUPPORT; |
3762 | } |
3763 | } |
3764 | + |
3765 | + if (data[IFLA_BR_VLAN_DEFAULT_PVID]) { |
3766 | + __u16 defpvid = nla_get_u16(data[IFLA_BR_VLAN_DEFAULT_PVID]); |
3767 | + |
3768 | + if (defpvid >= VLAN_VID_MASK) |
3769 | + return -EINVAL; |
3770 | + } |
3771 | #endif |
3772 | |
3773 | return 0; |
3774 | diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c |
3775 | index 08341d2aa9c9..0db8102995a5 100644 |
3776 | --- a/net/bridge/br_stp_if.c |
3777 | +++ b/net/bridge/br_stp_if.c |
3778 | @@ -179,6 +179,7 @@ static void br_stp_start(struct net_bridge *br) |
3779 | br_debug(br, "using kernel STP\n"); |
3780 | |
3781 | /* To start timers on any ports left in blocking */ |
3782 | + mod_timer(&br->hello_timer, jiffies + br->hello_time); |
3783 | br_port_state_selection(br); |
3784 | } |
3785 | |
3786 | diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c |
3787 | index c98b3e5c140a..60b6fe277a8b 100644 |
3788 | --- a/net/bridge/br_stp_timer.c |
3789 | +++ b/net/bridge/br_stp_timer.c |
3790 | @@ -40,7 +40,7 @@ static void br_hello_timer_expired(unsigned long arg) |
3791 | if (br->dev->flags & IFF_UP) { |
3792 | br_config_bpdu_generation(br); |
3793 | |
3794 | - if (br->stp_enabled != BR_USER_STP) |
3795 | + if (br->stp_enabled == BR_KERNEL_STP) |
3796 | mod_timer(&br->hello_timer, |
3797 | round_jiffies(jiffies + br->hello_time)); |
3798 | } |
3799 | diff --git a/net/core/dst.c b/net/core/dst.c |
3800 | index 960e503b5a52..6192f11beec9 100644 |
3801 | --- a/net/core/dst.c |
3802 | +++ b/net/core/dst.c |
3803 | @@ -151,13 +151,13 @@ int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb) |
3804 | } |
3805 | EXPORT_SYMBOL(dst_discard_out); |
3806 | |
3807 | -const u32 dst_default_metrics[RTAX_MAX + 1] = { |
3808 | +const struct dst_metrics dst_default_metrics = { |
3809 | /* This initializer is needed to force linker to place this variable |
3810 | * into const section. Otherwise it might end into bss section. |
3811 | * We really want to avoid false sharing on this variable, and catch |
3812 | * any writes on it. |
3813 | */ |
3814 | - [RTAX_MAX] = 0xdeadbeef, |
3815 | + .refcnt = ATOMIC_INIT(1), |
3816 | }; |
3817 | |
3818 | void dst_init(struct dst_entry *dst, struct dst_ops *ops, |
3819 | @@ -169,7 +169,7 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops, |
3820 | if (dev) |
3821 | dev_hold(dev); |
3822 | dst->ops = ops; |
3823 | - dst_init_metrics(dst, dst_default_metrics, true); |
3824 | + dst_init_metrics(dst, dst_default_metrics.metrics, true); |
3825 | dst->expires = 0UL; |
3826 | dst->path = dst; |
3827 | dst->from = NULL; |
3828 | @@ -314,25 +314,30 @@ EXPORT_SYMBOL(dst_release); |
3829 | |
3830 | u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old) |
3831 | { |
3832 | - u32 *p = kmalloc(sizeof(u32) * RTAX_MAX, GFP_ATOMIC); |
3833 | + struct dst_metrics *p = kmalloc(sizeof(*p), GFP_ATOMIC); |
3834 | |
3835 | if (p) { |
3836 | - u32 *old_p = __DST_METRICS_PTR(old); |
3837 | + struct dst_metrics *old_p = (struct dst_metrics *)__DST_METRICS_PTR(old); |
3838 | unsigned long prev, new; |
3839 | |
3840 | - memcpy(p, old_p, sizeof(u32) * RTAX_MAX); |
3841 | + atomic_set(&p->refcnt, 1); |
3842 | + memcpy(p->metrics, old_p->metrics, sizeof(p->metrics)); |
3843 | |
3844 | new = (unsigned long) p; |
3845 | prev = cmpxchg(&dst->_metrics, old, new); |
3846 | |
3847 | if (prev != old) { |
3848 | kfree(p); |
3849 | - p = __DST_METRICS_PTR(prev); |
3850 | + p = (struct dst_metrics *)__DST_METRICS_PTR(prev); |
3851 | if (prev & DST_METRICS_READ_ONLY) |
3852 | p = NULL; |
3853 | + } else if (prev & DST_METRICS_REFCOUNTED) { |
3854 | + if (atomic_dec_and_test(&old_p->refcnt)) |
3855 | + kfree(old_p); |
3856 | } |
3857 | } |
3858 | - return p; |
3859 | + BUILD_BUG_ON(offsetof(struct dst_metrics, metrics) != 0); |
3860 | + return (u32 *)p; |
3861 | } |
3862 | EXPORT_SYMBOL(dst_cow_metrics_generic); |
3863 | |
3864 | @@ -341,7 +346,7 @@ void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old) |
3865 | { |
3866 | unsigned long prev, new; |
3867 | |
3868 | - new = ((unsigned long) dst_default_metrics) | DST_METRICS_READ_ONLY; |
3869 | + new = ((unsigned long) &dst_default_metrics) | DST_METRICS_READ_ONLY; |
3870 | prev = cmpxchg(&dst->_metrics, old, new); |
3871 | if (prev == old) |
3872 | kfree(__DST_METRICS_PTR(old)); |
3873 | diff --git a/net/core/filter.c b/net/core/filter.c |
3874 | index ebaeaf2e46e8..6ca3b05eb627 100644 |
3875 | --- a/net/core/filter.c |
3876 | +++ b/net/core/filter.c |
3877 | @@ -2266,6 +2266,7 @@ bool bpf_helper_changes_pkt_data(void *func) |
3878 | func == bpf_skb_change_head || |
3879 | func == bpf_skb_change_tail || |
3880 | func == bpf_skb_pull_data || |
3881 | + func == bpf_clone_redirect || |
3882 | func == bpf_l3_csum_replace || |
3883 | func == bpf_l4_csum_replace || |
3884 | func == bpf_xdp_adjust_head) |
3885 | diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c |
3886 | index 69daf393cbe1..8d4a185a8143 100644 |
3887 | --- a/net/core/rtnetlink.c |
3888 | +++ b/net/core/rtnetlink.c |
3889 | @@ -1620,13 +1620,13 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) |
3890 | cb->nlh->nlmsg_seq, 0, |
3891 | flags, |
3892 | ext_filter_mask); |
3893 | - /* If we ran out of room on the first message, |
3894 | - * we're in trouble |
3895 | - */ |
3896 | - WARN_ON((err == -EMSGSIZE) && (skb->len == 0)); |
3897 | |
3898 | - if (err < 0) |
3899 | - goto out; |
3900 | + if (err < 0) { |
3901 | + if (likely(skb->len)) |
3902 | + goto out; |
3903 | + |
3904 | + goto out_err; |
3905 | + } |
3906 | |
3907 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); |
3908 | cont: |
3909 | @@ -1634,10 +1634,12 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) |
3910 | } |
3911 | } |
3912 | out: |
3913 | + err = skb->len; |
3914 | +out_err: |
3915 | cb->args[1] = idx; |
3916 | cb->args[0] = h; |
3917 | |
3918 | - return skb->len; |
3919 | + return err; |
3920 | } |
3921 | |
3922 | int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len) |
3923 | @@ -3427,8 +3429,12 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) |
3924 | err = br_dev->netdev_ops->ndo_bridge_getlink( |
3925 | skb, portid, seq, dev, |
3926 | filter_mask, NLM_F_MULTI); |
3927 | - if (err < 0 && err != -EOPNOTSUPP) |
3928 | - break; |
3929 | + if (err < 0 && err != -EOPNOTSUPP) { |
3930 | + if (likely(skb->len)) |
3931 | + break; |
3932 | + |
3933 | + goto out_err; |
3934 | + } |
3935 | } |
3936 | idx++; |
3937 | } |
3938 | @@ -3439,16 +3445,22 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) |
3939 | seq, dev, |
3940 | filter_mask, |
3941 | NLM_F_MULTI); |
3942 | - if (err < 0 && err != -EOPNOTSUPP) |
3943 | - break; |
3944 | + if (err < 0 && err != -EOPNOTSUPP) { |
3945 | + if (likely(skb->len)) |
3946 | + break; |
3947 | + |
3948 | + goto out_err; |
3949 | + } |
3950 | } |
3951 | idx++; |
3952 | } |
3953 | } |
3954 | + err = skb->len; |
3955 | +out_err: |
3956 | rcu_read_unlock(); |
3957 | cb->args[0] = idx; |
3958 | |
3959 | - return skb->len; |
3960 | + return err; |
3961 | } |
3962 | |
3963 | static inline size_t bridge_nlmsg_size(void) |
3964 | diff --git a/net/core/sock.c b/net/core/sock.c |
3965 | index 2c4f574168fb..59edc0e8c71a 100644 |
3966 | --- a/net/core/sock.c |
3967 | +++ b/net/core/sock.c |
3968 | @@ -138,10 +138,7 @@ |
3969 | |
3970 | #include <trace/events/sock.h> |
3971 | |
3972 | -#ifdef CONFIG_INET |
3973 | #include <net/tcp.h> |
3974 | -#endif |
3975 | - |
3976 | #include <net/busy_poll.h> |
3977 | |
3978 | static DEFINE_MUTEX(proto_list_mutex); |
3979 | @@ -1699,28 +1696,24 @@ EXPORT_SYMBOL(skb_set_owner_w); |
3980 | * delay queue. We want to allow the owner socket to send more |
3981 | * packets, as if they were already TX completed by a typical driver. |
3982 | * But we also want to keep skb->sk set because some packet schedulers |
3983 | - * rely on it (sch_fq for example). So we set skb->truesize to a small |
3984 | - * amount (1) and decrease sk_wmem_alloc accordingly. |
3985 | + * rely on it (sch_fq for example). |
3986 | */ |
3987 | void skb_orphan_partial(struct sk_buff *skb) |
3988 | { |
3989 | - /* If this skb is a TCP pure ACK or already went here, |
3990 | - * we have nothing to do. 2 is already a very small truesize. |
3991 | - */ |
3992 | - if (skb->truesize <= 2) |
3993 | + if (skb_is_tcp_pure_ack(skb)) |
3994 | return; |
3995 | |
3996 | - /* TCP stack sets skb->ooo_okay based on sk_wmem_alloc, |
3997 | - * so we do not completely orphan skb, but transfert all |
3998 | - * accounted bytes but one, to avoid unexpected reorders. |
3999 | - */ |
4000 | if (skb->destructor == sock_wfree |
4001 | #ifdef CONFIG_INET |
4002 | || skb->destructor == tcp_wfree |
4003 | #endif |
4004 | ) { |
4005 | - atomic_sub(skb->truesize - 1, &skb->sk->sk_wmem_alloc); |
4006 | - skb->truesize = 1; |
4007 | + struct sock *sk = skb->sk; |
4008 | + |
4009 | + if (atomic_inc_not_zero(&sk->sk_refcnt)) { |
4010 | + atomic_sub(skb->truesize, &sk->sk_wmem_alloc); |
4011 | + skb->destructor = sock_efree; |
4012 | + } |
4013 | } else { |
4014 | skb_orphan(skb); |
4015 | } |
4016 | diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c |
4017 | index d9b6a4e403e7..b6bbb71e713e 100644 |
4018 | --- a/net/dccp/ipv6.c |
4019 | +++ b/net/dccp/ipv6.c |
4020 | @@ -426,6 +426,9 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk, |
4021 | newsk->sk_backlog_rcv = dccp_v4_do_rcv; |
4022 | newnp->pktoptions = NULL; |
4023 | newnp->opt = NULL; |
4024 | + newnp->ipv6_mc_list = NULL; |
4025 | + newnp->ipv6_ac_list = NULL; |
4026 | + newnp->ipv6_fl_list = NULL; |
4027 | newnp->mcast_oif = inet6_iif(skb); |
4028 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; |
4029 | |
4030 | @@ -490,6 +493,9 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk, |
4031 | /* Clone RX bits */ |
4032 | newnp->rxopt.all = np->rxopt.all; |
4033 | |
4034 | + newnp->ipv6_mc_list = NULL; |
4035 | + newnp->ipv6_ac_list = NULL; |
4036 | + newnp->ipv6_fl_list = NULL; |
4037 | newnp->pktoptions = NULL; |
4038 | newnp->opt = NULL; |
4039 | newnp->mcast_oif = inet6_iif(skb); |
4040 | diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c |
4041 | index 8f2133ffc2ff..a2f7de26670e 100644 |
4042 | --- a/net/ipv4/fib_frontend.c |
4043 | +++ b/net/ipv4/fib_frontend.c |
4044 | @@ -760,7 +760,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) |
4045 | unsigned int e = 0, s_e; |
4046 | struct fib_table *tb; |
4047 | struct hlist_head *head; |
4048 | - int dumped = 0; |
4049 | + int dumped = 0, err; |
4050 | |
4051 | if (nlmsg_len(cb->nlh) >= sizeof(struct rtmsg) && |
4052 | ((struct rtmsg *) nlmsg_data(cb->nlh))->rtm_flags & RTM_F_CLONED) |
4053 | @@ -780,20 +780,27 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) |
4054 | if (dumped) |
4055 | memset(&cb->args[2], 0, sizeof(cb->args) - |
4056 | 2 * sizeof(cb->args[0])); |
4057 | - if (fib_table_dump(tb, skb, cb) < 0) |
4058 | - goto out; |
4059 | + err = fib_table_dump(tb, skb, cb); |
4060 | + if (err < 0) { |
4061 | + if (likely(skb->len)) |
4062 | + goto out; |
4063 | + |
4064 | + goto out_err; |
4065 | + } |
4066 | dumped = 1; |
4067 | next: |
4068 | e++; |
4069 | } |
4070 | } |
4071 | out: |
4072 | + err = skb->len; |
4073 | +out_err: |
4074 | rcu_read_unlock(); |
4075 | |
4076 | cb->args[1] = e; |
4077 | cb->args[0] = h; |
4078 | |
4079 | - return skb->len; |
4080 | + return err; |
4081 | } |
4082 | |
4083 | /* Prepare and feed intra-kernel routing request. |
4084 | diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c |
4085 | index 317026a39cfa..6cf74de06467 100644 |
4086 | --- a/net/ipv4/fib_semantics.c |
4087 | +++ b/net/ipv4/fib_semantics.c |
4088 | @@ -204,6 +204,7 @@ static void rt_fibinfo_free_cpus(struct rtable __rcu * __percpu *rtp) |
4089 | static void free_fib_info_rcu(struct rcu_head *head) |
4090 | { |
4091 | struct fib_info *fi = container_of(head, struct fib_info, rcu); |
4092 | + struct dst_metrics *m; |
4093 | |
4094 | change_nexthops(fi) { |
4095 | if (nexthop_nh->nh_dev) |
4096 | @@ -214,8 +215,9 @@ static void free_fib_info_rcu(struct rcu_head *head) |
4097 | rt_fibinfo_free(&nexthop_nh->nh_rth_input); |
4098 | } endfor_nexthops(fi); |
4099 | |
4100 | - if (fi->fib_metrics != (u32 *) dst_default_metrics) |
4101 | - kfree(fi->fib_metrics); |
4102 | + m = fi->fib_metrics; |
4103 | + if (m != &dst_default_metrics && atomic_dec_and_test(&m->refcnt)) |
4104 | + kfree(m); |
4105 | kfree(fi); |
4106 | } |
4107 | |
4108 | @@ -975,11 +977,11 @@ fib_convert_metrics(struct fib_info *fi, const struct fib_config *cfg) |
4109 | val = 255; |
4110 | if (type == RTAX_FEATURES && (val & ~RTAX_FEATURE_MASK)) |
4111 | return -EINVAL; |
4112 | - fi->fib_metrics[type - 1] = val; |
4113 | + fi->fib_metrics->metrics[type - 1] = val; |
4114 | } |
4115 | |
4116 | if (ecn_ca) |
4117 | - fi->fib_metrics[RTAX_FEATURES - 1] |= DST_FEATURE_ECN_CA; |
4118 | + fi->fib_metrics->metrics[RTAX_FEATURES - 1] |= DST_FEATURE_ECN_CA; |
4119 | |
4120 | return 0; |
4121 | } |
4122 | @@ -1037,11 +1039,12 @@ struct fib_info *fib_create_info(struct fib_config *cfg) |
4123 | goto failure; |
4124 | fib_info_cnt++; |
4125 | if (cfg->fc_mx) { |
4126 | - fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL); |
4127 | + fi->fib_metrics = kzalloc(sizeof(*fi->fib_metrics), GFP_KERNEL); |
4128 | if (!fi->fib_metrics) |
4129 | goto failure; |
4130 | + atomic_set(&fi->fib_metrics->refcnt, 1); |
4131 | } else |
4132 | - fi->fib_metrics = (u32 *) dst_default_metrics; |
4133 | + fi->fib_metrics = (struct dst_metrics *)&dst_default_metrics; |
4134 | |
4135 | fi->fib_net = net; |
4136 | fi->fib_protocol = cfg->fc_protocol; |
4137 | @@ -1242,7 +1245,7 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event, |
4138 | if (fi->fib_priority && |
4139 | nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority)) |
4140 | goto nla_put_failure; |
4141 | - if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0) |
4142 | + if (rtnetlink_put_metrics(skb, fi->fib_metrics->metrics) < 0) |
4143 | goto nla_put_failure; |
4144 | |
4145 | if (fi->fib_prefsrc && |
4146 | diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c |
4147 | index 2f0d8233950f..08709fb62d2e 100644 |
4148 | --- a/net/ipv4/fib_trie.c |
4149 | +++ b/net/ipv4/fib_trie.c |
4150 | @@ -2079,6 +2079,8 @@ static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb, |
4151 | |
4152 | /* rcu_read_lock is hold by caller */ |
4153 | hlist_for_each_entry_rcu(fa, &l->leaf, fa_list) { |
4154 | + int err; |
4155 | + |
4156 | if (i < s_i) { |
4157 | i++; |
4158 | continue; |
4159 | @@ -2089,17 +2091,14 @@ static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb, |
4160 | continue; |
4161 | } |
4162 | |
4163 | - if (fib_dump_info(skb, NETLINK_CB(cb->skb).portid, |
4164 | - cb->nlh->nlmsg_seq, |
4165 | - RTM_NEWROUTE, |
4166 | - tb->tb_id, |
4167 | - fa->fa_type, |
4168 | - xkey, |
4169 | - KEYLENGTH - fa->fa_slen, |
4170 | - fa->fa_tos, |
4171 | - fa->fa_info, NLM_F_MULTI) < 0) { |
4172 | + err = fib_dump_info(skb, NETLINK_CB(cb->skb).portid, |
4173 | + cb->nlh->nlmsg_seq, RTM_NEWROUTE, |
4174 | + tb->tb_id, fa->fa_type, |
4175 | + xkey, KEYLENGTH - fa->fa_slen, |
4176 | + fa->fa_tos, fa->fa_info, NLM_F_MULTI); |
4177 | + if (err < 0) { |
4178 | cb->args[4] = i; |
4179 | - return -1; |
4180 | + return err; |
4181 | } |
4182 | i++; |
4183 | } |
4184 | @@ -2121,10 +2120,13 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, |
4185 | t_key key = cb->args[3]; |
4186 | |
4187 | while ((l = leaf_walk_rcu(&tp, key)) != NULL) { |
4188 | - if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) { |
4189 | + int err; |
4190 | + |
4191 | + err = fn_trie_dump_leaf(l, tb, skb, cb); |
4192 | + if (err < 0) { |
4193 | cb->args[3] = key; |
4194 | cb->args[2] = count; |
4195 | - return -1; |
4196 | + return err; |
4197 | } |
4198 | |
4199 | ++count; |
4200 | diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c |
4201 | index 5e313c1ac94f..1054d330bf9d 100644 |
4202 | --- a/net/ipv4/inet_connection_sock.c |
4203 | +++ b/net/ipv4/inet_connection_sock.c |
4204 | @@ -794,6 +794,8 @@ struct sock *inet_csk_clone_lock(const struct sock *sk, |
4205 | /* listeners have SOCK_RCU_FREE, not the children */ |
4206 | sock_reset_flag(newsk, SOCK_RCU_FREE); |
4207 | |
4208 | + inet_sk(newsk)->mc_list = NULL; |
4209 | + |
4210 | newsk->sk_mark = inet_rsk(req)->ir_mark; |
4211 | atomic64_set(&newsk->sk_cookie, |
4212 | atomic64_read(&inet_rsk(req)->ir_cookie)); |
4213 | diff --git a/net/ipv4/route.c b/net/ipv4/route.c |
4214 | index d9724889ff09..e0cc6c1fe69d 100644 |
4215 | --- a/net/ipv4/route.c |
4216 | +++ b/net/ipv4/route.c |
4217 | @@ -1389,8 +1389,12 @@ static void rt_add_uncached_list(struct rtable *rt) |
4218 | |
4219 | static void ipv4_dst_destroy(struct dst_entry *dst) |
4220 | { |
4221 | + struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst); |
4222 | struct rtable *rt = (struct rtable *) dst; |
4223 | |
4224 | + if (p != &dst_default_metrics && atomic_dec_and_test(&p->refcnt)) |
4225 | + kfree(p); |
4226 | + |
4227 | if (!list_empty(&rt->rt_uncached)) { |
4228 | struct uncached_list *ul = rt->rt_uncached_list; |
4229 | |
4230 | @@ -1442,7 +1446,11 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr, |
4231 | rt->rt_gateway = nh->nh_gw; |
4232 | rt->rt_uses_gateway = 1; |
4233 | } |
4234 | - dst_init_metrics(&rt->dst, fi->fib_metrics, true); |
4235 | + dst_init_metrics(&rt->dst, fi->fib_metrics->metrics, true); |
4236 | + if (fi->fib_metrics != &dst_default_metrics) { |
4237 | + rt->dst._metrics |= DST_METRICS_REFCOUNTED; |
4238 | + atomic_inc(&fi->fib_metrics->refcnt); |
4239 | + } |
4240 | #ifdef CONFIG_IP_ROUTE_CLASSID |
4241 | rt->dst.tclassid = nh->nh_tclassid; |
4242 | #endif |
4243 | diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c |
4244 | index 2dc7fcf60bf3..651f1f058a64 100644 |
4245 | --- a/net/ipv4/tcp.c |
4246 | +++ b/net/ipv4/tcp.c |
4247 | @@ -1084,9 +1084,12 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, |
4248 | { |
4249 | struct tcp_sock *tp = tcp_sk(sk); |
4250 | struct inet_sock *inet = inet_sk(sk); |
4251 | + struct sockaddr *uaddr = msg->msg_name; |
4252 | int err, flags; |
4253 | |
4254 | - if (!(sysctl_tcp_fastopen & TFO_CLIENT_ENABLE)) |
4255 | + if (!(sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) || |
4256 | + (uaddr && msg->msg_namelen >= sizeof(uaddr->sa_family) && |
4257 | + uaddr->sa_family == AF_UNSPEC)) |
4258 | return -EOPNOTSUPP; |
4259 | if (tp->fastopen_req) |
4260 | return -EALREADY; /* Another Fast Open is in progress */ |
4261 | @@ -1108,7 +1111,7 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, |
4262 | } |
4263 | } |
4264 | flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0; |
4265 | - err = __inet_stream_connect(sk->sk_socket, msg->msg_name, |
4266 | + err = __inet_stream_connect(sk->sk_socket, uaddr, |
4267 | msg->msg_namelen, flags, 1); |
4268 | /* fastopen_req could already be freed in __inet_stream_connect |
4269 | * if the connection times out or gets rst |
4270 | diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c |
4271 | index 3c6c8787b42e..896a0458e578 100644 |
4272 | --- a/net/ipv4/tcp_input.c |
4273 | +++ b/net/ipv4/tcp_input.c |
4274 | @@ -1174,13 +1174,14 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb, |
4275 | */ |
4276 | if (pkt_len > mss) { |
4277 | unsigned int new_len = (pkt_len / mss) * mss; |
4278 | - if (!in_sack && new_len < pkt_len) { |
4279 | + if (!in_sack && new_len < pkt_len) |
4280 | new_len += mss; |
4281 | - if (new_len >= skb->len) |
4282 | - return 0; |
4283 | - } |
4284 | pkt_len = new_len; |
4285 | } |
4286 | + |
4287 | + if (pkt_len >= skb->len && !in_sack) |
4288 | + return 0; |
4289 | + |
4290 | err = tcp_fragment(sk, skb, pkt_len, mss, GFP_ATOMIC); |
4291 | if (err < 0) |
4292 | return err; |
4293 | @@ -3188,7 +3189,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, |
4294 | int delta; |
4295 | |
4296 | /* Non-retransmitted hole got filled? That's reordering */ |
4297 | - if (reord < prior_fackets) |
4298 | + if (reord < prior_fackets && reord <= tp->fackets_out) |
4299 | tcp_update_reordering(sk, tp->fackets_out - reord, 0); |
4300 | |
4301 | delta = tcp_is_fack(tp) ? pkts_acked : |
4302 | diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c |
4303 | index 6fcb7cb49bb2..4d60164c17e2 100644 |
4304 | --- a/net/ipv6/ip6_gre.c |
4305 | +++ b/net/ipv6/ip6_gre.c |
4306 | @@ -537,11 +537,10 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev) |
4307 | |
4308 | memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); |
4309 | |
4310 | - dsfield = ipv4_get_dsfield(iph); |
4311 | - |
4312 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) |
4313 | - fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) |
4314 | - & IPV6_TCLASS_MASK; |
4315 | + dsfield = ipv4_get_dsfield(iph); |
4316 | + else |
4317 | + dsfield = ip6_tclass(t->parms.flowinfo); |
4318 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) |
4319 | fl6.flowi6_mark = skb->mark; |
4320 | |
4321 | @@ -596,9 +595,11 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev) |
4322 | |
4323 | memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); |
4324 | |
4325 | - dsfield = ipv6_get_dsfield(ipv6h); |
4326 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) |
4327 | - fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK); |
4328 | + dsfield = ipv6_get_dsfield(ipv6h); |
4329 | + else |
4330 | + dsfield = ip6_tclass(t->parms.flowinfo); |
4331 | + |
4332 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL) |
4333 | fl6.flowlabel |= ip6_flowlabel(ipv6h); |
4334 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) |
4335 | diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c |
4336 | index 93e58a5e1837..280268f1dd7b 100644 |
4337 | --- a/net/ipv6/ip6_offload.c |
4338 | +++ b/net/ipv6/ip6_offload.c |
4339 | @@ -63,7 +63,6 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, |
4340 | const struct net_offload *ops; |
4341 | int proto; |
4342 | struct frag_hdr *fptr; |
4343 | - unsigned int unfrag_ip6hlen; |
4344 | unsigned int payload_len; |
4345 | u8 *prevhdr; |
4346 | int offset = 0; |
4347 | @@ -116,8 +115,10 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, |
4348 | skb->network_header = (u8 *)ipv6h - skb->head; |
4349 | |
4350 | if (udpfrag) { |
4351 | - unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); |
4352 | - fptr = (struct frag_hdr *)((u8 *)ipv6h + unfrag_ip6hlen); |
4353 | + int err = ip6_find_1stfragopt(skb, &prevhdr); |
4354 | + if (err < 0) |
4355 | + return ERR_PTR(err); |
4356 | + fptr = (struct frag_hdr *)((u8 *)ipv6h + err); |
4357 | fptr->frag_off = htons(offset); |
4358 | if (skb->next) |
4359 | fptr->frag_off |= htons(IP6_MF); |
4360 | diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
4361 | index 58f6288e9ba5..bf8a58a1c32d 100644 |
4362 | --- a/net/ipv6/ip6_output.c |
4363 | +++ b/net/ipv6/ip6_output.c |
4364 | @@ -597,7 +597,10 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, |
4365 | int ptr, offset = 0, err = 0; |
4366 | u8 *prevhdr, nexthdr = 0; |
4367 | |
4368 | - hlen = ip6_find_1stfragopt(skb, &prevhdr); |
4369 | + err = ip6_find_1stfragopt(skb, &prevhdr); |
4370 | + if (err < 0) |
4371 | + goto fail; |
4372 | + hlen = err; |
4373 | nexthdr = *prevhdr; |
4374 | |
4375 | mtu = ip6_skb_dst_mtu(skb); |
4376 | @@ -1463,6 +1466,11 @@ static int __ip6_append_data(struct sock *sk, |
4377 | */ |
4378 | alloclen += sizeof(struct frag_hdr); |
4379 | |
4380 | + copy = datalen - transhdrlen - fraggap; |
4381 | + if (copy < 0) { |
4382 | + err = -EINVAL; |
4383 | + goto error; |
4384 | + } |
4385 | if (transhdrlen) { |
4386 | skb = sock_alloc_send_skb(sk, |
4387 | alloclen + hh_len, |
4388 | @@ -1512,13 +1520,9 @@ static int __ip6_append_data(struct sock *sk, |
4389 | data += fraggap; |
4390 | pskb_trim_unique(skb_prev, maxfraglen); |
4391 | } |
4392 | - copy = datalen - transhdrlen - fraggap; |
4393 | - |
4394 | - if (copy < 0) { |
4395 | - err = -EINVAL; |
4396 | - kfree_skb(skb); |
4397 | - goto error; |
4398 | - } else if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) { |
4399 | + if (copy > 0 && |
4400 | + getfrag(from, data + transhdrlen, offset, |
4401 | + copy, fraggap, skb) < 0) { |
4402 | err = -EFAULT; |
4403 | kfree_skb(skb); |
4404 | goto error; |
4405 | diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c |
4406 | index a9692ec0cd6d..15ff33934f79 100644 |
4407 | --- a/net/ipv6/ip6_tunnel.c |
4408 | +++ b/net/ipv6/ip6_tunnel.c |
4409 | @@ -1196,7 +1196,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, |
4410 | skb_push(skb, sizeof(struct ipv6hdr)); |
4411 | skb_reset_network_header(skb); |
4412 | ipv6h = ipv6_hdr(skb); |
4413 | - ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), |
4414 | + ip6_flow_hdr(ipv6h, dsfield, |
4415 | ip6_make_flowlabel(net, skb, fl6->flowlabel, true, fl6)); |
4416 | ipv6h->hop_limit = hop_limit; |
4417 | ipv6h->nexthdr = proto; |
4418 | @@ -1231,8 +1231,6 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
4419 | if (tproto != IPPROTO_IPIP && tproto != 0) |
4420 | return -1; |
4421 | |
4422 | - dsfield = ipv4_get_dsfield(iph); |
4423 | - |
4424 | if (t->parms.collect_md) { |
4425 | struct ip_tunnel_info *tun_info; |
4426 | const struct ip_tunnel_key *key; |
4427 | @@ -1246,6 +1244,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
4428 | fl6.flowi6_proto = IPPROTO_IPIP; |
4429 | fl6.daddr = key->u.ipv6.dst; |
4430 | fl6.flowlabel = key->label; |
4431 | + dsfield = ip6_tclass(key->label); |
4432 | } else { |
4433 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) |
4434 | encap_limit = t->parms.encap_limit; |
4435 | @@ -1254,8 +1253,9 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
4436 | fl6.flowi6_proto = IPPROTO_IPIP; |
4437 | |
4438 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) |
4439 | - fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) |
4440 | - & IPV6_TCLASS_MASK; |
4441 | + dsfield = ipv4_get_dsfield(iph); |
4442 | + else |
4443 | + dsfield = ip6_tclass(t->parms.flowinfo); |
4444 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) |
4445 | fl6.flowi6_mark = skb->mark; |
4446 | } |
4447 | @@ -1265,6 +1265,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
4448 | if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) |
4449 | return -1; |
4450 | |
4451 | + dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph)); |
4452 | + |
4453 | skb_set_inner_ipproto(skb, IPPROTO_IPIP); |
4454 | |
4455 | err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, |
4456 | @@ -1298,8 +1300,6 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
4457 | ip6_tnl_addr_conflict(t, ipv6h)) |
4458 | return -1; |
4459 | |
4460 | - dsfield = ipv6_get_dsfield(ipv6h); |
4461 | - |
4462 | if (t->parms.collect_md) { |
4463 | struct ip_tunnel_info *tun_info; |
4464 | const struct ip_tunnel_key *key; |
4465 | @@ -1313,6 +1313,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
4466 | fl6.flowi6_proto = IPPROTO_IPV6; |
4467 | fl6.daddr = key->u.ipv6.dst; |
4468 | fl6.flowlabel = key->label; |
4469 | + dsfield = ip6_tclass(key->label); |
4470 | } else { |
4471 | offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); |
4472 | /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */ |
4473 | @@ -1335,7 +1336,9 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
4474 | fl6.flowi6_proto = IPPROTO_IPV6; |
4475 | |
4476 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) |
4477 | - fl6.flowlabel |= (*(__be32 *)ipv6h & IPV6_TCLASS_MASK); |
4478 | + dsfield = ipv6_get_dsfield(ipv6h); |
4479 | + else |
4480 | + dsfield = ip6_tclass(t->parms.flowinfo); |
4481 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL) |
4482 | fl6.flowlabel |= ip6_flowlabel(ipv6h); |
4483 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) |
4484 | @@ -1347,6 +1350,8 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) |
4485 | if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) |
4486 | return -1; |
4487 | |
4488 | + dsfield = INET_ECN_encapsulate(dsfield, ipv6_get_dsfield(ipv6h)); |
4489 | + |
4490 | skb_set_inner_ipproto(skb, IPPROTO_IPV6); |
4491 | |
4492 | err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, |
4493 | diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c |
4494 | index cd4252346a32..e9065b8d3af8 100644 |
4495 | --- a/net/ipv6/output_core.c |
4496 | +++ b/net/ipv6/output_core.c |
4497 | @@ -79,14 +79,13 @@ EXPORT_SYMBOL(ipv6_select_ident); |
4498 | int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) |
4499 | { |
4500 | u16 offset = sizeof(struct ipv6hdr); |
4501 | - struct ipv6_opt_hdr *exthdr = |
4502 | - (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1); |
4503 | unsigned int packet_len = skb_tail_pointer(skb) - |
4504 | skb_network_header(skb); |
4505 | int found_rhdr = 0; |
4506 | *nexthdr = &ipv6_hdr(skb)->nexthdr; |
4507 | |
4508 | - while (offset + 1 <= packet_len) { |
4509 | + while (offset <= packet_len) { |
4510 | + struct ipv6_opt_hdr *exthdr; |
4511 | |
4512 | switch (**nexthdr) { |
4513 | |
4514 | @@ -107,13 +106,16 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) |
4515 | return offset; |
4516 | } |
4517 | |
4518 | - offset += ipv6_optlen(exthdr); |
4519 | - *nexthdr = &exthdr->nexthdr; |
4520 | + if (offset + sizeof(struct ipv6_opt_hdr) > packet_len) |
4521 | + return -EINVAL; |
4522 | + |
4523 | exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + |
4524 | offset); |
4525 | + offset += ipv6_optlen(exthdr); |
4526 | + *nexthdr = &exthdr->nexthdr; |
4527 | } |
4528 | |
4529 | - return offset; |
4530 | + return -EINVAL; |
4531 | } |
4532 | EXPORT_SYMBOL(ip6_find_1stfragopt); |
4533 | |
4534 | diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c |
4535 | index 4c4afdca41ff..ff5f87641651 100644 |
4536 | --- a/net/ipv6/tcp_ipv6.c |
4537 | +++ b/net/ipv6/tcp_ipv6.c |
4538 | @@ -1070,6 +1070,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * |
4539 | newtp->af_specific = &tcp_sock_ipv6_mapped_specific; |
4540 | #endif |
4541 | |
4542 | + newnp->ipv6_mc_list = NULL; |
4543 | newnp->ipv6_ac_list = NULL; |
4544 | newnp->ipv6_fl_list = NULL; |
4545 | newnp->pktoptions = NULL; |
4546 | @@ -1139,6 +1140,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * |
4547 | First: no IPv4 options. |
4548 | */ |
4549 | newinet->inet_opt = NULL; |
4550 | + newnp->ipv6_mc_list = NULL; |
4551 | newnp->ipv6_ac_list = NULL; |
4552 | newnp->ipv6_fl_list = NULL; |
4553 | |
4554 | diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c |
4555 | index ac858c480f2f..a2267f80febb 100644 |
4556 | --- a/net/ipv6/udp_offload.c |
4557 | +++ b/net/ipv6/udp_offload.c |
4558 | @@ -29,6 +29,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, |
4559 | u8 frag_hdr_sz = sizeof(struct frag_hdr); |
4560 | __wsum csum; |
4561 | int tnl_hlen; |
4562 | + int err; |
4563 | |
4564 | mss = skb_shinfo(skb)->gso_size; |
4565 | if (unlikely(skb->len <= mss)) |
4566 | @@ -90,7 +91,10 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, |
4567 | /* Find the unfragmentable header and shift it left by frag_hdr_sz |
4568 | * bytes to insert fragment header. |
4569 | */ |
4570 | - unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); |
4571 | + err = ip6_find_1stfragopt(skb, &prevhdr); |
4572 | + if (err < 0) |
4573 | + return ERR_PTR(err); |
4574 | + unfrag_ip6hlen = err; |
4575 | nexthdr = *prevhdr; |
4576 | *prevhdr = NEXTHDR_FRAGMENT; |
4577 | unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) + |
4578 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c |
4579 | index ea81ccf3c7d6..b2d8e8c23e46 100644 |
4580 | --- a/net/packet/af_packet.c |
4581 | +++ b/net/packet/af_packet.c |
4582 | @@ -2614,13 +2614,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) |
4583 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); |
4584 | } |
4585 | |
4586 | - sockc.tsflags = po->sk.sk_tsflags; |
4587 | - if (msg->msg_controllen) { |
4588 | - err = sock_cmsg_send(&po->sk, msg, &sockc); |
4589 | - if (unlikely(err)) |
4590 | - goto out; |
4591 | - } |
4592 | - |
4593 | err = -ENXIO; |
4594 | if (unlikely(dev == NULL)) |
4595 | goto out; |
4596 | @@ -2628,6 +2621,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) |
4597 | if (unlikely(!(dev->flags & IFF_UP))) |
4598 | goto out_put; |
4599 | |
4600 | + sockc.tsflags = po->sk.sk_tsflags; |
4601 | + if (msg->msg_controllen) { |
4602 | + err = sock_cmsg_send(&po->sk, msg, &sockc); |
4603 | + if (unlikely(err)) |
4604 | + goto out_put; |
4605 | + } |
4606 | + |
4607 | if (po->sk.sk_socket->type == SOCK_RAW) |
4608 | reserve = dev->hard_header_len; |
4609 | size_max = po->tx_ring.frame_size |
4610 | diff --git a/net/sctp/input.c b/net/sctp/input.c |
4611 | index 0e06a278d2a9..ba9ad32fc447 100644 |
4612 | --- a/net/sctp/input.c |
4613 | +++ b/net/sctp/input.c |
4614 | @@ -473,15 +473,14 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, |
4615 | struct sctp_association **app, |
4616 | struct sctp_transport **tpp) |
4617 | { |
4618 | + struct sctp_init_chunk *chunkhdr, _chunkhdr; |
4619 | union sctp_addr saddr; |
4620 | union sctp_addr daddr; |
4621 | struct sctp_af *af; |
4622 | struct sock *sk = NULL; |
4623 | struct sctp_association *asoc; |
4624 | struct sctp_transport *transport = NULL; |
4625 | - struct sctp_init_chunk *chunkhdr; |
4626 | __u32 vtag = ntohl(sctphdr->vtag); |
4627 | - int len = skb->len - ((void *)sctphdr - (void *)skb->data); |
4628 | |
4629 | *app = NULL; *tpp = NULL; |
4630 | |
4631 | @@ -516,13 +515,16 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, |
4632 | * discard the packet. |
4633 | */ |
4634 | if (vtag == 0) { |
4635 | - chunkhdr = (void *)sctphdr + sizeof(struct sctphdr); |
4636 | - if (len < sizeof(struct sctphdr) + sizeof(sctp_chunkhdr_t) |
4637 | - + sizeof(__be32) || |
4638 | + /* chunk header + first 4 octects of init header */ |
4639 | + chunkhdr = skb_header_pointer(skb, skb_transport_offset(skb) + |
4640 | + sizeof(struct sctphdr), |
4641 | + sizeof(struct sctp_chunkhdr) + |
4642 | + sizeof(__be32), &_chunkhdr); |
4643 | + if (!chunkhdr || |
4644 | chunkhdr->chunk_hdr.type != SCTP_CID_INIT || |
4645 | - ntohl(chunkhdr->init_hdr.init_tag) != asoc->c.my_vtag) { |
4646 | + ntohl(chunkhdr->init_hdr.init_tag) != asoc->c.my_vtag) |
4647 | goto out; |
4648 | - } |
4649 | + |
4650 | } else if (vtag != asoc->c.peer_vtag) { |
4651 | goto out; |
4652 | } |
4653 | diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c |
4654 | index 961ee59f696a..f5b45b8b8b16 100644 |
4655 | --- a/net/sctp/ipv6.c |
4656 | +++ b/net/sctp/ipv6.c |
4657 | @@ -240,12 +240,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, |
4658 | struct sctp_bind_addr *bp; |
4659 | struct ipv6_pinfo *np = inet6_sk(sk); |
4660 | struct sctp_sockaddr_entry *laddr; |
4661 | - union sctp_addr *baddr = NULL; |
4662 | union sctp_addr *daddr = &t->ipaddr; |
4663 | union sctp_addr dst_saddr; |
4664 | struct in6_addr *final_p, final; |
4665 | __u8 matchlen = 0; |
4666 | - __u8 bmatchlen; |
4667 | sctp_scope_t scope; |
4668 | |
4669 | memset(fl6, 0, sizeof(struct flowi6)); |
4670 | @@ -312,23 +310,37 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, |
4671 | */ |
4672 | rcu_read_lock(); |
4673 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { |
4674 | - if (!laddr->valid) |
4675 | + struct dst_entry *bdst; |
4676 | + __u8 bmatchlen; |
4677 | + |
4678 | + if (!laddr->valid || |
4679 | + laddr->state != SCTP_ADDR_SRC || |
4680 | + laddr->a.sa.sa_family != AF_INET6 || |
4681 | + scope > sctp_scope(&laddr->a)) |
4682 | continue; |
4683 | - if ((laddr->state == SCTP_ADDR_SRC) && |
4684 | - (laddr->a.sa.sa_family == AF_INET6) && |
4685 | - (scope <= sctp_scope(&laddr->a))) { |
4686 | - bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); |
4687 | - if (!baddr || (matchlen < bmatchlen)) { |
4688 | - baddr = &laddr->a; |
4689 | - matchlen = bmatchlen; |
4690 | - } |
4691 | - } |
4692 | - } |
4693 | - if (baddr) { |
4694 | - fl6->saddr = baddr->v6.sin6_addr; |
4695 | - fl6->fl6_sport = baddr->v6.sin6_port; |
4696 | + |
4697 | + fl6->saddr = laddr->a.v6.sin6_addr; |
4698 | + fl6->fl6_sport = laddr->a.v6.sin6_port; |
4699 | final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); |
4700 | - dst = ip6_dst_lookup_flow(sk, fl6, final_p); |
4701 | + bdst = ip6_dst_lookup_flow(sk, fl6, final_p); |
4702 | + |
4703 | + if (!IS_ERR(bdst) && |
4704 | + ipv6_chk_addr(dev_net(bdst->dev), |
4705 | + &laddr->a.v6.sin6_addr, bdst->dev, 1)) { |
4706 | + if (!IS_ERR_OR_NULL(dst)) |
4707 | + dst_release(dst); |
4708 | + dst = bdst; |
4709 | + break; |
4710 | + } |
4711 | + |
4712 | + bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); |
4713 | + if (matchlen > bmatchlen) |
4714 | + continue; |
4715 | + |
4716 | + if (!IS_ERR_OR_NULL(dst)) |
4717 | + dst_release(dst); |
4718 | + dst = bdst; |
4719 | + matchlen = bmatchlen; |
4720 | } |
4721 | rcu_read_unlock(); |
4722 | |
4723 | @@ -665,6 +677,9 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk, |
4724 | newnp = inet6_sk(newsk); |
4725 | |
4726 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); |
4727 | + newnp->ipv6_mc_list = NULL; |
4728 | + newnp->ipv6_ac_list = NULL; |
4729 | + newnp->ipv6_fl_list = NULL; |
4730 | |
4731 | rcu_read_lock(); |
4732 | opt = rcu_dereference(np->opt); |
4733 | diff --git a/net/smc/Kconfig b/net/smc/Kconfig |
4734 | index c717ef0896aa..33954852f3f8 100644 |
4735 | --- a/net/smc/Kconfig |
4736 | +++ b/net/smc/Kconfig |
4737 | @@ -8,6 +8,10 @@ config SMC |
4738 | The Linux implementation of the SMC-R solution is designed as |
4739 | a separate socket family SMC. |
4740 | |
4741 | + Warning: SMC will expose all memory for remote reads and writes |
4742 | + once a connection is established. Don't enable this option except |
4743 | + for tightly controlled lab environment. |
4744 | + |
4745 | Select this option if you want to run SMC socket applications |
4746 | |
4747 | config SMC_DIAG |
4748 | diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c |
4749 | index e41f594a1e1d..03ec058d18df 100644 |
4750 | --- a/net/smc/smc_clc.c |
4751 | +++ b/net/smc/smc_clc.c |
4752 | @@ -204,7 +204,7 @@ int smc_clc_send_confirm(struct smc_sock *smc) |
4753 | memcpy(&cclc.lcl.mac, &link->smcibdev->mac[link->ibport - 1], ETH_ALEN); |
4754 | hton24(cclc.qpn, link->roce_qp->qp_num); |
4755 | cclc.rmb_rkey = |
4756 | - htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey); |
4757 | + htonl(conn->rmb_desc->rkey[SMC_SINGLE_LINK]); |
4758 | cclc.conn_idx = 1; /* for now: 1 RMB = 1 RMBE */ |
4759 | cclc.rmbe_alert_token = htonl(conn->alert_token_local); |
4760 | cclc.qp_mtu = min(link->path_mtu, link->peer_mtu); |
4761 | @@ -256,7 +256,7 @@ int smc_clc_send_accept(struct smc_sock *new_smc, int srv_first_contact) |
4762 | memcpy(&aclc.lcl.mac, link->smcibdev->mac[link->ibport - 1], ETH_ALEN); |
4763 | hton24(aclc.qpn, link->roce_qp->qp_num); |
4764 | aclc.rmb_rkey = |
4765 | - htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey); |
4766 | + htonl(conn->rmb_desc->rkey[SMC_SINGLE_LINK]); |
4767 | aclc.conn_idx = 1; /* as long as 1 RMB = 1 RMBE */ |
4768 | aclc.rmbe_alert_token = htonl(conn->alert_token_local); |
4769 | aclc.qp_mtu = link->path_mtu; |
4770 | diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c |
4771 | index 0eac633fb354..88cbb8a22d4a 100644 |
4772 | --- a/net/smc/smc_core.c |
4773 | +++ b/net/smc/smc_core.c |
4774 | @@ -613,19 +613,8 @@ int smc_rmb_create(struct smc_sock *smc) |
4775 | rmb_desc = NULL; |
4776 | continue; /* if mapping failed, try smaller one */ |
4777 | } |
4778 | - rc = smc_ib_get_memory_region(lgr->lnk[SMC_SINGLE_LINK].roce_pd, |
4779 | - IB_ACCESS_REMOTE_WRITE | |
4780 | - IB_ACCESS_LOCAL_WRITE, |
4781 | - &rmb_desc->mr_rx[SMC_SINGLE_LINK]); |
4782 | - if (rc) { |
4783 | - smc_ib_buf_unmap(lgr->lnk[SMC_SINGLE_LINK].smcibdev, |
4784 | - tmp_bufsize, rmb_desc, |
4785 | - DMA_FROM_DEVICE); |
4786 | - kfree(rmb_desc->cpu_addr); |
4787 | - kfree(rmb_desc); |
4788 | - rmb_desc = NULL; |
4789 | - continue; |
4790 | - } |
4791 | + rmb_desc->rkey[SMC_SINGLE_LINK] = |
4792 | + lgr->lnk[SMC_SINGLE_LINK].roce_pd->unsafe_global_rkey; |
4793 | rmb_desc->used = 1; |
4794 | write_lock_bh(&lgr->rmbs_lock); |
4795 | list_add(&rmb_desc->list, |
4796 | @@ -668,6 +657,7 @@ int smc_rmb_rtoken_handling(struct smc_connection *conn, |
4797 | |
4798 | for (i = 0; i < SMC_RMBS_PER_LGR_MAX; i++) { |
4799 | if ((lgr->rtokens[i][SMC_SINGLE_LINK].rkey == rkey) && |
4800 | + (lgr->rtokens[i][SMC_SINGLE_LINK].dma_addr == dma_addr) && |
4801 | test_bit(i, lgr->rtokens_used_mask)) { |
4802 | conn->rtoken_idx = i; |
4803 | return 0; |
4804 | diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h |
4805 | index 27eb38056a27..b013cb43a327 100644 |
4806 | --- a/net/smc/smc_core.h |
4807 | +++ b/net/smc/smc_core.h |
4808 | @@ -93,7 +93,7 @@ struct smc_buf_desc { |
4809 | u64 dma_addr[SMC_LINKS_PER_LGR_MAX]; |
4810 | /* mapped address of buffer */ |
4811 | void *cpu_addr; /* virtual address of buffer */ |
4812 | - struct ib_mr *mr_rx[SMC_LINKS_PER_LGR_MAX]; |
4813 | + u32 rkey[SMC_LINKS_PER_LGR_MAX]; |
4814 | /* for rmb only: |
4815 | * rkey provided to peer |
4816 | */ |
4817 | diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c |
4818 | index e6743c008ac5..51e5f0124f31 100644 |
4819 | --- a/net/smc/smc_ib.c |
4820 | +++ b/net/smc/smc_ib.c |
4821 | @@ -37,24 +37,6 @@ u8 local_systemid[SMC_SYSTEMID_LEN] = SMC_LOCAL_SYSTEMID_RESET; /* unique system |
4822 | * identifier |
4823 | */ |
4824 | |
4825 | -int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags, |
4826 | - struct ib_mr **mr) |
4827 | -{ |
4828 | - int rc; |
4829 | - |
4830 | - if (*mr) |
4831 | - return 0; /* already done */ |
4832 | - |
4833 | - /* obtain unique key - |
4834 | - * next invocation of get_dma_mr returns a different key! |
4835 | - */ |
4836 | - *mr = pd->device->get_dma_mr(pd, access_flags); |
4837 | - rc = PTR_ERR_OR_ZERO(*mr); |
4838 | - if (IS_ERR(*mr)) |
4839 | - *mr = NULL; |
4840 | - return rc; |
4841 | -} |
4842 | - |
4843 | static int smc_ib_modify_qp_init(struct smc_link *lnk) |
4844 | { |
4845 | struct ib_qp_attr qp_attr; |
4846 | @@ -213,7 +195,8 @@ int smc_ib_create_protection_domain(struct smc_link *lnk) |
4847 | { |
4848 | int rc; |
4849 | |
4850 | - lnk->roce_pd = ib_alloc_pd(lnk->smcibdev->ibdev, 0); |
4851 | + lnk->roce_pd = ib_alloc_pd(lnk->smcibdev->ibdev, |
4852 | + IB_PD_UNSAFE_GLOBAL_RKEY); |
4853 | rc = PTR_ERR_OR_ZERO(lnk->roce_pd); |
4854 | if (IS_ERR(lnk->roce_pd)) |
4855 | lnk->roce_pd = NULL; |
4856 | diff --git a/net/smc/smc_ib.h b/net/smc/smc_ib.h |
4857 | index a95f74bb5569..cde21263287c 100644 |
4858 | --- a/net/smc/smc_ib.h |
4859 | +++ b/net/smc/smc_ib.h |
4860 | @@ -60,8 +60,6 @@ void smc_ib_dealloc_protection_domain(struct smc_link *lnk); |
4861 | int smc_ib_create_protection_domain(struct smc_link *lnk); |
4862 | void smc_ib_destroy_queue_pair(struct smc_link *lnk); |
4863 | int smc_ib_create_queue_pair(struct smc_link *lnk); |
4864 | -int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags, |
4865 | - struct ib_mr **mr); |
4866 | int smc_ib_ready_link(struct smc_link *lnk); |
4867 | int smc_ib_modify_qp_rts(struct smc_link *lnk); |
4868 | int smc_ib_modify_qp_reset(struct smc_link *lnk); |
4869 | diff --git a/net/tipc/socket.c b/net/tipc/socket.c |
4870 | index bdce99f9407a..599c69bca8b9 100644 |
4871 | --- a/net/tipc/socket.c |
4872 | +++ b/net/tipc/socket.c |
4873 | @@ -361,25 +361,25 @@ static int tipc_sk_sock_err(struct socket *sock, long *timeout) |
4874 | return 0; |
4875 | } |
4876 | |
4877 | -#define tipc_wait_for_cond(sock_, timeout_, condition_) \ |
4878 | -({ \ |
4879 | - int rc_ = 0; \ |
4880 | - int done_ = 0; \ |
4881 | - \ |
4882 | - while (!(condition_) && !done_) { \ |
4883 | - struct sock *sk_ = sock->sk; \ |
4884 | - DEFINE_WAIT_FUNC(wait_, woken_wake_function); \ |
4885 | - \ |
4886 | - rc_ = tipc_sk_sock_err(sock_, timeout_); \ |
4887 | - if (rc_) \ |
4888 | - break; \ |
4889 | - prepare_to_wait(sk_sleep(sk_), &wait_, \ |
4890 | - TASK_INTERRUPTIBLE); \ |
4891 | - done_ = sk_wait_event(sk_, timeout_, \ |
4892 | - (condition_), &wait_); \ |
4893 | - remove_wait_queue(sk_sleep(sk_), &wait_); \ |
4894 | - } \ |
4895 | - rc_; \ |
4896 | +#define tipc_wait_for_cond(sock_, timeo_, condition_) \ |
4897 | +({ \ |
4898 | + struct sock *sk_; \ |
4899 | + int rc_; \ |
4900 | + \ |
4901 | + while ((rc_ = !(condition_))) { \ |
4902 | + DEFINE_WAIT_FUNC(wait_, woken_wake_function); \ |
4903 | + sk_ = (sock_)->sk; \ |
4904 | + rc_ = tipc_sk_sock_err((sock_), timeo_); \ |
4905 | + if (rc_) \ |
4906 | + break; \ |
4907 | + prepare_to_wait(sk_sleep(sk_), &wait_, TASK_INTERRUPTIBLE); \ |
4908 | + release_sock(sk_); \ |
4909 | + *(timeo_) = wait_woken(&wait_, TASK_INTERRUPTIBLE, *(timeo_)); \ |
4910 | + sched_annotate_sleep(); \ |
4911 | + lock_sock(sk_); \ |
4912 | + remove_wait_queue(sk_sleep(sk_), &wait_); \ |
4913 | + } \ |
4914 | + rc_; \ |
4915 | }) |
4916 | |
4917 | /** |
4918 | diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c |
4919 | index 299835d1fbaa..1aa21d7e7245 100644 |
4920 | --- a/sound/pci/hda/patch_realtek.c |
4921 | +++ b/sound/pci/hda/patch_realtek.c |
4922 | @@ -6276,8 +6276,11 @@ static int patch_alc269(struct hda_codec *codec) |
4923 | break; |
4924 | case 0x10ec0225: |
4925 | case 0x10ec0295: |
4926 | + spec->codec_variant = ALC269_TYPE_ALC225; |
4927 | + break; |
4928 | case 0x10ec0299: |
4929 | spec->codec_variant = ALC269_TYPE_ALC225; |
4930 | + spec->gen.mixer_nid = 0; /* no loopback on ALC299 */ |
4931 | break; |
4932 | case 0x10ec0234: |
4933 | case 0x10ec0274: |
4934 | diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c |
4935 | index faa3d38bac0b..6cefdf6c0b75 100644 |
4936 | --- a/sound/pci/hda/patch_sigmatel.c |
4937 | +++ b/sound/pci/hda/patch_sigmatel.c |
4938 | @@ -1559,6 +1559,8 @@ static const struct snd_pci_quirk stac9200_fixup_tbl[] = { |
4939 | "Dell Inspiron 1501", STAC_9200_DELL_M26), |
4940 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6, |
4941 | "unknown Dell", STAC_9200_DELL_M26), |
4942 | + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0201, |
4943 | + "Dell Latitude D430", STAC_9200_DELL_M22), |
4944 | /* Panasonic */ |
4945 | SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), |
4946 | /* Gateway machines needs EAPD to be set on resume */ |
4947 | diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c |
4948 | index dc48eedea92e..442d8f7998e3 100644 |
4949 | --- a/sound/usb/mixer_us16x08.c |
4950 | +++ b/sound/usb/mixer_us16x08.c |
4951 | @@ -698,12 +698,12 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, |
4952 | struct snd_usb_audio *chip = elem->head.mixer->chip; |
4953 | struct snd_us16x08_meter_store *store = elem->private_data; |
4954 | u8 meter_urb[64]; |
4955 | - char tmp[sizeof(mix_init_msg2)] = {0}; |
4956 | + char tmp[max(sizeof(mix_init_msg1), sizeof(mix_init_msg2))]; |
4957 | |
4958 | switch (kcontrol->private_value) { |
4959 | case 0: |
4960 | - snd_us16x08_send_urb(chip, (char *)mix_init_msg1, |
4961 | - sizeof(mix_init_msg1)); |
4962 | + memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1)); |
4963 | + snd_us16x08_send_urb(chip, tmp, 4); |
4964 | snd_us16x08_recv_urb(chip, meter_urb, |
4965 | sizeof(meter_urb)); |
4966 | kcontrol->private_value++; |
4967 | @@ -721,7 +721,7 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, |
4968 | case 3: |
4969 | memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2)); |
4970 | tmp[2] = snd_get_meter_comp_index(store); |
4971 | - snd_us16x08_send_urb(chip, tmp, sizeof(mix_init_msg2)); |
4972 | + snd_us16x08_send_urb(chip, tmp, 10); |
4973 | snd_us16x08_recv_urb(chip, meter_urb, |
4974 | sizeof(meter_urb)); |
4975 | kcontrol->private_value = 0; |
4976 | @@ -1135,7 +1135,7 @@ static const struct snd_us16x08_control_params eq_controls[] = { |
4977 | .control_id = SND_US16X08_ID_EQLOWMIDWIDTH, |
4978 | .type = USB_MIXER_U8, |
4979 | .num_channels = 16, |
4980 | - .name = "EQ MidQLow Q", |
4981 | + .name = "EQ MidLow Q", |
4982 | }, |
4983 | { /* EQ mid high gain */ |
4984 | .kcontrol_new = &snd_us16x08_eq_gain_ctl, |