Annotation of /trunk/kernel-alx/patches-4.19/0156-4.19.57-all-fixes.patch
Parent Directory | Revision Log
Revision 3435 -
(hide annotations)
(download)
Fri Aug 2 11:48:02 2019 UTC (5 years, 1 month ago) by niro
File size: 136970 byte(s)
Fri Aug 2 11:48:02 2019 UTC (5 years, 1 month ago) by niro
File size: 136970 byte(s)
-linux-4.19.57
1 | niro | 3435 | diff --git a/Documentation/robust-futexes.txt b/Documentation/robust-futexes.txt |
2 | index 6c42c75103eb..6361fb01c9c1 100644 | ||
3 | --- a/Documentation/robust-futexes.txt | ||
4 | +++ b/Documentation/robust-futexes.txt | ||
5 | @@ -218,5 +218,4 @@ All other architectures should build just fine too - but they won't have | ||
6 | the new syscalls yet. | ||
7 | |||
8 | Architectures need to implement the new futex_atomic_cmpxchg_inatomic() | ||
9 | -inline function before writing up the syscalls (that function returns | ||
10 | --ENOSYS right now). | ||
11 | +inline function before writing up the syscalls. | ||
12 | diff --git a/Makefile b/Makefile | ||
13 | index a76c61f77bcd..5412d556b561 100644 | ||
14 | --- a/Makefile | ||
15 | +++ b/Makefile | ||
16 | @@ -1,7 +1,7 @@ | ||
17 | # SPDX-License-Identifier: GPL-2.0 | ||
18 | VERSION = 4 | ||
19 | PATCHLEVEL = 19 | ||
20 | -SUBLEVEL = 56 | ||
21 | +SUBLEVEL = 57 | ||
22 | EXTRAVERSION = | ||
23 | NAME = "People's Front" | ||
24 | |||
25 | diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile | ||
26 | index c12ff63265a9..5d8787f0ca5f 100644 | ||
27 | --- a/arch/arm64/Makefile | ||
28 | +++ b/arch/arm64/Makefile | ||
29 | @@ -51,7 +51,7 @@ endif | ||
30 | |||
31 | KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) $(brokengasinst) | ||
32 | KBUILD_CFLAGS += -fno-asynchronous-unwind-tables | ||
33 | -KBUILD_CFLAGS += -Wno-psabi | ||
34 | +KBUILD_CFLAGS += $(call cc-disable-warning, psabi) | ||
35 | KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) | ||
36 | |||
37 | KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) | ||
38 | diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h | ||
39 | index c7e30a6ed56e..232917e9c1d9 100644 | ||
40 | --- a/arch/arm64/include/asm/futex.h | ||
41 | +++ b/arch/arm64/include/asm/futex.h | ||
42 | @@ -134,7 +134,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *_uaddr, | ||
43 | : "memory"); | ||
44 | uaccess_disable(); | ||
45 | |||
46 | - *uval = val; | ||
47 | + if (!ret) | ||
48 | + *uval = val; | ||
49 | + | ||
50 | return ret; | ||
51 | } | ||
52 | |||
53 | diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h | ||
54 | index c6802dea6cab..310e47d54d81 100644 | ||
55 | --- a/arch/arm64/include/asm/insn.h | ||
56 | +++ b/arch/arm64/include/asm/insn.h | ||
57 | @@ -272,6 +272,7 @@ __AARCH64_INSN_FUNCS(adrp, 0x9F000000, 0x90000000) | ||
58 | __AARCH64_INSN_FUNCS(prfm, 0x3FC00000, 0x39800000) | ||
59 | __AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000) | ||
60 | __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800) | ||
61 | +__AARCH64_INSN_FUNCS(ldadd, 0x3F20FC00, 0x38200000) | ||
62 | __AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800) | ||
63 | __AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000) | ||
64 | __AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000) | ||
65 | @@ -389,6 +390,13 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg, | ||
66 | enum aarch64_insn_register state, | ||
67 | enum aarch64_insn_size_type size, | ||
68 | enum aarch64_insn_ldst_type type); | ||
69 | +u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result, | ||
70 | + enum aarch64_insn_register address, | ||
71 | + enum aarch64_insn_register value, | ||
72 | + enum aarch64_insn_size_type size); | ||
73 | +u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address, | ||
74 | + enum aarch64_insn_register value, | ||
75 | + enum aarch64_insn_size_type size); | ||
76 | u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst, | ||
77 | enum aarch64_insn_register src, | ||
78 | int imm, enum aarch64_insn_variant variant, | ||
79 | diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c | ||
80 | index 2b3413549734..3e6229e30109 100644 | ||
81 | --- a/arch/arm64/kernel/insn.c | ||
82 | +++ b/arch/arm64/kernel/insn.c | ||
83 | @@ -734,6 +734,46 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg, | ||
84 | state); | ||
85 | } | ||
86 | |||
87 | +u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result, | ||
88 | + enum aarch64_insn_register address, | ||
89 | + enum aarch64_insn_register value, | ||
90 | + enum aarch64_insn_size_type size) | ||
91 | +{ | ||
92 | + u32 insn = aarch64_insn_get_ldadd_value(); | ||
93 | + | ||
94 | + switch (size) { | ||
95 | + case AARCH64_INSN_SIZE_32: | ||
96 | + case AARCH64_INSN_SIZE_64: | ||
97 | + break; | ||
98 | + default: | ||
99 | + pr_err("%s: unimplemented size encoding %d\n", __func__, size); | ||
100 | + return AARCH64_BREAK_FAULT; | ||
101 | + } | ||
102 | + | ||
103 | + insn = aarch64_insn_encode_ldst_size(size, insn); | ||
104 | + | ||
105 | + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, | ||
106 | + result); | ||
107 | + | ||
108 | + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, | ||
109 | + address); | ||
110 | + | ||
111 | + return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn, | ||
112 | + value); | ||
113 | +} | ||
114 | + | ||
115 | +u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address, | ||
116 | + enum aarch64_insn_register value, | ||
117 | + enum aarch64_insn_size_type size) | ||
118 | +{ | ||
119 | + /* | ||
120 | + * STADD is simply encoded as an alias for LDADD with XZR as | ||
121 | + * the destination register. | ||
122 | + */ | ||
123 | + return aarch64_insn_gen_ldadd(AARCH64_INSN_REG_ZR, address, | ||
124 | + value, size); | ||
125 | +} | ||
126 | + | ||
127 | static u32 aarch64_insn_encode_prfm_imm(enum aarch64_insn_prfm_type type, | ||
128 | enum aarch64_insn_prfm_target target, | ||
129 | enum aarch64_insn_prfm_policy policy, | ||
130 | diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h | ||
131 | index 6c881659ee8a..76606e87233f 100644 | ||
132 | --- a/arch/arm64/net/bpf_jit.h | ||
133 | +++ b/arch/arm64/net/bpf_jit.h | ||
134 | @@ -100,6 +100,10 @@ | ||
135 | #define A64_STXR(sf, Rt, Rn, Rs) \ | ||
136 | A64_LSX(sf, Rt, Rn, Rs, STORE_EX) | ||
137 | |||
138 | +/* LSE atomics */ | ||
139 | +#define A64_STADD(sf, Rn, Rs) \ | ||
140 | + aarch64_insn_gen_stadd(Rn, Rs, A64_SIZE(sf)) | ||
141 | + | ||
142 | /* Add/subtract (immediate) */ | ||
143 | #define A64_ADDSUB_IMM(sf, Rd, Rn, imm12, type) \ | ||
144 | aarch64_insn_gen_add_sub_imm(Rd, Rn, imm12, \ | ||
145 | diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c | ||
146 | index 2eef156b38bb..7f0258ed1f5f 100644 | ||
147 | --- a/arch/arm64/net/bpf_jit_comp.c | ||
148 | +++ b/arch/arm64/net/bpf_jit_comp.c | ||
149 | @@ -364,7 +364,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) | ||
150 | const int i = insn - ctx->prog->insnsi; | ||
151 | const bool is64 = BPF_CLASS(code) == BPF_ALU64; | ||
152 | const bool isdw = BPF_SIZE(code) == BPF_DW; | ||
153 | - u8 jmp_cond; | ||
154 | + u8 jmp_cond, reg; | ||
155 | s32 jmp_offset; | ||
156 | |||
157 | #define check_imm(bits, imm) do { \ | ||
158 | @@ -730,18 +730,28 @@ emit_cond_jmp: | ||
159 | break; | ||
160 | } | ||
161 | break; | ||
162 | + | ||
163 | /* STX XADD: lock *(u32 *)(dst + off) += src */ | ||
164 | case BPF_STX | BPF_XADD | BPF_W: | ||
165 | /* STX XADD: lock *(u64 *)(dst + off) += src */ | ||
166 | case BPF_STX | BPF_XADD | BPF_DW: | ||
167 | - emit_a64_mov_i(1, tmp, off, ctx); | ||
168 | - emit(A64_ADD(1, tmp, tmp, dst), ctx); | ||
169 | - emit(A64_LDXR(isdw, tmp2, tmp), ctx); | ||
170 | - emit(A64_ADD(isdw, tmp2, tmp2, src), ctx); | ||
171 | - emit(A64_STXR(isdw, tmp2, tmp, tmp3), ctx); | ||
172 | - jmp_offset = -3; | ||
173 | - check_imm19(jmp_offset); | ||
174 | - emit(A64_CBNZ(0, tmp3, jmp_offset), ctx); | ||
175 | + if (!off) { | ||
176 | + reg = dst; | ||
177 | + } else { | ||
178 | + emit_a64_mov_i(1, tmp, off, ctx); | ||
179 | + emit(A64_ADD(1, tmp, tmp, dst), ctx); | ||
180 | + reg = tmp; | ||
181 | + } | ||
182 | + if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS)) { | ||
183 | + emit(A64_STADD(isdw, reg, src), ctx); | ||
184 | + } else { | ||
185 | + emit(A64_LDXR(isdw, tmp2, reg), ctx); | ||
186 | + emit(A64_ADD(isdw, tmp2, tmp2, src), ctx); | ||
187 | + emit(A64_STXR(isdw, tmp2, reg, tmp3), ctx); | ||
188 | + jmp_offset = -3; | ||
189 | + check_imm19(jmp_offset); | ||
190 | + emit(A64_CBNZ(0, tmp3, jmp_offset), ctx); | ||
191 | + } | ||
192 | break; | ||
193 | |||
194 | default: | ||
195 | diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h | ||
196 | index 558059a8f218..0277b56157af 100644 | ||
197 | --- a/arch/mips/include/asm/mips-gic.h | ||
198 | +++ b/arch/mips/include/asm/mips-gic.h | ||
199 | @@ -314,6 +314,36 @@ static inline bool mips_gic_present(void) | ||
200 | return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base; | ||
201 | } | ||
202 | |||
203 | +/** | ||
204 | + * mips_gic_vx_map_reg() - Return GIC_Vx_<intr>_MAP register offset | ||
205 | + * @intr: A GIC local interrupt | ||
206 | + * | ||
207 | + * Determine the index of the GIC_VL_<intr>_MAP or GIC_VO_<intr>_MAP register | ||
208 | + * within the block of GIC map registers. This is almost the same as the order | ||
209 | + * of interrupts in the pending & mask registers, as used by enum | ||
210 | + * mips_gic_local_interrupt, but moves the FDC interrupt & thus offsets the | ||
211 | + * interrupts after it... | ||
212 | + * | ||
213 | + * Return: The map register index corresponding to @intr. | ||
214 | + * | ||
215 | + * The return value is suitable for use with the (read|write)_gic_v[lo]_map | ||
216 | + * accessor functions. | ||
217 | + */ | ||
218 | +static inline unsigned int | ||
219 | +mips_gic_vx_map_reg(enum mips_gic_local_interrupt intr) | ||
220 | +{ | ||
221 | + /* WD, Compare & Timer are 1:1 */ | ||
222 | + if (intr <= GIC_LOCAL_INT_TIMER) | ||
223 | + return intr; | ||
224 | + | ||
225 | + /* FDC moves to after Timer... */ | ||
226 | + if (intr == GIC_LOCAL_INT_FDC) | ||
227 | + return GIC_LOCAL_INT_TIMER + 1; | ||
228 | + | ||
229 | + /* As a result everything else is offset by 1 */ | ||
230 | + return intr + 1; | ||
231 | +} | ||
232 | + | ||
233 | /** | ||
234 | * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq | ||
235 | * | ||
236 | diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c | ||
237 | index 9b096f26d1c8..a5cde748cf76 100644 | ||
238 | --- a/arch/x86/kernel/cpu/bugs.c | ||
239 | +++ b/arch/x86/kernel/cpu/bugs.c | ||
240 | @@ -820,6 +820,16 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void) | ||
241 | break; | ||
242 | } | ||
243 | |||
244 | + /* | ||
245 | + * If SSBD is controlled by the SPEC_CTRL MSR, then set the proper | ||
246 | + * bit in the mask to allow guests to use the mitigation even in the | ||
247 | + * case where the host does not enable it. | ||
248 | + */ | ||
249 | + if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) || | ||
250 | + static_cpu_has(X86_FEATURE_AMD_SSBD)) { | ||
251 | + x86_spec_ctrl_mask |= SPEC_CTRL_SSBD; | ||
252 | + } | ||
253 | + | ||
254 | /* | ||
255 | * We have three CPU feature flags that are in play here: | ||
256 | * - X86_BUG_SPEC_STORE_BYPASS - CPU is susceptible. | ||
257 | @@ -837,7 +847,6 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void) | ||
258 | x86_amd_ssb_disable(); | ||
259 | } else { | ||
260 | x86_spec_ctrl_base |= SPEC_CTRL_SSBD; | ||
261 | - x86_spec_ctrl_mask |= SPEC_CTRL_SSBD; | ||
262 | wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); | ||
263 | } | ||
264 | } | ||
265 | diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | ||
266 | index 274d220d0a83..2013699a5c54 100644 | ||
267 | --- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | ||
268 | +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | ||
269 | @@ -792,8 +792,12 @@ static int rdt_bit_usage_show(struct kernfs_open_file *of, | ||
270 | struct seq_file *seq, void *v) | ||
271 | { | ||
272 | struct rdt_resource *r = of->kn->parent->priv; | ||
273 | - u32 sw_shareable = 0, hw_shareable = 0; | ||
274 | - u32 exclusive = 0, pseudo_locked = 0; | ||
275 | + /* | ||
276 | + * Use unsigned long even though only 32 bits are used to ensure | ||
277 | + * test_bit() is used safely. | ||
278 | + */ | ||
279 | + unsigned long sw_shareable = 0, hw_shareable = 0; | ||
280 | + unsigned long exclusive = 0, pseudo_locked = 0; | ||
281 | struct rdt_domain *dom; | ||
282 | int i, hwb, swb, excl, psl; | ||
283 | enum rdtgrp_mode mode; | ||
284 | @@ -838,10 +842,10 @@ static int rdt_bit_usage_show(struct kernfs_open_file *of, | ||
285 | } | ||
286 | for (i = r->cache.cbm_len - 1; i >= 0; i--) { | ||
287 | pseudo_locked = dom->plr ? dom->plr->cbm : 0; | ||
288 | - hwb = test_bit(i, (unsigned long *)&hw_shareable); | ||
289 | - swb = test_bit(i, (unsigned long *)&sw_shareable); | ||
290 | - excl = test_bit(i, (unsigned long *)&exclusive); | ||
291 | - psl = test_bit(i, (unsigned long *)&pseudo_locked); | ||
292 | + hwb = test_bit(i, &hw_shareable); | ||
293 | + swb = test_bit(i, &sw_shareable); | ||
294 | + excl = test_bit(i, &exclusive); | ||
295 | + psl = test_bit(i, &pseudo_locked); | ||
296 | if (hwb && swb) | ||
297 | seq_putc(seq, 'X'); | ||
298 | else if (hwb && !swb) | ||
299 | @@ -2320,26 +2324,19 @@ out_destroy: | ||
300 | */ | ||
301 | static void cbm_ensure_valid(u32 *_val, struct rdt_resource *r) | ||
302 | { | ||
303 | - /* | ||
304 | - * Convert the u32 _val to an unsigned long required by all the bit | ||
305 | - * operations within this function. No more than 32 bits of this | ||
306 | - * converted value can be accessed because all bit operations are | ||
307 | - * additionally provided with cbm_len that is initialized during | ||
308 | - * hardware enumeration using five bits from the EAX register and | ||
309 | - * thus never can exceed 32 bits. | ||
310 | - */ | ||
311 | - unsigned long *val = (unsigned long *)_val; | ||
312 | + unsigned long val = *_val; | ||
313 | unsigned int cbm_len = r->cache.cbm_len; | ||
314 | unsigned long first_bit, zero_bit; | ||
315 | |||
316 | - if (*val == 0) | ||
317 | + if (val == 0) | ||
318 | return; | ||
319 | |||
320 | - first_bit = find_first_bit(val, cbm_len); | ||
321 | - zero_bit = find_next_zero_bit(val, cbm_len, first_bit); | ||
322 | + first_bit = find_first_bit(&val, cbm_len); | ||
323 | + zero_bit = find_next_zero_bit(&val, cbm_len, first_bit); | ||
324 | |||
325 | /* Clear any remaining bits to ensure contiguous region */ | ||
326 | - bitmap_clear(val, zero_bit, cbm_len - zero_bit); | ||
327 | + bitmap_clear(&val, zero_bit, cbm_len - zero_bit); | ||
328 | + *_val = (u32)val; | ||
329 | } | ||
330 | |||
331 | /** | ||
332 | diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c | ||
333 | index b7027e667604..a96091d44a45 100644 | ||
334 | --- a/arch/x86/kernel/cpu/microcode/core.c | ||
335 | +++ b/arch/x86/kernel/cpu/microcode/core.c | ||
336 | @@ -790,13 +790,16 @@ static struct syscore_ops mc_syscore_ops = { | ||
337 | .resume = mc_bp_resume, | ||
338 | }; | ||
339 | |||
340 | -static int mc_cpu_online(unsigned int cpu) | ||
341 | +static int mc_cpu_starting(unsigned int cpu) | ||
342 | { | ||
343 | - struct device *dev; | ||
344 | - | ||
345 | - dev = get_cpu_device(cpu); | ||
346 | microcode_update_cpu(cpu); | ||
347 | pr_debug("CPU%d added\n", cpu); | ||
348 | + return 0; | ||
349 | +} | ||
350 | + | ||
351 | +static int mc_cpu_online(unsigned int cpu) | ||
352 | +{ | ||
353 | + struct device *dev = get_cpu_device(cpu); | ||
354 | |||
355 | if (sysfs_create_group(&dev->kobj, &mc_attr_group)) | ||
356 | pr_err("Failed to create group for CPU%d\n", cpu); | ||
357 | @@ -873,7 +876,9 @@ int __init microcode_init(void) | ||
358 | goto out_ucode_group; | ||
359 | |||
360 | register_syscore_ops(&mc_syscore_ops); | ||
361 | - cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:online", | ||
362 | + cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:starting", | ||
363 | + mc_cpu_starting, NULL); | ||
364 | + cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/microcode:online", | ||
365 | mc_cpu_online, mc_cpu_down_prep); | ||
366 | |||
367 | pr_info("Microcode Update Driver: v%s.", DRIVER_VERSION); | ||
368 | diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c | ||
369 | index 779ed52047d1..e0f982e35c96 100644 | ||
370 | --- a/arch/x86/kvm/mmu.c | ||
371 | +++ b/arch/x86/kvm/mmu.c | ||
372 | @@ -5386,7 +5386,16 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu) | ||
373 | struct page *page; | ||
374 | int i; | ||
375 | |||
376 | - if (tdp_enabled) | ||
377 | + /* | ||
378 | + * When using PAE paging, the four PDPTEs are treated as 'root' pages, | ||
379 | + * while the PDP table is a per-vCPU construct that's allocated at MMU | ||
380 | + * creation. When emulating 32-bit mode, cr3 is only 32 bits even on | ||
381 | + * x86_64. Therefore we need to allocate the PDP table in the first | ||
382 | + * 4GB of memory, which happens to fit the DMA32 zone. Except for | ||
383 | + * SVM's 32-bit NPT support, TDP paging doesn't use PAE paging and can | ||
384 | + * skip allocating the PDP table. | ||
385 | + */ | ||
386 | + if (tdp_enabled && kvm_x86_ops->get_tdp_level(vcpu) > PT32E_ROOT_LEVEL) | ||
387 | return 0; | ||
388 | |||
389 | /* | ||
390 | diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c | ||
391 | index 8281dfbf38c2..5bed36e12951 100644 | ||
392 | --- a/drivers/clk/socfpga/clk-s10.c | ||
393 | +++ b/drivers/clk/socfpga/clk-s10.c | ||
394 | @@ -103,9 +103,9 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { | ||
395 | { STRATIX10_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), | ||
396 | 0, 0, 0, 0x3C, 1}, | ||
397 | { STRATIX10_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux), | ||
398 | - 0, 0, 4, 0xB0, 0}, | ||
399 | + 0, 0, 2, 0xB0, 0}, | ||
400 | { STRATIX10_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux), | ||
401 | - 0, 0, 4, 0xB0, 1}, | ||
402 | + 0, 0, 2, 0xB0, 1}, | ||
403 | { STRATIX10_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL, emac_ptp_free_mux, | ||
404 | ARRAY_SIZE(emac_ptp_free_mux), 0, 0, 4, 0xB0, 2}, | ||
405 | { STRATIX10_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux, | ||
406 | diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c | ||
407 | index 46b855a42884..9e5f70e7122a 100644 | ||
408 | --- a/drivers/infiniband/core/addr.c | ||
409 | +++ b/drivers/infiniband/core/addr.c | ||
410 | @@ -716,22 +716,22 @@ int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid, | ||
411 | struct rdma_dev_addr dev_addr; | ||
412 | struct resolve_cb_context ctx; | ||
413 | union { | ||
414 | - struct sockaddr _sockaddr; | ||
415 | struct sockaddr_in _sockaddr_in; | ||
416 | struct sockaddr_in6 _sockaddr_in6; | ||
417 | } sgid_addr, dgid_addr; | ||
418 | int ret; | ||
419 | |||
420 | - rdma_gid2ip(&sgid_addr._sockaddr, sgid); | ||
421 | - rdma_gid2ip(&dgid_addr._sockaddr, dgid); | ||
422 | + rdma_gid2ip((struct sockaddr *)&sgid_addr, sgid); | ||
423 | + rdma_gid2ip((struct sockaddr *)&dgid_addr, dgid); | ||
424 | |||
425 | memset(&dev_addr, 0, sizeof(dev_addr)); | ||
426 | dev_addr.bound_dev_if = ndev->ifindex; | ||
427 | dev_addr.net = &init_net; | ||
428 | |||
429 | init_completion(&ctx.comp); | ||
430 | - ret = rdma_resolve_ip(&sgid_addr._sockaddr, &dgid_addr._sockaddr, | ||
431 | - &dev_addr, 1000, resolve_cb, &ctx); | ||
432 | + ret = rdma_resolve_ip((struct sockaddr *)&sgid_addr, | ||
433 | + (struct sockaddr *)&dgid_addr, &dev_addr, 1000, | ||
434 | + resolve_cb, &ctx); | ||
435 | if (ret) | ||
436 | return ret; | ||
437 | |||
438 | diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c | ||
439 | index 51831bfbf90f..cbff746d9e9d 100644 | ||
440 | --- a/drivers/infiniband/hw/hfi1/user_sdma.c | ||
441 | +++ b/drivers/infiniband/hw/hfi1/user_sdma.c | ||
442 | @@ -132,25 +132,22 @@ static int defer_packet_queue( | ||
443 | struct hfi1_user_sdma_pkt_q *pq = | ||
444 | container_of(wait, struct hfi1_user_sdma_pkt_q, busy); | ||
445 | struct hfi1_ibdev *dev = &pq->dd->verbs_dev; | ||
446 | - struct user_sdma_txreq *tx = | ||
447 | - container_of(txreq, struct user_sdma_txreq, txreq); | ||
448 | |||
449 | - if (sdma_progress(sde, seq, txreq)) { | ||
450 | - if (tx->busycount++ < MAX_DEFER_RETRY_COUNT) | ||
451 | - goto eagain; | ||
452 | - } | ||
453 | + write_seqlock(&dev->iowait_lock); | ||
454 | + if (sdma_progress(sde, seq, txreq)) | ||
455 | + goto eagain; | ||
456 | /* | ||
457 | * We are assuming that if the list is enqueued somewhere, it | ||
458 | * is to the dmawait list since that is the only place where | ||
459 | * it is supposed to be enqueued. | ||
460 | */ | ||
461 | xchg(&pq->state, SDMA_PKT_Q_DEFERRED); | ||
462 | - write_seqlock(&dev->iowait_lock); | ||
463 | if (list_empty(&pq->busy.list)) | ||
464 | iowait_queue(pkts_sent, &pq->busy, &sde->dmawait); | ||
465 | write_sequnlock(&dev->iowait_lock); | ||
466 | return -EBUSY; | ||
467 | eagain: | ||
468 | + write_sequnlock(&dev->iowait_lock); | ||
469 | return -EAGAIN; | ||
470 | } | ||
471 | |||
472 | @@ -803,7 +800,6 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) | ||
473 | |||
474 | tx->flags = 0; | ||
475 | tx->req = req; | ||
476 | - tx->busycount = 0; | ||
477 | INIT_LIST_HEAD(&tx->list); | ||
478 | |||
479 | /* | ||
480 | diff --git a/drivers/infiniband/hw/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h | ||
481 | index 91c343f91776..2c056702d975 100644 | ||
482 | --- a/drivers/infiniband/hw/hfi1/user_sdma.h | ||
483 | +++ b/drivers/infiniband/hw/hfi1/user_sdma.h | ||
484 | @@ -245,7 +245,6 @@ struct user_sdma_txreq { | ||
485 | struct list_head list; | ||
486 | struct user_sdma_request *req; | ||
487 | u16 flags; | ||
488 | - unsigned int busycount; | ||
489 | u64 seqnum; | ||
490 | }; | ||
491 | |||
492 | diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c | ||
493 | index 58188fe5aed2..32aaa4ef481c 100644 | ||
494 | --- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c | ||
495 | +++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c | ||
496 | @@ -83,7 +83,6 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, | ||
497 | struct iphdr ipv4; | ||
498 | const struct ib_global_route *ib_grh; | ||
499 | union { | ||
500 | - struct sockaddr _sockaddr; | ||
501 | struct sockaddr_in _sockaddr_in; | ||
502 | struct sockaddr_in6 _sockaddr_in6; | ||
503 | } sgid_addr, dgid_addr; | ||
504 | @@ -133,9 +132,9 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, | ||
505 | ipv4.tot_len = htons(0); | ||
506 | ipv4.ttl = ib_grh->hop_limit; | ||
507 | ipv4.protocol = nxthdr; | ||
508 | - rdma_gid2ip(&sgid_addr._sockaddr, sgid); | ||
509 | + rdma_gid2ip((struct sockaddr *)&sgid_addr, sgid); | ||
510 | ipv4.saddr = sgid_addr._sockaddr_in.sin_addr.s_addr; | ||
511 | - rdma_gid2ip(&dgid_addr._sockaddr, &ib_grh->dgid); | ||
512 | + rdma_gid2ip((struct sockaddr*)&dgid_addr, &ib_grh->dgid); | ||
513 | ipv4.daddr = dgid_addr._sockaddr_in.sin_addr.s_addr; | ||
514 | memcpy((u8 *)ah->av + eth_sz, &ipv4, sizeof(struct iphdr)); | ||
515 | } else { | ||
516 | diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c | ||
517 | index e578281471af..28181f01734c 100644 | ||
518 | --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c | ||
519 | +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c | ||
520 | @@ -2499,7 +2499,6 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp, | ||
521 | u32 vlan_id = 0xFFFF; | ||
522 | u8 mac_addr[6], hdr_type; | ||
523 | union { | ||
524 | - struct sockaddr _sockaddr; | ||
525 | struct sockaddr_in _sockaddr_in; | ||
526 | struct sockaddr_in6 _sockaddr_in6; | ||
527 | } sgid_addr, dgid_addr; | ||
528 | @@ -2541,8 +2540,8 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp, | ||
529 | |||
530 | hdr_type = rdma_gid_attr_network_type(sgid_attr); | ||
531 | if (hdr_type == RDMA_NETWORK_IPV4) { | ||
532 | - rdma_gid2ip(&sgid_addr._sockaddr, &sgid_attr->gid); | ||
533 | - rdma_gid2ip(&dgid_addr._sockaddr, &grh->dgid); | ||
534 | + rdma_gid2ip((struct sockaddr *)&sgid_addr, &sgid_attr->gid); | ||
535 | + rdma_gid2ip((struct sockaddr *)&dgid_addr, &grh->dgid); | ||
536 | memcpy(&cmd->params.dgid[0], | ||
537 | &dgid_addr._sockaddr_in.sin_addr.s_addr, 4); | ||
538 | memcpy(&cmd->params.sgid[0], | ||
539 | diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c | ||
540 | index d32268cc1174..f3985469c221 100644 | ||
541 | --- a/drivers/irqchip/irq-mips-gic.c | ||
542 | +++ b/drivers/irqchip/irq-mips-gic.c | ||
543 | @@ -388,7 +388,7 @@ static void gic_all_vpes_irq_cpu_online(struct irq_data *d) | ||
544 | intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); | ||
545 | cd = irq_data_get_irq_chip_data(d); | ||
546 | |||
547 | - write_gic_vl_map(intr, cd->map); | ||
548 | + write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map); | ||
549 | if (cd->mask) | ||
550 | write_gic_vl_smask(BIT(intr)); | ||
551 | } | ||
552 | @@ -517,7 +517,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, | ||
553 | spin_lock_irqsave(&gic_lock, flags); | ||
554 | for_each_online_cpu(cpu) { | ||
555 | write_gic_vl_other(mips_cm_vp_id(cpu)); | ||
556 | - write_gic_vo_map(intr, map); | ||
557 | + write_gic_vo_map(mips_gic_vx_map_reg(intr), map); | ||
558 | } | ||
559 | spin_unlock_irqrestore(&gic_lock, flags); | ||
560 | |||
561 | diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c | ||
562 | index 9ea2b0291f20..e549392e0ea5 100644 | ||
563 | --- a/drivers/md/dm-log-writes.c | ||
564 | +++ b/drivers/md/dm-log-writes.c | ||
565 | @@ -60,6 +60,7 @@ | ||
566 | |||
567 | #define WRITE_LOG_VERSION 1ULL | ||
568 | #define WRITE_LOG_MAGIC 0x6a736677736872ULL | ||
569 | +#define WRITE_LOG_SUPER_SECTOR 0 | ||
570 | |||
571 | /* | ||
572 | * The disk format for this is braindead simple. | ||
573 | @@ -115,6 +116,7 @@ struct log_writes_c { | ||
574 | struct list_head logging_blocks; | ||
575 | wait_queue_head_t wait; | ||
576 | struct task_struct *log_kthread; | ||
577 | + struct completion super_done; | ||
578 | }; | ||
579 | |||
580 | struct pending_block { | ||
581 | @@ -180,6 +182,14 @@ static void log_end_io(struct bio *bio) | ||
582 | bio_put(bio); | ||
583 | } | ||
584 | |||
585 | +static void log_end_super(struct bio *bio) | ||
586 | +{ | ||
587 | + struct log_writes_c *lc = bio->bi_private; | ||
588 | + | ||
589 | + complete(&lc->super_done); | ||
590 | + log_end_io(bio); | ||
591 | +} | ||
592 | + | ||
593 | /* | ||
594 | * Meant to be called if there is an error, it will free all the pages | ||
595 | * associated with the block. | ||
596 | @@ -215,7 +225,8 @@ static int write_metadata(struct log_writes_c *lc, void *entry, | ||
597 | bio->bi_iter.bi_size = 0; | ||
598 | bio->bi_iter.bi_sector = sector; | ||
599 | bio_set_dev(bio, lc->logdev->bdev); | ||
600 | - bio->bi_end_io = log_end_io; | ||
601 | + bio->bi_end_io = (sector == WRITE_LOG_SUPER_SECTOR) ? | ||
602 | + log_end_super : log_end_io; | ||
603 | bio->bi_private = lc; | ||
604 | bio_set_op_attrs(bio, REQ_OP_WRITE, 0); | ||
605 | |||
606 | @@ -418,11 +429,18 @@ static int log_super(struct log_writes_c *lc) | ||
607 | super.nr_entries = cpu_to_le64(lc->logged_entries); | ||
608 | super.sectorsize = cpu_to_le32(lc->sectorsize); | ||
609 | |||
610 | - if (write_metadata(lc, &super, sizeof(super), NULL, 0, 0)) { | ||
611 | + if (write_metadata(lc, &super, sizeof(super), NULL, 0, | ||
612 | + WRITE_LOG_SUPER_SECTOR)) { | ||
613 | DMERR("Couldn't write super"); | ||
614 | return -1; | ||
615 | } | ||
616 | |||
617 | + /* | ||
618 | + * Super sector should be writen in-order, otherwise the | ||
619 | + * nr_entries could be rewritten incorrectly by an old bio. | ||
620 | + */ | ||
621 | + wait_for_completion_io(&lc->super_done); | ||
622 | + | ||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | @@ -531,6 +549,7 @@ static int log_writes_ctr(struct dm_target *ti, unsigned int argc, char **argv) | ||
627 | INIT_LIST_HEAD(&lc->unflushed_blocks); | ||
628 | INIT_LIST_HEAD(&lc->logging_blocks); | ||
629 | init_waitqueue_head(&lc->wait); | ||
630 | + init_completion(&lc->super_done); | ||
631 | atomic_set(&lc->io_blocks, 0); | ||
632 | atomic_set(&lc->pending_blocks, 0); | ||
633 | |||
634 | diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c | ||
635 | index 94836fcbe721..ddfcf4ade7bf 100644 | ||
636 | --- a/drivers/misc/eeprom/at24.c | ||
637 | +++ b/drivers/misc/eeprom/at24.c | ||
638 | @@ -106,23 +106,6 @@ static unsigned int at24_write_timeout = 25; | ||
639 | module_param_named(write_timeout, at24_write_timeout, uint, 0); | ||
640 | MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)"); | ||
641 | |||
642 | -/* | ||
643 | - * Both reads and writes fail if the previous write didn't complete yet. This | ||
644 | - * macro loops a few times waiting at least long enough for one entire page | ||
645 | - * write to work while making sure that at least one iteration is run before | ||
646 | - * checking the break condition. | ||
647 | - * | ||
648 | - * It takes two parameters: a variable in which the future timeout in jiffies | ||
649 | - * will be stored and a temporary variable holding the time of the last | ||
650 | - * iteration of processing the request. Both should be unsigned integers | ||
651 | - * holding at least 32 bits. | ||
652 | - */ | ||
653 | -#define at24_loop_until_timeout(tout, op_time) \ | ||
654 | - for (tout = jiffies + msecs_to_jiffies(at24_write_timeout), \ | ||
655 | - op_time = 0; \ | ||
656 | - op_time ? time_before(op_time, tout) : true; \ | ||
657 | - usleep_range(1000, 1500), op_time = jiffies) | ||
658 | - | ||
659 | struct at24_chip_data { | ||
660 | /* | ||
661 | * these fields mirror their equivalents in | ||
662 | @@ -311,13 +294,22 @@ static ssize_t at24_regmap_read(struct at24_data *at24, char *buf, | ||
663 | /* adjust offset for mac and serial read ops */ | ||
664 | offset += at24->offset_adj; | ||
665 | |||
666 | - at24_loop_until_timeout(timeout, read_time) { | ||
667 | + timeout = jiffies + msecs_to_jiffies(at24_write_timeout); | ||
668 | + do { | ||
669 | + /* | ||
670 | + * The timestamp shall be taken before the actual operation | ||
671 | + * to avoid a premature timeout in case of high CPU load. | ||
672 | + */ | ||
673 | + read_time = jiffies; | ||
674 | + | ||
675 | ret = regmap_bulk_read(regmap, offset, buf, count); | ||
676 | dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", | ||
677 | count, offset, ret, jiffies); | ||
678 | if (!ret) | ||
679 | return count; | ||
680 | - } | ||
681 | + | ||
682 | + usleep_range(1000, 1500); | ||
683 | + } while (time_before(read_time, timeout)); | ||
684 | |||
685 | return -ETIMEDOUT; | ||
686 | } | ||
687 | @@ -361,14 +353,23 @@ static ssize_t at24_regmap_write(struct at24_data *at24, const char *buf, | ||
688 | regmap = at24_client->regmap; | ||
689 | client = at24_client->client; | ||
690 | count = at24_adjust_write_count(at24, offset, count); | ||
691 | + timeout = jiffies + msecs_to_jiffies(at24_write_timeout); | ||
692 | + | ||
693 | + do { | ||
694 | + /* | ||
695 | + * The timestamp shall be taken before the actual operation | ||
696 | + * to avoid a premature timeout in case of high CPU load. | ||
697 | + */ | ||
698 | + write_time = jiffies; | ||
699 | |||
700 | - at24_loop_until_timeout(timeout, write_time) { | ||
701 | ret = regmap_bulk_write(regmap, offset, buf, count); | ||
702 | dev_dbg(&client->dev, "write %zu@%d --> %d (%ld)\n", | ||
703 | count, offset, ret, jiffies); | ||
704 | if (!ret) | ||
705 | return count; | ||
706 | - } | ||
707 | + | ||
708 | + usleep_range(1000, 1500); | ||
709 | + } while (time_before(write_time, timeout)); | ||
710 | |||
711 | return -ETIMEDOUT; | ||
712 | } | ||
713 | diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c | ||
714 | index 039beb5e0fa2..7e162fff01ab 100644 | ||
715 | --- a/drivers/net/bonding/bond_main.c | ||
716 | +++ b/drivers/net/bonding/bond_main.c | ||
717 | @@ -4307,12 +4307,12 @@ void bond_setup(struct net_device *bond_dev) | ||
718 | bond_dev->features |= NETIF_F_NETNS_LOCAL; | ||
719 | |||
720 | bond_dev->hw_features = BOND_VLAN_FEATURES | | ||
721 | - NETIF_F_HW_VLAN_CTAG_TX | | ||
722 | NETIF_F_HW_VLAN_CTAG_RX | | ||
723 | NETIF_F_HW_VLAN_CTAG_FILTER; | ||
724 | |||
725 | bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4; | ||
726 | bond_dev->features |= bond_dev->hw_features; | ||
727 | + bond_dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX; | ||
728 | } | ||
729 | |||
730 | /* Destroy a bonding device. | ||
731 | diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | ||
732 | index 8d9cc2157afd..7423262ce590 100644 | ||
733 | --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | ||
734 | +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | ||
735 | @@ -122,7 +122,7 @@ static int adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec, | ||
736 | * programmed with (2^32 – <new_sec_value>) | ||
737 | */ | ||
738 | if (gmac4) | ||
739 | - sec = (100000000ULL - sec); | ||
740 | + sec = -sec; | ||
741 | |||
742 | value = readl(ioaddr + PTP_TCR); | ||
743 | if (value & PTP_TCR_TSCTRLSSR) | ||
744 | diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | ||
745 | index 45e64d71a93f..5c18874614ba 100644 | ||
746 | --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | ||
747 | +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | ||
748 | @@ -2938,12 +2938,15 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) | ||
749 | |||
750 | /* Manage tx mitigation */ | ||
751 | tx_q->tx_count_frames += nfrags + 1; | ||
752 | - if (priv->tx_coal_frames <= tx_q->tx_count_frames) { | ||
753 | + if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) && | ||
754 | + !(priv->synopsys_id >= DWMAC_CORE_4_00 && | ||
755 | + (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && | ||
756 | + priv->hwts_tx_en)) { | ||
757 | + stmmac_tx_timer_arm(priv, queue); | ||
758 | + } else { | ||
759 | + tx_q->tx_count_frames = 0; | ||
760 | stmmac_set_tx_ic(priv, desc); | ||
761 | priv->xstats.tx_set_ic_bit++; | ||
762 | - tx_q->tx_count_frames = 0; | ||
763 | - } else { | ||
764 | - stmmac_tx_timer_arm(priv, queue); | ||
765 | } | ||
766 | |||
767 | skb_tx_timestamp(skb); | ||
768 | @@ -3157,12 +3160,15 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | ||
769 | * element in case of no SG. | ||
770 | */ | ||
771 | tx_q->tx_count_frames += nfrags + 1; | ||
772 | - if (priv->tx_coal_frames <= tx_q->tx_count_frames) { | ||
773 | + if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) && | ||
774 | + !(priv->synopsys_id >= DWMAC_CORE_4_00 && | ||
775 | + (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && | ||
776 | + priv->hwts_tx_en)) { | ||
777 | + stmmac_tx_timer_arm(priv, queue); | ||
778 | + } else { | ||
779 | + tx_q->tx_count_frames = 0; | ||
780 | stmmac_set_tx_ic(priv, desc); | ||
781 | priv->xstats.tx_set_ic_bit++; | ||
782 | - tx_q->tx_count_frames = 0; | ||
783 | - } else { | ||
784 | - stmmac_tx_timer_arm(priv, queue); | ||
785 | } | ||
786 | |||
787 | skb_tx_timestamp(skb); | ||
788 | diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c | ||
789 | index 6c6230b44bcd..dc30f11f4766 100644 | ||
790 | --- a/drivers/net/team/team.c | ||
791 | +++ b/drivers/net/team/team.c | ||
792 | @@ -2139,12 +2139,12 @@ static void team_setup(struct net_device *dev) | ||
793 | dev->features |= NETIF_F_NETNS_LOCAL; | ||
794 | |||
795 | dev->hw_features = TEAM_VLAN_FEATURES | | ||
796 | - NETIF_F_HW_VLAN_CTAG_TX | | ||
797 | NETIF_F_HW_VLAN_CTAG_RX | | ||
798 | NETIF_F_HW_VLAN_CTAG_FILTER; | ||
799 | |||
800 | dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4; | ||
801 | dev->features |= dev->hw_features; | ||
802 | + dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX; | ||
803 | } | ||
804 | |||
805 | static int team_newlink(struct net *src_net, struct net_device *dev, | ||
806 | diff --git a/drivers/net/tun.c b/drivers/net/tun.c | ||
807 | index 78d34e0306e0..b67fee56ec81 100644 | ||
808 | --- a/drivers/net/tun.c | ||
809 | +++ b/drivers/net/tun.c | ||
810 | @@ -1024,18 +1024,8 @@ static void tun_net_uninit(struct net_device *dev) | ||
811 | /* Net device open. */ | ||
812 | static int tun_net_open(struct net_device *dev) | ||
813 | { | ||
814 | - struct tun_struct *tun = netdev_priv(dev); | ||
815 | - int i; | ||
816 | - | ||
817 | netif_tx_start_all_queues(dev); | ||
818 | |||
819 | - for (i = 0; i < tun->numqueues; i++) { | ||
820 | - struct tun_file *tfile; | ||
821 | - | ||
822 | - tfile = rtnl_dereference(tun->tfiles[i]); | ||
823 | - tfile->socket.sk->sk_write_space(tfile->socket.sk); | ||
824 | - } | ||
825 | - | ||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | @@ -3443,6 +3433,7 @@ static int tun_device_event(struct notifier_block *unused, | ||
830 | { | ||
831 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | ||
832 | struct tun_struct *tun = netdev_priv(dev); | ||
833 | + int i; | ||
834 | |||
835 | if (dev->rtnl_link_ops != &tun_link_ops) | ||
836 | return NOTIFY_DONE; | ||
837 | @@ -3452,6 +3443,14 @@ static int tun_device_event(struct notifier_block *unused, | ||
838 | if (tun_queue_resize(tun)) | ||
839 | return NOTIFY_BAD; | ||
840 | break; | ||
841 | + case NETDEV_UP: | ||
842 | + for (i = 0; i < tun->numqueues; i++) { | ||
843 | + struct tun_file *tfile; | ||
844 | + | ||
845 | + tfile = rtnl_dereference(tun->tfiles[i]); | ||
846 | + tfile->socket.sk->sk_write_space(tfile->socket.sk); | ||
847 | + } | ||
848 | + break; | ||
849 | default: | ||
850 | break; | ||
851 | } | ||
852 | diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c | ||
853 | index d9a6699abe59..e657d8947125 100644 | ||
854 | --- a/drivers/net/usb/qmi_wwan.c | ||
855 | +++ b/drivers/net/usb/qmi_wwan.c | ||
856 | @@ -1412,7 +1412,7 @@ static int qmi_wwan_probe(struct usb_interface *intf, | ||
857 | * different. Ignore the current interface if the number of endpoints | ||
858 | * equals the number for the diag interface (two). | ||
859 | */ | ||
860 | - info = (void *)&id->driver_info; | ||
861 | + info = (void *)id->driver_info; | ||
862 | |||
863 | if (info->data & QMI_WWAN_QUIRK_QUECTEL_DYNCFG) { | ||
864 | if (desc->bNumEndpoints == 2) | ||
865 | diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c | ||
866 | index 890b8aaf95e1..64eb8ffb2ddf 100644 | ||
867 | --- a/drivers/scsi/vmw_pvscsi.c | ||
868 | +++ b/drivers/scsi/vmw_pvscsi.c | ||
869 | @@ -763,6 +763,7 @@ static int pvscsi_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd | ||
870 | struct pvscsi_adapter *adapter = shost_priv(host); | ||
871 | struct pvscsi_ctx *ctx; | ||
872 | unsigned long flags; | ||
873 | + unsigned char op; | ||
874 | |||
875 | spin_lock_irqsave(&adapter->hw_lock, flags); | ||
876 | |||
877 | @@ -775,13 +776,14 @@ static int pvscsi_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd | ||
878 | } | ||
879 | |||
880 | cmd->scsi_done = done; | ||
881 | + op = cmd->cmnd[0]; | ||
882 | |||
883 | dev_dbg(&cmd->device->sdev_gendev, | ||
884 | - "queued cmd %p, ctx %p, op=%x\n", cmd, ctx, cmd->cmnd[0]); | ||
885 | + "queued cmd %p, ctx %p, op=%x\n", cmd, ctx, op); | ||
886 | |||
887 | spin_unlock_irqrestore(&adapter->hw_lock, flags); | ||
888 | |||
889 | - pvscsi_kick_io(adapter, cmd->cmnd[0]); | ||
890 | + pvscsi_kick_io(adapter, op); | ||
891 | |||
892 | return 0; | ||
893 | } | ||
894 | diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h | ||
895 | index 5bfb62533e0f..131028501752 100644 | ||
896 | --- a/drivers/usb/dwc3/core.h | ||
897 | +++ b/drivers/usb/dwc3/core.h | ||
898 | @@ -636,9 +636,9 @@ struct dwc3_event_buffer { | ||
899 | /** | ||
900 | * struct dwc3_ep - device side endpoint representation | ||
901 | * @endpoint: usb endpoint | ||
902 | + * @cancelled_list: list of cancelled requests for this endpoint | ||
903 | * @pending_list: list of pending requests for this endpoint | ||
904 | * @started_list: list of started requests on this endpoint | ||
905 | - * @wait_end_transfer: wait_queue_head_t for waiting on End Transfer complete | ||
906 | * @lock: spinlock for endpoint request queue traversal | ||
907 | * @regs: pointer to first endpoint register | ||
908 | * @trb_pool: array of transaction buffers | ||
909 | @@ -659,11 +659,10 @@ struct dwc3_event_buffer { | ||
910 | */ | ||
911 | struct dwc3_ep { | ||
912 | struct usb_ep endpoint; | ||
913 | + struct list_head cancelled_list; | ||
914 | struct list_head pending_list; | ||
915 | struct list_head started_list; | ||
916 | |||
917 | - wait_queue_head_t wait_end_transfer; | ||
918 | - | ||
919 | spinlock_t lock; | ||
920 | void __iomem *regs; | ||
921 | |||
922 | @@ -847,11 +846,12 @@ struct dwc3_hwparams { | ||
923 | * @epnum: endpoint number to which this request refers | ||
924 | * @trb: pointer to struct dwc3_trb | ||
925 | * @trb_dma: DMA address of @trb | ||
926 | - * @unaligned: true for OUT endpoints with length not divisible by maxp | ||
927 | + * @num_trbs: number of TRBs used by this request | ||
928 | + * @needs_extra_trb: true when request needs one extra TRB (either due to ZLP | ||
929 | + * or unaligned OUT) | ||
930 | * @direction: IN or OUT direction flag | ||
931 | * @mapped: true when request has been dma-mapped | ||
932 | * @started: request is started | ||
933 | - * @zero: wants a ZLP | ||
934 | */ | ||
935 | struct dwc3_request { | ||
936 | struct usb_request request; | ||
937 | @@ -867,11 +867,12 @@ struct dwc3_request { | ||
938 | struct dwc3_trb *trb; | ||
939 | dma_addr_t trb_dma; | ||
940 | |||
941 | - unsigned unaligned:1; | ||
942 | + unsigned num_trbs; | ||
943 | + | ||
944 | + unsigned needs_extra_trb:1; | ||
945 | unsigned direction:1; | ||
946 | unsigned mapped:1; | ||
947 | unsigned started:1; | ||
948 | - unsigned zero:1; | ||
949 | }; | ||
950 | |||
951 | /* | ||
952 | diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c | ||
953 | index 65ba1038b111..e7461c995116 100644 | ||
954 | --- a/drivers/usb/dwc3/gadget.c | ||
955 | +++ b/drivers/usb/dwc3/gadget.c | ||
956 | @@ -177,8 +177,7 @@ static void dwc3_gadget_del_and_unmap_request(struct dwc3_ep *dep, | ||
957 | req->started = false; | ||
958 | list_del(&req->list); | ||
959 | req->remaining = 0; | ||
960 | - req->unaligned = false; | ||
961 | - req->zero = false; | ||
962 | + req->needs_extra_trb = false; | ||
963 | |||
964 | if (req->request.status == -EINPROGRESS) | ||
965 | req->request.status = status; | ||
966 | @@ -640,8 +639,6 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action) | ||
967 | reg |= DWC3_DALEPENA_EP(dep->number); | ||
968 | dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); | ||
969 | |||
970 | - init_waitqueue_head(&dep->wait_end_transfer); | ||
971 | - | ||
972 | if (usb_endpoint_xfer_control(desc)) | ||
973 | goto out; | ||
974 | |||
975 | @@ -1043,6 +1040,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | ||
976 | req->trb_dma = dwc3_trb_dma_offset(dep, trb); | ||
977 | } | ||
978 | |||
979 | + req->num_trbs++; | ||
980 | + | ||
981 | __dwc3_prepare_one_trb(dep, trb, dma, length, chain, node, | ||
982 | stream_id, short_not_ok, no_interrupt); | ||
983 | } | ||
984 | @@ -1070,13 +1069,14 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, | ||
985 | struct dwc3 *dwc = dep->dwc; | ||
986 | struct dwc3_trb *trb; | ||
987 | |||
988 | - req->unaligned = true; | ||
989 | + req->needs_extra_trb = true; | ||
990 | |||
991 | /* prepare normal TRB */ | ||
992 | dwc3_prepare_one_trb(dep, req, true, i); | ||
993 | |||
994 | /* Now prepare one extra TRB to align transfer size */ | ||
995 | trb = &dep->trb_pool[dep->trb_enqueue]; | ||
996 | + req->num_trbs++; | ||
997 | __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, | ||
998 | maxp - rem, false, 1, | ||
999 | req->request.stream_id, | ||
1000 | @@ -1114,13 +1114,14 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, | ||
1001 | struct dwc3 *dwc = dep->dwc; | ||
1002 | struct dwc3_trb *trb; | ||
1003 | |||
1004 | - req->unaligned = true; | ||
1005 | + req->needs_extra_trb = true; | ||
1006 | |||
1007 | /* prepare normal TRB */ | ||
1008 | dwc3_prepare_one_trb(dep, req, true, 0); | ||
1009 | |||
1010 | /* Now prepare one extra TRB to align transfer size */ | ||
1011 | trb = &dep->trb_pool[dep->trb_enqueue]; | ||
1012 | + req->num_trbs++; | ||
1013 | __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp - rem, | ||
1014 | false, 1, req->request.stream_id, | ||
1015 | req->request.short_not_ok, | ||
1016 | @@ -1130,13 +1131,14 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, | ||
1017 | struct dwc3 *dwc = dep->dwc; | ||
1018 | struct dwc3_trb *trb; | ||
1019 | |||
1020 | - req->zero = true; | ||
1021 | + req->needs_extra_trb = true; | ||
1022 | |||
1023 | /* prepare normal TRB */ | ||
1024 | dwc3_prepare_one_trb(dep, req, true, 0); | ||
1025 | |||
1026 | /* Now prepare one extra TRB to handle ZLP */ | ||
1027 | trb = &dep->trb_pool[dep->trb_enqueue]; | ||
1028 | + req->num_trbs++; | ||
1029 | __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0, | ||
1030 | false, 1, req->request.stream_id, | ||
1031 | req->request.short_not_ok, | ||
1032 | @@ -1338,6 +1340,42 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, | ||
1033 | return ret; | ||
1034 | } | ||
1035 | |||
1036 | +static void dwc3_gadget_ep_skip_trbs(struct dwc3_ep *dep, struct dwc3_request *req) | ||
1037 | +{ | ||
1038 | + int i; | ||
1039 | + | ||
1040 | + /* | ||
1041 | + * If request was already started, this means we had to | ||
1042 | + * stop the transfer. With that we also need to ignore | ||
1043 | + * all TRBs used by the request, however TRBs can only | ||
1044 | + * be modified after completion of END_TRANSFER | ||
1045 | + * command. So what we do here is that we wait for | ||
1046 | + * END_TRANSFER completion and only after that, we jump | ||
1047 | + * over TRBs by clearing HWO and incrementing dequeue | ||
1048 | + * pointer. | ||
1049 | + */ | ||
1050 | + for (i = 0; i < req->num_trbs; i++) { | ||
1051 | + struct dwc3_trb *trb; | ||
1052 | + | ||
1053 | + trb = req->trb + i; | ||
1054 | + trb->ctrl &= ~DWC3_TRB_CTRL_HWO; | ||
1055 | + dwc3_ep_inc_deq(dep); | ||
1056 | + } | ||
1057 | + | ||
1058 | + req->num_trbs = 0; | ||
1059 | +} | ||
1060 | + | ||
1061 | +static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep) | ||
1062 | +{ | ||
1063 | + struct dwc3_request *req; | ||
1064 | + struct dwc3_request *tmp; | ||
1065 | + | ||
1066 | + list_for_each_entry_safe(req, tmp, &dep->cancelled_list, list) { | ||
1067 | + dwc3_gadget_ep_skip_trbs(dep, req); | ||
1068 | + dwc3_gadget_giveback(dep, req, -ECONNRESET); | ||
1069 | + } | ||
1070 | +} | ||
1071 | + | ||
1072 | static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, | ||
1073 | struct usb_request *request) | ||
1074 | { | ||
1075 | @@ -1368,68 +1406,11 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, | ||
1076 | /* wait until it is processed */ | ||
1077 | dwc3_stop_active_transfer(dep, true); | ||
1078 | |||
1079 | - /* | ||
1080 | - * If request was already started, this means we had to | ||
1081 | - * stop the transfer. With that we also need to ignore | ||
1082 | - * all TRBs used by the request, however TRBs can only | ||
1083 | - * be modified after completion of END_TRANSFER | ||
1084 | - * command. So what we do here is that we wait for | ||
1085 | - * END_TRANSFER completion and only after that, we jump | ||
1086 | - * over TRBs by clearing HWO and incrementing dequeue | ||
1087 | - * pointer. | ||
1088 | - * | ||
1089 | - * Note that we have 2 possible types of transfers here: | ||
1090 | - * | ||
1091 | - * i) Linear buffer request | ||
1092 | - * ii) SG-list based request | ||
1093 | - * | ||
1094 | - * SG-list based requests will have r->num_pending_sgs | ||
1095 | - * set to a valid number (> 0). Linear requests, | ||
1096 | - * normally use a single TRB. | ||
1097 | - * | ||
1098 | - * For each of these two cases, if r->unaligned flag is | ||
1099 | - * set, one extra TRB has been used to align transfer | ||
1100 | - * size to wMaxPacketSize. | ||
1101 | - * | ||
1102 | - * All of these cases need to be taken into | ||
1103 | - * consideration so we don't mess up our TRB ring | ||
1104 | - * pointers. | ||
1105 | - */ | ||
1106 | - wait_event_lock_irq(dep->wait_end_transfer, | ||
1107 | - !(dep->flags & DWC3_EP_END_TRANSFER_PENDING), | ||
1108 | - dwc->lock); | ||
1109 | - | ||
1110 | if (!r->trb) | ||
1111 | goto out0; | ||
1112 | |||
1113 | - if (r->num_pending_sgs) { | ||
1114 | - struct dwc3_trb *trb; | ||
1115 | - int i = 0; | ||
1116 | - | ||
1117 | - for (i = 0; i < r->num_pending_sgs; i++) { | ||
1118 | - trb = r->trb + i; | ||
1119 | - trb->ctrl &= ~DWC3_TRB_CTRL_HWO; | ||
1120 | - dwc3_ep_inc_deq(dep); | ||
1121 | - } | ||
1122 | - | ||
1123 | - if (r->unaligned || r->zero) { | ||
1124 | - trb = r->trb + r->num_pending_sgs + 1; | ||
1125 | - trb->ctrl &= ~DWC3_TRB_CTRL_HWO; | ||
1126 | - dwc3_ep_inc_deq(dep); | ||
1127 | - } | ||
1128 | - } else { | ||
1129 | - struct dwc3_trb *trb = r->trb; | ||
1130 | - | ||
1131 | - trb->ctrl &= ~DWC3_TRB_CTRL_HWO; | ||
1132 | - dwc3_ep_inc_deq(dep); | ||
1133 | - | ||
1134 | - if (r->unaligned || r->zero) { | ||
1135 | - trb = r->trb + 1; | ||
1136 | - trb->ctrl &= ~DWC3_TRB_CTRL_HWO; | ||
1137 | - dwc3_ep_inc_deq(dep); | ||
1138 | - } | ||
1139 | - } | ||
1140 | - goto out1; | ||
1141 | + dwc3_gadget_move_cancelled_request(req); | ||
1142 | + goto out0; | ||
1143 | } | ||
1144 | dev_err(dwc->dev, "request %pK was not queued to %s\n", | ||
1145 | request, ep->name); | ||
1146 | @@ -1437,9 +1418,6 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, | ||
1147 | goto out0; | ||
1148 | } | ||
1149 | |||
1150 | -out1: | ||
1151 | - /* giveback the request */ | ||
1152 | - | ||
1153 | dwc3_gadget_giveback(dep, req, -ECONNRESET); | ||
1154 | |||
1155 | out0: | ||
1156 | @@ -1932,8 +1910,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g) | ||
1157 | { | ||
1158 | struct dwc3 *dwc = gadget_to_dwc(g); | ||
1159 | unsigned long flags; | ||
1160 | - int epnum; | ||
1161 | - u32 tmo_eps = 0; | ||
1162 | |||
1163 | spin_lock_irqsave(&dwc->lock, flags); | ||
1164 | |||
1165 | @@ -1942,36 +1918,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g) | ||
1166 | |||
1167 | __dwc3_gadget_stop(dwc); | ||
1168 | |||
1169 | - for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) { | ||
1170 | - struct dwc3_ep *dep = dwc->eps[epnum]; | ||
1171 | - int ret; | ||
1172 | - | ||
1173 | - if (!dep) | ||
1174 | - continue; | ||
1175 | - | ||
1176 | - if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) | ||
1177 | - continue; | ||
1178 | - | ||
1179 | - ret = wait_event_interruptible_lock_irq_timeout(dep->wait_end_transfer, | ||
1180 | - !(dep->flags & DWC3_EP_END_TRANSFER_PENDING), | ||
1181 | - dwc->lock, msecs_to_jiffies(5)); | ||
1182 | - | ||
1183 | - if (ret <= 0) { | ||
1184 | - /* Timed out or interrupted! There's nothing much | ||
1185 | - * we can do so we just log here and print which | ||
1186 | - * endpoints timed out at the end. | ||
1187 | - */ | ||
1188 | - tmo_eps |= 1 << epnum; | ||
1189 | - dep->flags &= DWC3_EP_END_TRANSFER_PENDING; | ||
1190 | - } | ||
1191 | - } | ||
1192 | - | ||
1193 | - if (tmo_eps) { | ||
1194 | - dev_err(dwc->dev, | ||
1195 | - "end transfer timed out on endpoints 0x%x [bitmap]\n", | ||
1196 | - tmo_eps); | ||
1197 | - } | ||
1198 | - | ||
1199 | out: | ||
1200 | dwc->gadget_driver = NULL; | ||
1201 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
1202 | @@ -2174,6 +2120,7 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum) | ||
1203 | |||
1204 | INIT_LIST_HEAD(&dep->pending_list); | ||
1205 | INIT_LIST_HEAD(&dep->started_list); | ||
1206 | + INIT_LIST_HEAD(&dep->cancelled_list); | ||
1207 | |||
1208 | return 0; | ||
1209 | } | ||
1210 | @@ -2233,6 +2180,7 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep, | ||
1211 | dwc3_ep_inc_deq(dep); | ||
1212 | |||
1213 | trace_dwc3_complete_trb(dep, trb); | ||
1214 | + req->num_trbs--; | ||
1215 | |||
1216 | /* | ||
1217 | * If we're in the middle of series of chained TRBs and we | ||
1218 | @@ -2252,7 +2200,8 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep, | ||
1219 | * with one TRB pending in the ring. We need to manually clear HWO bit | ||
1220 | * from that TRB. | ||
1221 | */ | ||
1222 | - if ((req->zero || req->unaligned) && !(trb->ctrl & DWC3_TRB_CTRL_CHN)) { | ||
1223 | + | ||
1224 | + if (req->needs_extra_trb && !(trb->ctrl & DWC3_TRB_CTRL_CHN)) { | ||
1225 | trb->ctrl &= ~DWC3_TRB_CTRL_HWO; | ||
1226 | return 1; | ||
1227 | } | ||
1228 | @@ -2329,11 +2278,10 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, | ||
1229 | ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event, | ||
1230 | status); | ||
1231 | |||
1232 | - if (req->unaligned || req->zero) { | ||
1233 | + if (req->needs_extra_trb) { | ||
1234 | ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event, | ||
1235 | status); | ||
1236 | - req->unaligned = false; | ||
1237 | - req->zero = false; | ||
1238 | + req->needs_extra_trb = false; | ||
1239 | } | ||
1240 | |||
1241 | req->request.actual = req->request.length - req->remaining; | ||
1242 | @@ -2466,7 +2414,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | ||
1243 | |||
1244 | if (cmd == DWC3_DEPCMD_ENDTRANSFER) { | ||
1245 | dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; | ||
1246 | - wake_up(&dep->wait_end_transfer); | ||
1247 | + dwc3_gadget_ep_cleanup_cancelled_requests(dep); | ||
1248 | } | ||
1249 | break; | ||
1250 | case DWC3_DEPEVT_STREAMEVT: | ||
1251 | diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h | ||
1252 | index 2aacd1afd9ff..023a473648eb 100644 | ||
1253 | --- a/drivers/usb/dwc3/gadget.h | ||
1254 | +++ b/drivers/usb/dwc3/gadget.h | ||
1255 | @@ -79,6 +79,21 @@ static inline void dwc3_gadget_move_started_request(struct dwc3_request *req) | ||
1256 | list_move_tail(&req->list, &dep->started_list); | ||
1257 | } | ||
1258 | |||
1259 | +/** | ||
1260 | + * dwc3_gadget_move_cancelled_request - move @req to the cancelled_list | ||
1261 | + * @req: the request to be moved | ||
1262 | + * | ||
1263 | + * Caller should take care of locking. This function will move @req from its | ||
1264 | + * current list to the endpoint's cancelled_list. | ||
1265 | + */ | ||
1266 | +static inline void dwc3_gadget_move_cancelled_request(struct dwc3_request *req) | ||
1267 | +{ | ||
1268 | + struct dwc3_ep *dep = req->dep; | ||
1269 | + | ||
1270 | + req->started = false; | ||
1271 | + list_move_tail(&req->list, &dep->cancelled_list); | ||
1272 | +} | ||
1273 | + | ||
1274 | void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | ||
1275 | int status); | ||
1276 | |||
1277 | diff --git a/fs/9p/acl.c b/fs/9p/acl.c | ||
1278 | index 082d227fa56b..6261719f6f2a 100644 | ||
1279 | --- a/fs/9p/acl.c | ||
1280 | +++ b/fs/9p/acl.c | ||
1281 | @@ -276,7 +276,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, | ||
1282 | switch (handler->flags) { | ||
1283 | case ACL_TYPE_ACCESS: | ||
1284 | if (acl) { | ||
1285 | - struct iattr iattr; | ||
1286 | + struct iattr iattr = { 0 }; | ||
1287 | struct posix_acl *old_acl = acl; | ||
1288 | |||
1289 | retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); | ||
1290 | diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c | ||
1291 | index 82a48e830018..e4b59e76afb0 100644 | ||
1292 | --- a/fs/binfmt_flat.c | ||
1293 | +++ b/fs/binfmt_flat.c | ||
1294 | @@ -856,9 +856,14 @@ err: | ||
1295 | |||
1296 | static int load_flat_shared_library(int id, struct lib_info *libs) | ||
1297 | { | ||
1298 | + /* | ||
1299 | + * This is a fake bprm struct; only the members "buf", "file" and | ||
1300 | + * "filename" are actually used. | ||
1301 | + */ | ||
1302 | struct linux_binprm bprm; | ||
1303 | int res; | ||
1304 | char buf[16]; | ||
1305 | + loff_t pos = 0; | ||
1306 | |||
1307 | memset(&bprm, 0, sizeof(bprm)); | ||
1308 | |||
1309 | @@ -872,25 +877,11 @@ static int load_flat_shared_library(int id, struct lib_info *libs) | ||
1310 | if (IS_ERR(bprm.file)) | ||
1311 | return res; | ||
1312 | |||
1313 | - bprm.cred = prepare_exec_creds(); | ||
1314 | - res = -ENOMEM; | ||
1315 | - if (!bprm.cred) | ||
1316 | - goto out; | ||
1317 | - | ||
1318 | - /* We don't really care about recalculating credentials at this point | ||
1319 | - * as we're past the point of no return and are dealing with shared | ||
1320 | - * libraries. | ||
1321 | - */ | ||
1322 | - bprm.called_set_creds = 1; | ||
1323 | + res = kernel_read(bprm.file, bprm.buf, BINPRM_BUF_SIZE, &pos); | ||
1324 | |||
1325 | - res = prepare_binprm(&bprm); | ||
1326 | - | ||
1327 | - if (!res) | ||
1328 | + if (res >= 0) | ||
1329 | res = load_flat_file(&bprm, libs, id, NULL); | ||
1330 | |||
1331 | - abort_creds(bprm.cred); | ||
1332 | - | ||
1333 | -out: | ||
1334 | allow_write_access(bprm.file); | ||
1335 | fput(bprm.file); | ||
1336 | |||
1337 | diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c | ||
1338 | index a8df2f496898..364028c710a8 100644 | ||
1339 | --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c | ||
1340 | +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c | ||
1341 | @@ -18,7 +18,7 @@ | ||
1342 | |||
1343 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | ||
1344 | |||
1345 | -static unsigned int dataserver_timeo = NFS_DEF_TCP_RETRANS; | ||
1346 | +static unsigned int dataserver_timeo = NFS_DEF_TCP_TIMEO; | ||
1347 | static unsigned int dataserver_retrans; | ||
1348 | |||
1349 | static bool ff_layout_has_available_ds(struct pnfs_layout_segment *lseg); | ||
1350 | diff --git a/fs/proc/array.c b/fs/proc/array.c | ||
1351 | index 0ceb3b6b37e7..9eb99a43f849 100644 | ||
1352 | --- a/fs/proc/array.c | ||
1353 | +++ b/fs/proc/array.c | ||
1354 | @@ -452,7 +452,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, | ||
1355 | * a program is not able to use ptrace(2) in that case. It is | ||
1356 | * safe because the task has stopped executing permanently. | ||
1357 | */ | ||
1358 | - if (permitted && (task->flags & PF_DUMPCORE)) { | ||
1359 | + if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE))) { | ||
1360 | if (try_get_task_stack(task)) { | ||
1361 | eip = KSTK_EIP(task); | ||
1362 | esp = KSTK_ESP(task); | ||
1363 | diff --git a/include/asm-generic/futex.h b/include/asm-generic/futex.h | ||
1364 | index fcb61b4659b3..8666fe7f35d7 100644 | ||
1365 | --- a/include/asm-generic/futex.h | ||
1366 | +++ b/include/asm-generic/futex.h | ||
1367 | @@ -23,7 +23,9 @@ | ||
1368 | * | ||
1369 | * Return: | ||
1370 | * 0 - On success | ||
1371 | - * <0 - On error | ||
1372 | + * -EFAULT - User access resulted in a page fault | ||
1373 | + * -EAGAIN - Atomic operation was unable to complete due to contention | ||
1374 | + * -ENOSYS - Operation not supported | ||
1375 | */ | ||
1376 | static inline int | ||
1377 | arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) | ||
1378 | @@ -85,7 +87,9 @@ out_pagefault_enable: | ||
1379 | * | ||
1380 | * Return: | ||
1381 | * 0 - On success | ||
1382 | - * <0 - On error | ||
1383 | + * -EFAULT - User access resulted in a page fault | ||
1384 | + * -EAGAIN - Atomic operation was unable to complete due to contention | ||
1385 | + * -ENOSYS - Function not implemented (only if !HAVE_FUTEX_CMPXCHG) | ||
1386 | */ | ||
1387 | static inline int | ||
1388 | futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | ||
1389 | diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h | ||
1390 | index f91b0f8ff3a9..ad6b30137ac2 100644 | ||
1391 | --- a/include/linux/bpf-cgroup.h | ||
1392 | +++ b/include/linux/bpf-cgroup.h | ||
1393 | @@ -210,6 +210,12 @@ void bpf_cgroup_storage_release(struct bpf_prog *prog, struct bpf_map *map); | ||
1394 | #define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) \ | ||
1395 | BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP6_SENDMSG, t_ctx) | ||
1396 | |||
1397 | +#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr) \ | ||
1398 | + BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP4_RECVMSG, NULL) | ||
1399 | + | ||
1400 | +#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr) \ | ||
1401 | + BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP6_RECVMSG, NULL) | ||
1402 | + | ||
1403 | #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \ | ||
1404 | ({ \ | ||
1405 | int __ret = 0; \ | ||
1406 | @@ -290,6 +296,8 @@ static inline void bpf_cgroup_storage_free( | ||
1407 | #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) ({ 0; }) | ||
1408 | #define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; }) | ||
1409 | #define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; }) | ||
1410 | +#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr) ({ 0; }) | ||
1411 | +#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr) ({ 0; }) | ||
1412 | #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; }) | ||
1413 | #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; }) | ||
1414 | |||
1415 | diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h | ||
1416 | index f30bf500888d..e7bbd82908b1 100644 | ||
1417 | --- a/include/linux/sunrpc/xprt.h | ||
1418 | +++ b/include/linux/sunrpc/xprt.h | ||
1419 | @@ -325,7 +325,6 @@ struct xprt_class { | ||
1420 | struct rpc_xprt *xprt_create_transport(struct xprt_create *args); | ||
1421 | void xprt_connect(struct rpc_task *task); | ||
1422 | void xprt_reserve(struct rpc_task *task); | ||
1423 | -void xprt_request_init(struct rpc_task *task); | ||
1424 | void xprt_retry_reserve(struct rpc_task *task); | ||
1425 | int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task); | ||
1426 | int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); | ||
1427 | diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h | ||
1428 | index b8eb51a661e5..4ab293f574e0 100644 | ||
1429 | --- a/include/net/9p/9p.h | ||
1430 | +++ b/include/net/9p/9p.h | ||
1431 | @@ -336,6 +336,9 @@ enum p9_qid_t { | ||
1432 | #define P9_NOFID (u32)(~0) | ||
1433 | #define P9_MAXWELEM 16 | ||
1434 | |||
1435 | +/* Minimal header size: size[4] type[1] tag[2] */ | ||
1436 | +#define P9_HDRSZ 7 | ||
1437 | + | ||
1438 | /* ample room for Twrite/Rread header */ | ||
1439 | #define P9_IOHDRSZ 24 | ||
1440 | |||
1441 | @@ -558,6 +561,7 @@ struct p9_fcall { | ||
1442 | size_t offset; | ||
1443 | size_t capacity; | ||
1444 | |||
1445 | + struct kmem_cache *cache; | ||
1446 | u8 *sdata; | ||
1447 | }; | ||
1448 | |||
1449 | diff --git a/include/net/9p/client.h b/include/net/9p/client.h | ||
1450 | index 0fa0fbab33b0..947a570307a6 100644 | ||
1451 | --- a/include/net/9p/client.h | ||
1452 | +++ b/include/net/9p/client.h | ||
1453 | @@ -64,22 +64,15 @@ enum p9_trans_status { | ||
1454 | |||
1455 | /** | ||
1456 | * enum p9_req_status_t - status of a request | ||
1457 | - * @REQ_STATUS_IDLE: request slot unused | ||
1458 | * @REQ_STATUS_ALLOC: request has been allocated but not sent | ||
1459 | * @REQ_STATUS_UNSENT: request waiting to be sent | ||
1460 | * @REQ_STATUS_SENT: request sent to server | ||
1461 | * @REQ_STATUS_RCVD: response received from server | ||
1462 | * @REQ_STATUS_FLSHD: request has been flushed | ||
1463 | * @REQ_STATUS_ERROR: request encountered an error on the client side | ||
1464 | - * | ||
1465 | - * The @REQ_STATUS_IDLE state is used to mark a request slot as unused | ||
1466 | - * but use is actually tracked by the idpool structure which handles tag | ||
1467 | - * id allocation. | ||
1468 | - * | ||
1469 | */ | ||
1470 | |||
1471 | enum p9_req_status_t { | ||
1472 | - REQ_STATUS_IDLE, | ||
1473 | REQ_STATUS_ALLOC, | ||
1474 | REQ_STATUS_UNSENT, | ||
1475 | REQ_STATUS_SENT, | ||
1476 | @@ -92,70 +85,46 @@ enum p9_req_status_t { | ||
1477 | * struct p9_req_t - request slots | ||
1478 | * @status: status of this request slot | ||
1479 | * @t_err: transport error | ||
1480 | - * @flush_tag: tag of request being flushed (for flush requests) | ||
1481 | * @wq: wait_queue for the client to block on for this request | ||
1482 | * @tc: the request fcall structure | ||
1483 | * @rc: the response fcall structure | ||
1484 | * @aux: transport specific data (provided for trans_fd migration) | ||
1485 | * @req_list: link for higher level objects to chain requests | ||
1486 | - * | ||
1487 | - * Transport use an array to track outstanding requests | ||
1488 | - * instead of a list. While this may incurr overhead during initial | ||
1489 | - * allocation or expansion, it makes request lookup much easier as the | ||
1490 | - * tag id is a index into an array. (We use tag+1 so that we can accommodate | ||
1491 | - * the -1 tag for the T_VERSION request). | ||
1492 | - * This also has the nice effect of only having to allocate wait_queues | ||
1493 | - * once, instead of constantly allocating and freeing them. Its possible | ||
1494 | - * other resources could benefit from this scheme as well. | ||
1495 | - * | ||
1496 | */ | ||
1497 | - | ||
1498 | struct p9_req_t { | ||
1499 | int status; | ||
1500 | int t_err; | ||
1501 | + struct kref refcount; | ||
1502 | wait_queue_head_t wq; | ||
1503 | - struct p9_fcall *tc; | ||
1504 | - struct p9_fcall *rc; | ||
1505 | + struct p9_fcall tc; | ||
1506 | + struct p9_fcall rc; | ||
1507 | void *aux; | ||
1508 | - | ||
1509 | struct list_head req_list; | ||
1510 | }; | ||
1511 | |||
1512 | /** | ||
1513 | * struct p9_client - per client instance state | ||
1514 | - * @lock: protect @fidlist | ||
1515 | + * @lock: protect @fids and @reqs | ||
1516 | * @msize: maximum data size negotiated by protocol | ||
1517 | - * @dotu: extension flags negotiated by protocol | ||
1518 | * @proto_version: 9P protocol version to use | ||
1519 | * @trans_mod: module API instantiated with this client | ||
1520 | + * @status: connection state | ||
1521 | * @trans: tranport instance state and API | ||
1522 | * @fids: All active FID handles | ||
1523 | - * @tagpool - transaction id accounting for session | ||
1524 | - * @reqs - 2D array of requests | ||
1525 | - * @max_tag - current maximum tag id allocated | ||
1526 | - * @name - node name used as client id | ||
1527 | + * @reqs: All active requests. | ||
1528 | + * @name: node name used as client id | ||
1529 | * | ||
1530 | * The client structure is used to keep track of various per-client | ||
1531 | * state that has been instantiated. | ||
1532 | - * In order to minimize per-transaction overhead we use a | ||
1533 | - * simple array to lookup requests instead of a hash table | ||
1534 | - * or linked list. In order to support larger number of | ||
1535 | - * transactions, we make this a 2D array, allocating new rows | ||
1536 | - * when we need to grow the total number of the transactions. | ||
1537 | - * | ||
1538 | - * Each row is 256 requests and we'll support up to 256 rows for | ||
1539 | - * a total of 64k concurrent requests per session. | ||
1540 | - * | ||
1541 | - * Bugs: duplicated data and potentially unnecessary elements. | ||
1542 | */ | ||
1543 | - | ||
1544 | struct p9_client { | ||
1545 | - spinlock_t lock; /* protect client structure */ | ||
1546 | + spinlock_t lock; | ||
1547 | unsigned int msize; | ||
1548 | unsigned char proto_version; | ||
1549 | struct p9_trans_module *trans_mod; | ||
1550 | enum p9_trans_status status; | ||
1551 | void *trans; | ||
1552 | + struct kmem_cache *fcall_cache; | ||
1553 | |||
1554 | union { | ||
1555 | struct { | ||
1556 | @@ -170,10 +139,7 @@ struct p9_client { | ||
1557 | } trans_opts; | ||
1558 | |||
1559 | struct idr fids; | ||
1560 | - | ||
1561 | - struct p9_idpool *tagpool; | ||
1562 | - struct p9_req_t *reqs[P9_ROW_MAXTAG]; | ||
1563 | - int max_tag; | ||
1564 | + struct idr reqs; | ||
1565 | |||
1566 | char name[__NEW_UTS_LEN + 1]; | ||
1567 | }; | ||
1568 | @@ -266,7 +232,21 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode, | ||
1569 | kgid_t gid, struct p9_qid *); | ||
1570 | int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status); | ||
1571 | int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl); | ||
1572 | +void p9_fcall_fini(struct p9_fcall *fc); | ||
1573 | struct p9_req_t *p9_tag_lookup(struct p9_client *, u16); | ||
1574 | + | ||
1575 | +static inline void p9_req_get(struct p9_req_t *r) | ||
1576 | +{ | ||
1577 | + kref_get(&r->refcount); | ||
1578 | +} | ||
1579 | + | ||
1580 | +static inline int p9_req_try_get(struct p9_req_t *r) | ||
1581 | +{ | ||
1582 | + return kref_get_unless_zero(&r->refcount); | ||
1583 | +} | ||
1584 | + | ||
1585 | +int p9_req_put(struct p9_req_t *r); | ||
1586 | + | ||
1587 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status); | ||
1588 | |||
1589 | int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int); | ||
1590 | @@ -279,4 +259,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *, const char *, u64 *); | ||
1591 | int p9_client_xattrcreate(struct p9_fid *, const char *, u64, int); | ||
1592 | int p9_client_readlink(struct p9_fid *fid, char **target); | ||
1593 | |||
1594 | +int p9_client_init(void); | ||
1595 | +void p9_client_exit(void); | ||
1596 | + | ||
1597 | #endif /* NET_9P_CLIENT_H */ | ||
1598 | diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h | ||
1599 | index 66917a4eba27..2932600ce271 100644 | ||
1600 | --- a/include/uapi/linux/bpf.h | ||
1601 | +++ b/include/uapi/linux/bpf.h | ||
1602 | @@ -172,6 +172,8 @@ enum bpf_attach_type { | ||
1603 | BPF_CGROUP_UDP4_SENDMSG, | ||
1604 | BPF_CGROUP_UDP6_SENDMSG, | ||
1605 | BPF_LIRC_MODE2, | ||
1606 | + BPF_CGROUP_UDP4_RECVMSG = 19, | ||
1607 | + BPF_CGROUP_UDP6_RECVMSG, | ||
1608 | __MAX_BPF_ATTACH_TYPE | ||
1609 | }; | ||
1610 | |||
1611 | @@ -2705,8 +2707,8 @@ struct bpf_raw_tracepoint_args { | ||
1612 | /* DIRECT: Skip the FIB rules and go to FIB table associated with device | ||
1613 | * OUTPUT: Do lookup from egress perspective; default is ingress | ||
1614 | */ | ||
1615 | -#define BPF_FIB_LOOKUP_DIRECT BIT(0) | ||
1616 | -#define BPF_FIB_LOOKUP_OUTPUT BIT(1) | ||
1617 | +#define BPF_FIB_LOOKUP_DIRECT (1U << 0) | ||
1618 | +#define BPF_FIB_LOOKUP_OUTPUT (1U << 1) | ||
1619 | |||
1620 | enum { | ||
1621 | BPF_FIB_LKUP_RET_SUCCESS, /* lookup successful */ | ||
1622 | diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c | ||
1623 | index 4f3138e6ecb2..1a8b208f6c55 100644 | ||
1624 | --- a/kernel/bpf/lpm_trie.c | ||
1625 | +++ b/kernel/bpf/lpm_trie.c | ||
1626 | @@ -676,9 +676,14 @@ find_leftmost: | ||
1627 | * have exact two children, so this function will never return NULL. | ||
1628 | */ | ||
1629 | for (node = search_root; node;) { | ||
1630 | - if (!(node->flags & LPM_TREE_NODE_FLAG_IM)) | ||
1631 | + if (node->flags & LPM_TREE_NODE_FLAG_IM) { | ||
1632 | + node = rcu_dereference(node->child[0]); | ||
1633 | + } else { | ||
1634 | next_node = node; | ||
1635 | - node = rcu_dereference(node->child[0]); | ||
1636 | + node = rcu_dereference(node->child[0]); | ||
1637 | + if (!node) | ||
1638 | + node = rcu_dereference(next_node->child[1]); | ||
1639 | + } | ||
1640 | } | ||
1641 | do_copy: | ||
1642 | next_key->prefixlen = next_node->prefixlen; | ||
1643 | diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c | ||
1644 | index ede82382dd32..118e3a8fc764 100644 | ||
1645 | --- a/kernel/bpf/syscall.c | ||
1646 | +++ b/kernel/bpf/syscall.c | ||
1647 | @@ -1342,6 +1342,8 @@ bpf_prog_load_check_attach_type(enum bpf_prog_type prog_type, | ||
1648 | case BPF_CGROUP_INET6_CONNECT: | ||
1649 | case BPF_CGROUP_UDP4_SENDMSG: | ||
1650 | case BPF_CGROUP_UDP6_SENDMSG: | ||
1651 | + case BPF_CGROUP_UDP4_RECVMSG: | ||
1652 | + case BPF_CGROUP_UDP6_RECVMSG: | ||
1653 | return 0; | ||
1654 | default: | ||
1655 | return -EINVAL; | ||
1656 | @@ -1622,6 +1624,8 @@ static int bpf_prog_attach(const union bpf_attr *attr) | ||
1657 | case BPF_CGROUP_INET6_CONNECT: | ||
1658 | case BPF_CGROUP_UDP4_SENDMSG: | ||
1659 | case BPF_CGROUP_UDP6_SENDMSG: | ||
1660 | + case BPF_CGROUP_UDP4_RECVMSG: | ||
1661 | + case BPF_CGROUP_UDP6_RECVMSG: | ||
1662 | ptype = BPF_PROG_TYPE_CGROUP_SOCK_ADDR; | ||
1663 | break; | ||
1664 | case BPF_CGROUP_SOCK_OPS: | ||
1665 | @@ -1698,6 +1702,8 @@ static int bpf_prog_detach(const union bpf_attr *attr) | ||
1666 | case BPF_CGROUP_INET6_CONNECT: | ||
1667 | case BPF_CGROUP_UDP4_SENDMSG: | ||
1668 | case BPF_CGROUP_UDP6_SENDMSG: | ||
1669 | + case BPF_CGROUP_UDP4_RECVMSG: | ||
1670 | + case BPF_CGROUP_UDP6_RECVMSG: | ||
1671 | ptype = BPF_PROG_TYPE_CGROUP_SOCK_ADDR; | ||
1672 | break; | ||
1673 | case BPF_CGROUP_SOCK_OPS: | ||
1674 | @@ -1744,6 +1750,8 @@ static int bpf_prog_query(const union bpf_attr *attr, | ||
1675 | case BPF_CGROUP_INET6_CONNECT: | ||
1676 | case BPF_CGROUP_UDP4_SENDMSG: | ||
1677 | case BPF_CGROUP_UDP6_SENDMSG: | ||
1678 | + case BPF_CGROUP_UDP4_RECVMSG: | ||
1679 | + case BPF_CGROUP_UDP6_RECVMSG: | ||
1680 | case BPF_CGROUP_SOCK_OPS: | ||
1681 | case BPF_CGROUP_DEVICE: | ||
1682 | break; | ||
1683 | diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c | ||
1684 | index d3580a68dbef..1dff5f7323cc 100644 | ||
1685 | --- a/kernel/bpf/verifier.c | ||
1686 | +++ b/kernel/bpf/verifier.c | ||
1687 | @@ -4342,9 +4342,12 @@ static int check_return_code(struct bpf_verifier_env *env) | ||
1688 | struct tnum range = tnum_range(0, 1); | ||
1689 | |||
1690 | switch (env->prog->type) { | ||
1691 | + case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: | ||
1692 | + if (env->prog->expected_attach_type == BPF_CGROUP_UDP4_RECVMSG || | ||
1693 | + env->prog->expected_attach_type == BPF_CGROUP_UDP6_RECVMSG) | ||
1694 | + range = tnum_range(1, 1); | ||
1695 | case BPF_PROG_TYPE_CGROUP_SKB: | ||
1696 | case BPF_PROG_TYPE_CGROUP_SOCK: | ||
1697 | - case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: | ||
1698 | case BPF_PROG_TYPE_SOCK_OPS: | ||
1699 | case BPF_PROG_TYPE_CGROUP_DEVICE: | ||
1700 | break; | ||
1701 | @@ -4360,16 +4363,17 @@ static int check_return_code(struct bpf_verifier_env *env) | ||
1702 | } | ||
1703 | |||
1704 | if (!tnum_in(range, reg->var_off)) { | ||
1705 | + char tn_buf[48]; | ||
1706 | + | ||
1707 | verbose(env, "At program exit the register R0 "); | ||
1708 | if (!tnum_is_unknown(reg->var_off)) { | ||
1709 | - char tn_buf[48]; | ||
1710 | - | ||
1711 | tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); | ||
1712 | verbose(env, "has value %s", tn_buf); | ||
1713 | } else { | ||
1714 | verbose(env, "has unknown scalar value"); | ||
1715 | } | ||
1716 | - verbose(env, " should have been 0 or 1\n"); | ||
1717 | + tnum_strn(tn_buf, sizeof(tn_buf), range); | ||
1718 | + verbose(env, " should have been in %s\n", tn_buf); | ||
1719 | return -EINVAL; | ||
1720 | } | ||
1721 | return 0; | ||
1722 | diff --git a/kernel/cpu.c b/kernel/cpu.c | ||
1723 | index 5d65eae893bd..46aefe5c0e35 100644 | ||
1724 | --- a/kernel/cpu.c | ||
1725 | +++ b/kernel/cpu.c | ||
1726 | @@ -2289,6 +2289,9 @@ static int __init mitigations_parse_cmdline(char *arg) | ||
1727 | cpu_mitigations = CPU_MITIGATIONS_AUTO; | ||
1728 | else if (!strcmp(arg, "auto,nosmt")) | ||
1729 | cpu_mitigations = CPU_MITIGATIONS_AUTO_NOSMT; | ||
1730 | + else | ||
1731 | + pr_crit("Unsupported mitigations=%s, system may still be vulnerable\n", | ||
1732 | + arg); | ||
1733 | |||
1734 | return 0; | ||
1735 | } | ||
1736 | diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c | ||
1737 | index 6c28d519447d..83c4e76f513a 100644 | ||
1738 | --- a/kernel/trace/bpf_trace.c | ||
1739 | +++ b/kernel/trace/bpf_trace.c | ||
1740 | @@ -365,8 +365,6 @@ static const struct bpf_func_proto bpf_perf_event_read_value_proto = { | ||
1741 | .arg4_type = ARG_CONST_SIZE, | ||
1742 | }; | ||
1743 | |||
1744 | -static DEFINE_PER_CPU(struct perf_sample_data, bpf_trace_sd); | ||
1745 | - | ||
1746 | static __always_inline u64 | ||
1747 | __bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map, | ||
1748 | u64 flags, struct perf_sample_data *sd) | ||
1749 | @@ -398,24 +396,50 @@ __bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map, | ||
1750 | return 0; | ||
1751 | } | ||
1752 | |||
1753 | +/* | ||
1754 | + * Support executing tracepoints in normal, irq, and nmi context that each call | ||
1755 | + * bpf_perf_event_output | ||
1756 | + */ | ||
1757 | +struct bpf_trace_sample_data { | ||
1758 | + struct perf_sample_data sds[3]; | ||
1759 | +}; | ||
1760 | + | ||
1761 | +static DEFINE_PER_CPU(struct bpf_trace_sample_data, bpf_trace_sds); | ||
1762 | +static DEFINE_PER_CPU(int, bpf_trace_nest_level); | ||
1763 | BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map, | ||
1764 | u64, flags, void *, data, u64, size) | ||
1765 | { | ||
1766 | - struct perf_sample_data *sd = this_cpu_ptr(&bpf_trace_sd); | ||
1767 | + struct bpf_trace_sample_data *sds = this_cpu_ptr(&bpf_trace_sds); | ||
1768 | + int nest_level = this_cpu_inc_return(bpf_trace_nest_level); | ||
1769 | struct perf_raw_record raw = { | ||
1770 | .frag = { | ||
1771 | .size = size, | ||
1772 | .data = data, | ||
1773 | }, | ||
1774 | }; | ||
1775 | + struct perf_sample_data *sd; | ||
1776 | + int err; | ||
1777 | |||
1778 | - if (unlikely(flags & ~(BPF_F_INDEX_MASK))) | ||
1779 | - return -EINVAL; | ||
1780 | + if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(sds->sds))) { | ||
1781 | + err = -EBUSY; | ||
1782 | + goto out; | ||
1783 | + } | ||
1784 | + | ||
1785 | + sd = &sds->sds[nest_level - 1]; | ||
1786 | + | ||
1787 | + if (unlikely(flags & ~(BPF_F_INDEX_MASK))) { | ||
1788 | + err = -EINVAL; | ||
1789 | + goto out; | ||
1790 | + } | ||
1791 | |||
1792 | perf_sample_data_init(sd, 0, 0); | ||
1793 | sd->raw = &raw; | ||
1794 | |||
1795 | - return __bpf_perf_event_output(regs, map, flags, sd); | ||
1796 | + err = __bpf_perf_event_output(regs, map, flags, sd); | ||
1797 | + | ||
1798 | +out: | ||
1799 | + this_cpu_dec(bpf_trace_nest_level); | ||
1800 | + return err; | ||
1801 | } | ||
1802 | |||
1803 | static const struct bpf_func_proto bpf_perf_event_output_proto = { | ||
1804 | @@ -772,16 +796,48 @@ pe_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) | ||
1805 | /* | ||
1806 | * bpf_raw_tp_regs are separate from bpf_pt_regs used from skb/xdp | ||
1807 | * to avoid potential recursive reuse issue when/if tracepoints are added | ||
1808 | - * inside bpf_*_event_output, bpf_get_stackid and/or bpf_get_stack | ||
1809 | + * inside bpf_*_event_output, bpf_get_stackid and/or bpf_get_stack. | ||
1810 | + * | ||
1811 | + * Since raw tracepoints run despite bpf_prog_active, support concurrent usage | ||
1812 | + * in normal, irq, and nmi context. | ||
1813 | */ | ||
1814 | -static DEFINE_PER_CPU(struct pt_regs, bpf_raw_tp_regs); | ||
1815 | +struct bpf_raw_tp_regs { | ||
1816 | + struct pt_regs regs[3]; | ||
1817 | +}; | ||
1818 | +static DEFINE_PER_CPU(struct bpf_raw_tp_regs, bpf_raw_tp_regs); | ||
1819 | +static DEFINE_PER_CPU(int, bpf_raw_tp_nest_level); | ||
1820 | +static struct pt_regs *get_bpf_raw_tp_regs(void) | ||
1821 | +{ | ||
1822 | + struct bpf_raw_tp_regs *tp_regs = this_cpu_ptr(&bpf_raw_tp_regs); | ||
1823 | + int nest_level = this_cpu_inc_return(bpf_raw_tp_nest_level); | ||
1824 | + | ||
1825 | + if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(tp_regs->regs))) { | ||
1826 | + this_cpu_dec(bpf_raw_tp_nest_level); | ||
1827 | + return ERR_PTR(-EBUSY); | ||
1828 | + } | ||
1829 | + | ||
1830 | + return &tp_regs->regs[nest_level - 1]; | ||
1831 | +} | ||
1832 | + | ||
1833 | +static void put_bpf_raw_tp_regs(void) | ||
1834 | +{ | ||
1835 | + this_cpu_dec(bpf_raw_tp_nest_level); | ||
1836 | +} | ||
1837 | + | ||
1838 | BPF_CALL_5(bpf_perf_event_output_raw_tp, struct bpf_raw_tracepoint_args *, args, | ||
1839 | struct bpf_map *, map, u64, flags, void *, data, u64, size) | ||
1840 | { | ||
1841 | - struct pt_regs *regs = this_cpu_ptr(&bpf_raw_tp_regs); | ||
1842 | + struct pt_regs *regs = get_bpf_raw_tp_regs(); | ||
1843 | + int ret; | ||
1844 | + | ||
1845 | + if (IS_ERR(regs)) | ||
1846 | + return PTR_ERR(regs); | ||
1847 | |||
1848 | perf_fetch_caller_regs(regs); | ||
1849 | - return ____bpf_perf_event_output(regs, map, flags, data, size); | ||
1850 | + ret = ____bpf_perf_event_output(regs, map, flags, data, size); | ||
1851 | + | ||
1852 | + put_bpf_raw_tp_regs(); | ||
1853 | + return ret; | ||
1854 | } | ||
1855 | |||
1856 | static const struct bpf_func_proto bpf_perf_event_output_proto_raw_tp = { | ||
1857 | @@ -798,12 +854,18 @@ static const struct bpf_func_proto bpf_perf_event_output_proto_raw_tp = { | ||
1858 | BPF_CALL_3(bpf_get_stackid_raw_tp, struct bpf_raw_tracepoint_args *, args, | ||
1859 | struct bpf_map *, map, u64, flags) | ||
1860 | { | ||
1861 | - struct pt_regs *regs = this_cpu_ptr(&bpf_raw_tp_regs); | ||
1862 | + struct pt_regs *regs = get_bpf_raw_tp_regs(); | ||
1863 | + int ret; | ||
1864 | + | ||
1865 | + if (IS_ERR(regs)) | ||
1866 | + return PTR_ERR(regs); | ||
1867 | |||
1868 | perf_fetch_caller_regs(regs); | ||
1869 | /* similar to bpf_perf_event_output_tp, but pt_regs fetched differently */ | ||
1870 | - return bpf_get_stackid((unsigned long) regs, (unsigned long) map, | ||
1871 | - flags, 0, 0); | ||
1872 | + ret = bpf_get_stackid((unsigned long) regs, (unsigned long) map, | ||
1873 | + flags, 0, 0); | ||
1874 | + put_bpf_raw_tp_regs(); | ||
1875 | + return ret; | ||
1876 | } | ||
1877 | |||
1878 | static const struct bpf_func_proto bpf_get_stackid_proto_raw_tp = { | ||
1879 | @@ -818,11 +880,17 @@ static const struct bpf_func_proto bpf_get_stackid_proto_raw_tp = { | ||
1880 | BPF_CALL_4(bpf_get_stack_raw_tp, struct bpf_raw_tracepoint_args *, args, | ||
1881 | void *, buf, u32, size, u64, flags) | ||
1882 | { | ||
1883 | - struct pt_regs *regs = this_cpu_ptr(&bpf_raw_tp_regs); | ||
1884 | + struct pt_regs *regs = get_bpf_raw_tp_regs(); | ||
1885 | + int ret; | ||
1886 | + | ||
1887 | + if (IS_ERR(regs)) | ||
1888 | + return PTR_ERR(regs); | ||
1889 | |||
1890 | perf_fetch_caller_regs(regs); | ||
1891 | - return bpf_get_stack((unsigned long) regs, (unsigned long) buf, | ||
1892 | - (unsigned long) size, flags, 0); | ||
1893 | + ret = bpf_get_stack((unsigned long) regs, (unsigned long) buf, | ||
1894 | + (unsigned long) size, flags, 0); | ||
1895 | + put_bpf_raw_tp_regs(); | ||
1896 | + return ret; | ||
1897 | } | ||
1898 | |||
1899 | static const struct bpf_func_proto bpf_get_stack_proto_raw_tp = { | ||
1900 | diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c | ||
1901 | index 3ea65cdff30d..4ad967453b6f 100644 | ||
1902 | --- a/kernel/trace/trace_branch.c | ||
1903 | +++ b/kernel/trace/trace_branch.c | ||
1904 | @@ -205,8 +205,6 @@ void trace_likely_condition(struct ftrace_likely_data *f, int val, int expect) | ||
1905 | void ftrace_likely_update(struct ftrace_likely_data *f, int val, | ||
1906 | int expect, int is_constant) | ||
1907 | { | ||
1908 | - unsigned long flags = user_access_save(); | ||
1909 | - | ||
1910 | /* A constant is always correct */ | ||
1911 | if (is_constant) { | ||
1912 | f->constant++; | ||
1913 | @@ -225,8 +223,6 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, | ||
1914 | f->data.correct++; | ||
1915 | else | ||
1916 | f->data.incorrect++; | ||
1917 | - | ||
1918 | - user_access_restore(flags); | ||
1919 | } | ||
1920 | EXPORT_SYMBOL(ftrace_likely_update); | ||
1921 | |||
1922 | diff --git a/mm/hugetlb.c b/mm/hugetlb.c | ||
1923 | index 65179513c2b2..57053affaad2 100644 | ||
1924 | --- a/mm/hugetlb.c | ||
1925 | +++ b/mm/hugetlb.c | ||
1926 | @@ -1489,16 +1489,29 @@ static int free_pool_huge_page(struct hstate *h, nodemask_t *nodes_allowed, | ||
1927 | |||
1928 | /* | ||
1929 | * Dissolve a given free hugepage into free buddy pages. This function does | ||
1930 | - * nothing for in-use (including surplus) hugepages. Returns -EBUSY if the | ||
1931 | - * dissolution fails because a give page is not a free hugepage, or because | ||
1932 | - * free hugepages are fully reserved. | ||
1933 | + * nothing for in-use hugepages and non-hugepages. | ||
1934 | + * This function returns values like below: | ||
1935 | + * | ||
1936 | + * -EBUSY: failed to dissolved free hugepages or the hugepage is in-use | ||
1937 | + * (allocated or reserved.) | ||
1938 | + * 0: successfully dissolved free hugepages or the page is not a | ||
1939 | + * hugepage (considered as already dissolved) | ||
1940 | */ | ||
1941 | int dissolve_free_huge_page(struct page *page) | ||
1942 | { | ||
1943 | int rc = -EBUSY; | ||
1944 | |||
1945 | + /* Not to disrupt normal path by vainly holding hugetlb_lock */ | ||
1946 | + if (!PageHuge(page)) | ||
1947 | + return 0; | ||
1948 | + | ||
1949 | spin_lock(&hugetlb_lock); | ||
1950 | - if (PageHuge(page) && !page_count(page)) { | ||
1951 | + if (!PageHuge(page)) { | ||
1952 | + rc = 0; | ||
1953 | + goto out; | ||
1954 | + } | ||
1955 | + | ||
1956 | + if (!page_count(page)) { | ||
1957 | struct page *head = compound_head(page); | ||
1958 | struct hstate *h = page_hstate(head); | ||
1959 | int nid = page_to_nid(head); | ||
1960 | @@ -1543,11 +1556,9 @@ int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) | ||
1961 | |||
1962 | for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order) { | ||
1963 | page = pfn_to_page(pfn); | ||
1964 | - if (PageHuge(page) && !page_count(page)) { | ||
1965 | - rc = dissolve_free_huge_page(page); | ||
1966 | - if (rc) | ||
1967 | - break; | ||
1968 | - } | ||
1969 | + rc = dissolve_free_huge_page(page); | ||
1970 | + if (rc) | ||
1971 | + break; | ||
1972 | } | ||
1973 | |||
1974 | return rc; | ||
1975 | diff --git a/mm/memory-failure.c b/mm/memory-failure.c | ||
1976 | index 6edc6db5ec1b..2994ceb2e7b0 100644 | ||
1977 | --- a/mm/memory-failure.c | ||
1978 | +++ b/mm/memory-failure.c | ||
1979 | @@ -1731,6 +1731,8 @@ static int soft_offline_huge_page(struct page *page, int flags) | ||
1980 | if (!ret) { | ||
1981 | if (set_hwpoison_free_buddy_page(page)) | ||
1982 | num_poisoned_pages_inc(); | ||
1983 | + else | ||
1984 | + ret = -EBUSY; | ||
1985 | } | ||
1986 | } | ||
1987 | return ret; | ||
1988 | @@ -1855,11 +1857,8 @@ static int soft_offline_in_use_page(struct page *page, int flags) | ||
1989 | |||
1990 | static int soft_offline_free_page(struct page *page) | ||
1991 | { | ||
1992 | - int rc = 0; | ||
1993 | - struct page *head = compound_head(page); | ||
1994 | + int rc = dissolve_free_huge_page(page); | ||
1995 | |||
1996 | - if (PageHuge(head)) | ||
1997 | - rc = dissolve_free_huge_page(page); | ||
1998 | if (!rc) { | ||
1999 | if (set_hwpoison_free_buddy_page(page)) | ||
2000 | num_poisoned_pages_inc(); | ||
2001 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c | ||
2002 | index 360b24bc69e5..62f945ea3e36 100644 | ||
2003 | --- a/mm/mempolicy.c | ||
2004 | +++ b/mm/mempolicy.c | ||
2005 | @@ -306,7 +306,7 @@ static void mpol_rebind_nodemask(struct mempolicy *pol, const nodemask_t *nodes) | ||
2006 | else { | ||
2007 | nodes_remap(tmp, pol->v.nodes,pol->w.cpuset_mems_allowed, | ||
2008 | *nodes); | ||
2009 | - pol->w.cpuset_mems_allowed = tmp; | ||
2010 | + pol->w.cpuset_mems_allowed = *nodes; | ||
2011 | } | ||
2012 | |||
2013 | if (nodes_empty(tmp)) | ||
2014 | diff --git a/mm/page_idle.c b/mm/page_idle.c | ||
2015 | index 6302bc62c27d..52ed59bbc275 100644 | ||
2016 | --- a/mm/page_idle.c | ||
2017 | +++ b/mm/page_idle.c | ||
2018 | @@ -136,7 +136,7 @@ static ssize_t page_idle_bitmap_read(struct file *file, struct kobject *kobj, | ||
2019 | |||
2020 | end_pfn = pfn + count * BITS_PER_BYTE; | ||
2021 | if (end_pfn > max_pfn) | ||
2022 | - end_pfn = ALIGN(max_pfn, BITMAP_CHUNK_BITS); | ||
2023 | + end_pfn = max_pfn; | ||
2024 | |||
2025 | for (; pfn < end_pfn; pfn++) { | ||
2026 | bit = pfn % BITMAP_CHUNK_BITS; | ||
2027 | @@ -181,7 +181,7 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj, | ||
2028 | |||
2029 | end_pfn = pfn + count * BITS_PER_BYTE; | ||
2030 | if (end_pfn > max_pfn) | ||
2031 | - end_pfn = ALIGN(max_pfn, BITMAP_CHUNK_BITS); | ||
2032 | + end_pfn = max_pfn; | ||
2033 | |||
2034 | for (; pfn < end_pfn; pfn++) { | ||
2035 | bit = pfn % BITMAP_CHUNK_BITS; | ||
2036 | diff --git a/net/9p/client.c b/net/9p/client.c | ||
2037 | index 23ec6187dc07..b615aae5a0f8 100644 | ||
2038 | --- a/net/9p/client.c | ||
2039 | +++ b/net/9p/client.c | ||
2040 | @@ -237,144 +237,170 @@ free_and_return: | ||
2041 | return ret; | ||
2042 | } | ||
2043 | |||
2044 | -static struct p9_fcall *p9_fcall_alloc(int alloc_msize) | ||
2045 | +static int p9_fcall_init(struct p9_client *c, struct p9_fcall *fc, | ||
2046 | + int alloc_msize) | ||
2047 | { | ||
2048 | - struct p9_fcall *fc; | ||
2049 | - fc = kmalloc(sizeof(struct p9_fcall) + alloc_msize, GFP_NOFS); | ||
2050 | - if (!fc) | ||
2051 | - return NULL; | ||
2052 | + if (likely(c->fcall_cache) && alloc_msize == c->msize) { | ||
2053 | + fc->sdata = kmem_cache_alloc(c->fcall_cache, GFP_NOFS); | ||
2054 | + fc->cache = c->fcall_cache; | ||
2055 | + } else { | ||
2056 | + fc->sdata = kmalloc(alloc_msize, GFP_NOFS); | ||
2057 | + fc->cache = NULL; | ||
2058 | + } | ||
2059 | + if (!fc->sdata) | ||
2060 | + return -ENOMEM; | ||
2061 | fc->capacity = alloc_msize; | ||
2062 | - fc->sdata = (char *) fc + sizeof(struct p9_fcall); | ||
2063 | - return fc; | ||
2064 | + return 0; | ||
2065 | +} | ||
2066 | + | ||
2067 | +void p9_fcall_fini(struct p9_fcall *fc) | ||
2068 | +{ | ||
2069 | + /* sdata can be NULL for interrupted requests in trans_rdma, | ||
2070 | + * and kmem_cache_free does not do NULL-check for us | ||
2071 | + */ | ||
2072 | + if (unlikely(!fc->sdata)) | ||
2073 | + return; | ||
2074 | + | ||
2075 | + if (fc->cache) | ||
2076 | + kmem_cache_free(fc->cache, fc->sdata); | ||
2077 | + else | ||
2078 | + kfree(fc->sdata); | ||
2079 | } | ||
2080 | +EXPORT_SYMBOL(p9_fcall_fini); | ||
2081 | + | ||
2082 | +static struct kmem_cache *p9_req_cache; | ||
2083 | |||
2084 | /** | ||
2085 | - * p9_tag_alloc - lookup/allocate a request by tag | ||
2086 | - * @c: client session to lookup tag within | ||
2087 | - * @tag: numeric id for transaction | ||
2088 | - * | ||
2089 | - * this is a simple array lookup, but will grow the | ||
2090 | - * request_slots as necessary to accommodate transaction | ||
2091 | - * ids which did not previously have a slot. | ||
2092 | - * | ||
2093 | - * this code relies on the client spinlock to manage locks, its | ||
2094 | - * possible we should switch to something else, but I'd rather | ||
2095 | - * stick with something low-overhead for the common case. | ||
2096 | + * p9_req_alloc - Allocate a new request. | ||
2097 | + * @c: Client session. | ||
2098 | + * @type: Transaction type. | ||
2099 | + * @max_size: Maximum packet size for this request. | ||
2100 | * | ||
2101 | + * Context: Process context. | ||
2102 | + * Return: Pointer to new request. | ||
2103 | */ | ||
2104 | - | ||
2105 | static struct p9_req_t * | ||
2106 | -p9_tag_alloc(struct p9_client *c, u16 tag, unsigned int max_size) | ||
2107 | +p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size) | ||
2108 | { | ||
2109 | - unsigned long flags; | ||
2110 | - int row, col; | ||
2111 | - struct p9_req_t *req; | ||
2112 | + struct p9_req_t *req = kmem_cache_alloc(p9_req_cache, GFP_NOFS); | ||
2113 | int alloc_msize = min(c->msize, max_size); | ||
2114 | + int tag; | ||
2115 | |||
2116 | - /* This looks up the original request by tag so we know which | ||
2117 | - * buffer to read the data into */ | ||
2118 | - tag++; | ||
2119 | - | ||
2120 | - if (tag >= c->max_tag) { | ||
2121 | - spin_lock_irqsave(&c->lock, flags); | ||
2122 | - /* check again since original check was outside of lock */ | ||
2123 | - while (tag >= c->max_tag) { | ||
2124 | - row = (tag / P9_ROW_MAXTAG); | ||
2125 | - c->reqs[row] = kcalloc(P9_ROW_MAXTAG, | ||
2126 | - sizeof(struct p9_req_t), GFP_ATOMIC); | ||
2127 | - | ||
2128 | - if (!c->reqs[row]) { | ||
2129 | - pr_err("Couldn't grow tag array\n"); | ||
2130 | - spin_unlock_irqrestore(&c->lock, flags); | ||
2131 | - return ERR_PTR(-ENOMEM); | ||
2132 | - } | ||
2133 | - for (col = 0; col < P9_ROW_MAXTAG; col++) { | ||
2134 | - req = &c->reqs[row][col]; | ||
2135 | - req->status = REQ_STATUS_IDLE; | ||
2136 | - init_waitqueue_head(&req->wq); | ||
2137 | - } | ||
2138 | - c->max_tag += P9_ROW_MAXTAG; | ||
2139 | - } | ||
2140 | - spin_unlock_irqrestore(&c->lock, flags); | ||
2141 | - } | ||
2142 | - row = tag / P9_ROW_MAXTAG; | ||
2143 | - col = tag % P9_ROW_MAXTAG; | ||
2144 | - | ||
2145 | - req = &c->reqs[row][col]; | ||
2146 | - if (!req->tc) | ||
2147 | - req->tc = p9_fcall_alloc(alloc_msize); | ||
2148 | - if (!req->rc) | ||
2149 | - req->rc = p9_fcall_alloc(alloc_msize); | ||
2150 | - if (!req->tc || !req->rc) | ||
2151 | - goto grow_failed; | ||
2152 | + if (!req) | ||
2153 | + return ERR_PTR(-ENOMEM); | ||
2154 | |||
2155 | - p9pdu_reset(req->tc); | ||
2156 | - p9pdu_reset(req->rc); | ||
2157 | + if (p9_fcall_init(c, &req->tc, alloc_msize)) | ||
2158 | + goto free_req; | ||
2159 | + if (p9_fcall_init(c, &req->rc, alloc_msize)) | ||
2160 | + goto free; | ||
2161 | |||
2162 | - req->tc->tag = tag-1; | ||
2163 | + p9pdu_reset(&req->tc); | ||
2164 | + p9pdu_reset(&req->rc); | ||
2165 | req->status = REQ_STATUS_ALLOC; | ||
2166 | + init_waitqueue_head(&req->wq); | ||
2167 | + INIT_LIST_HEAD(&req->req_list); | ||
2168 | + | ||
2169 | + idr_preload(GFP_NOFS); | ||
2170 | + spin_lock_irq(&c->lock); | ||
2171 | + if (type == P9_TVERSION) | ||
2172 | + tag = idr_alloc(&c->reqs, req, P9_NOTAG, P9_NOTAG + 1, | ||
2173 | + GFP_NOWAIT); | ||
2174 | + else | ||
2175 | + tag = idr_alloc(&c->reqs, req, 0, P9_NOTAG, GFP_NOWAIT); | ||
2176 | + req->tc.tag = tag; | ||
2177 | + spin_unlock_irq(&c->lock); | ||
2178 | + idr_preload_end(); | ||
2179 | + if (tag < 0) | ||
2180 | + goto free; | ||
2181 | + | ||
2182 | + /* Init ref to two because in the general case there is one ref | ||
2183 | + * that is put asynchronously by a writer thread, one ref | ||
2184 | + * temporarily given by p9_tag_lookup and put by p9_client_cb | ||
2185 | + * in the recv thread, and one ref put by p9_tag_remove in the | ||
2186 | + * main thread. The only exception is virtio that does not use | ||
2187 | + * p9_tag_lookup but does not have a writer thread either | ||
2188 | + * (the write happens synchronously in the request/zc_request | ||
2189 | + * callback), so p9_client_cb eats the second ref there | ||
2190 | + * as the pointer is duplicated directly by virtqueue_add_sgs() | ||
2191 | + */ | ||
2192 | + refcount_set(&req->refcount.refcount, 2); | ||
2193 | |||
2194 | return req; | ||
2195 | |||
2196 | -grow_failed: | ||
2197 | - pr_err("Couldn't grow tag array\n"); | ||
2198 | - kfree(req->tc); | ||
2199 | - kfree(req->rc); | ||
2200 | - req->tc = req->rc = NULL; | ||
2201 | +free: | ||
2202 | + p9_fcall_fini(&req->tc); | ||
2203 | + p9_fcall_fini(&req->rc); | ||
2204 | +free_req: | ||
2205 | + kmem_cache_free(p9_req_cache, req); | ||
2206 | return ERR_PTR(-ENOMEM); | ||
2207 | } | ||
2208 | |||
2209 | /** | ||
2210 | - * p9_tag_lookup - lookup a request by tag | ||
2211 | - * @c: client session to lookup tag within | ||
2212 | - * @tag: numeric id for transaction | ||
2213 | + * p9_tag_lookup - Look up a request by tag. | ||
2214 | + * @c: Client session. | ||
2215 | + * @tag: Transaction ID. | ||
2216 | * | ||
2217 | + * Context: Any context. | ||
2218 | + * Return: A request, or %NULL if there is no request with that tag. | ||
2219 | */ | ||
2220 | - | ||
2221 | struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag) | ||
2222 | { | ||
2223 | - int row, col; | ||
2224 | - | ||
2225 | - /* This looks up the original request by tag so we know which | ||
2226 | - * buffer to read the data into */ | ||
2227 | - tag++; | ||
2228 | - | ||
2229 | - if (tag >= c->max_tag) | ||
2230 | - return NULL; | ||
2231 | + struct p9_req_t *req; | ||
2232 | |||
2233 | - row = tag / P9_ROW_MAXTAG; | ||
2234 | - col = tag % P9_ROW_MAXTAG; | ||
2235 | + rcu_read_lock(); | ||
2236 | +again: | ||
2237 | + req = idr_find(&c->reqs, tag); | ||
2238 | + if (req) { | ||
2239 | + /* We have to be careful with the req found under rcu_read_lock | ||
2240 | + * Thanks to SLAB_TYPESAFE_BY_RCU we can safely try to get the | ||
2241 | + * ref again without corrupting other data, then check again | ||
2242 | + * that the tag matches once we have the ref | ||
2243 | + */ | ||
2244 | + if (!p9_req_try_get(req)) | ||
2245 | + goto again; | ||
2246 | + if (req->tc.tag != tag) { | ||
2247 | + p9_req_put(req); | ||
2248 | + goto again; | ||
2249 | + } | ||
2250 | + } | ||
2251 | + rcu_read_unlock(); | ||
2252 | |||
2253 | - return &c->reqs[row][col]; | ||
2254 | + return req; | ||
2255 | } | ||
2256 | EXPORT_SYMBOL(p9_tag_lookup); | ||
2257 | |||
2258 | /** | ||
2259 | - * p9_tag_init - setup tags structure and contents | ||
2260 | - * @c: v9fs client struct | ||
2261 | - * | ||
2262 | - * This initializes the tags structure for each client instance. | ||
2263 | + * p9_tag_remove - Remove a tag. | ||
2264 | + * @c: Client session. | ||
2265 | + * @r: Request of reference. | ||
2266 | * | ||
2267 | + * Context: Any context. | ||
2268 | */ | ||
2269 | +static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r) | ||
2270 | +{ | ||
2271 | + unsigned long flags; | ||
2272 | + u16 tag = r->tc.tag; | ||
2273 | + | ||
2274 | + p9_debug(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag); | ||
2275 | + spin_lock_irqsave(&c->lock, flags); | ||
2276 | + idr_remove(&c->reqs, tag); | ||
2277 | + spin_unlock_irqrestore(&c->lock, flags); | ||
2278 | + return p9_req_put(r); | ||
2279 | +} | ||
2280 | |||
2281 | -static int p9_tag_init(struct p9_client *c) | ||
2282 | +static void p9_req_free(struct kref *ref) | ||
2283 | { | ||
2284 | - int err = 0; | ||
2285 | + struct p9_req_t *r = container_of(ref, struct p9_req_t, refcount); | ||
2286 | + p9_fcall_fini(&r->tc); | ||
2287 | + p9_fcall_fini(&r->rc); | ||
2288 | + kmem_cache_free(p9_req_cache, r); | ||
2289 | +} | ||
2290 | |||
2291 | - c->tagpool = p9_idpool_create(); | ||
2292 | - if (IS_ERR(c->tagpool)) { | ||
2293 | - err = PTR_ERR(c->tagpool); | ||
2294 | - goto error; | ||
2295 | - } | ||
2296 | - err = p9_idpool_get(c->tagpool); /* reserve tag 0 */ | ||
2297 | - if (err < 0) { | ||
2298 | - p9_idpool_destroy(c->tagpool); | ||
2299 | - goto error; | ||
2300 | - } | ||
2301 | - c->max_tag = 0; | ||
2302 | -error: | ||
2303 | - return err; | ||
2304 | +int p9_req_put(struct p9_req_t *r) | ||
2305 | +{ | ||
2306 | + return kref_put(&r->refcount, p9_req_free); | ||
2307 | } | ||
2308 | +EXPORT_SYMBOL(p9_req_put); | ||
2309 | |||
2310 | /** | ||
2311 | * p9_tag_cleanup - cleans up tags structure and reclaims resources | ||
2312 | @@ -385,52 +411,17 @@ error: | ||
2313 | */ | ||
2314 | static void p9_tag_cleanup(struct p9_client *c) | ||
2315 | { | ||
2316 | - int row, col; | ||
2317 | - | ||
2318 | - /* check to insure all requests are idle */ | ||
2319 | - for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) { | ||
2320 | - for (col = 0; col < P9_ROW_MAXTAG; col++) { | ||
2321 | - if (c->reqs[row][col].status != REQ_STATUS_IDLE) { | ||
2322 | - p9_debug(P9_DEBUG_MUX, | ||
2323 | - "Attempting to cleanup non-free tag %d,%d\n", | ||
2324 | - row, col); | ||
2325 | - /* TODO: delay execution of cleanup */ | ||
2326 | - return; | ||
2327 | - } | ||
2328 | - } | ||
2329 | - } | ||
2330 | - | ||
2331 | - if (c->tagpool) { | ||
2332 | - p9_idpool_put(0, c->tagpool); /* free reserved tag 0 */ | ||
2333 | - p9_idpool_destroy(c->tagpool); | ||
2334 | - } | ||
2335 | + struct p9_req_t *req; | ||
2336 | + int id; | ||
2337 | |||
2338 | - /* free requests associated with tags */ | ||
2339 | - for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) { | ||
2340 | - for (col = 0; col < P9_ROW_MAXTAG; col++) { | ||
2341 | - kfree(c->reqs[row][col].tc); | ||
2342 | - kfree(c->reqs[row][col].rc); | ||
2343 | - } | ||
2344 | - kfree(c->reqs[row]); | ||
2345 | + rcu_read_lock(); | ||
2346 | + idr_for_each_entry(&c->reqs, req, id) { | ||
2347 | + pr_info("Tag %d still in use\n", id); | ||
2348 | + if (p9_tag_remove(c, req) == 0) | ||
2349 | + pr_warn("Packet with tag %d has still references", | ||
2350 | + req->tc.tag); | ||
2351 | } | ||
2352 | - c->max_tag = 0; | ||
2353 | -} | ||
2354 | - | ||
2355 | -/** | ||
2356 | - * p9_free_req - free a request and clean-up as necessary | ||
2357 | - * c: client state | ||
2358 | - * r: request to release | ||
2359 | - * | ||
2360 | - */ | ||
2361 | - | ||
2362 | -static void p9_free_req(struct p9_client *c, struct p9_req_t *r) | ||
2363 | -{ | ||
2364 | - int tag = r->tc->tag; | ||
2365 | - p9_debug(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag); | ||
2366 | - | ||
2367 | - r->status = REQ_STATUS_IDLE; | ||
2368 | - if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool)) | ||
2369 | - p9_idpool_put(tag, c->tagpool); | ||
2370 | + rcu_read_unlock(); | ||
2371 | } | ||
2372 | |||
2373 | /** | ||
2374 | @@ -441,7 +432,7 @@ static void p9_free_req(struct p9_client *c, struct p9_req_t *r) | ||
2375 | */ | ||
2376 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status) | ||
2377 | { | ||
2378 | - p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc->tag); | ||
2379 | + p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc.tag); | ||
2380 | |||
2381 | /* | ||
2382 | * This barrier is needed to make sure any change made to req before | ||
2383 | @@ -451,7 +442,8 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status) | ||
2384 | req->status = status; | ||
2385 | |||
2386 | wake_up(&req->wq); | ||
2387 | - p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag); | ||
2388 | + p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag); | ||
2389 | + p9_req_put(req); | ||
2390 | } | ||
2391 | EXPORT_SYMBOL(p9_client_cb); | ||
2392 | |||
2393 | @@ -522,18 +514,18 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) | ||
2394 | int err; | ||
2395 | int ecode; | ||
2396 | |||
2397 | - err = p9_parse_header(req->rc, NULL, &type, NULL, 0); | ||
2398 | - if (req->rc->size >= c->msize) { | ||
2399 | + err = p9_parse_header(&req->rc, NULL, &type, NULL, 0); | ||
2400 | + if (req->rc.size >= c->msize) { | ||
2401 | p9_debug(P9_DEBUG_ERROR, | ||
2402 | "requested packet size too big: %d\n", | ||
2403 | - req->rc->size); | ||
2404 | + req->rc.size); | ||
2405 | return -EIO; | ||
2406 | } | ||
2407 | /* | ||
2408 | * dump the response from server | ||
2409 | * This should be after check errors which poplulate pdu_fcall. | ||
2410 | */ | ||
2411 | - trace_9p_protocol_dump(c, req->rc); | ||
2412 | + trace_9p_protocol_dump(c, &req->rc); | ||
2413 | if (err) { | ||
2414 | p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err); | ||
2415 | return err; | ||
2416 | @@ -543,7 +535,7 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) | ||
2417 | |||
2418 | if (!p9_is_proto_dotl(c)) { | ||
2419 | char *ename; | ||
2420 | - err = p9pdu_readf(req->rc, c->proto_version, "s?d", | ||
2421 | + err = p9pdu_readf(&req->rc, c->proto_version, "s?d", | ||
2422 | &ename, &ecode); | ||
2423 | if (err) | ||
2424 | goto out_err; | ||
2425 | @@ -559,7 +551,7 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) | ||
2426 | } | ||
2427 | kfree(ename); | ||
2428 | } else { | ||
2429 | - err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode); | ||
2430 | + err = p9pdu_readf(&req->rc, c->proto_version, "d", &ecode); | ||
2431 | err = -ecode; | ||
2432 | |||
2433 | p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode); | ||
2434 | @@ -593,12 +585,12 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, | ||
2435 | int8_t type; | ||
2436 | char *ename = NULL; | ||
2437 | |||
2438 | - err = p9_parse_header(req->rc, NULL, &type, NULL, 0); | ||
2439 | + err = p9_parse_header(&req->rc, NULL, &type, NULL, 0); | ||
2440 | /* | ||
2441 | * dump the response from server | ||
2442 | * This should be after parse_header which poplulate pdu_fcall. | ||
2443 | */ | ||
2444 | - trace_9p_protocol_dump(c, req->rc); | ||
2445 | + trace_9p_protocol_dump(c, &req->rc); | ||
2446 | if (err) { | ||
2447 | p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err); | ||
2448 | return err; | ||
2449 | @@ -613,13 +605,13 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, | ||
2450 | /* 7 = header size for RERROR; */ | ||
2451 | int inline_len = in_hdrlen - 7; | ||
2452 | |||
2453 | - len = req->rc->size - req->rc->offset; | ||
2454 | + len = req->rc.size - req->rc.offset; | ||
2455 | if (len > (P9_ZC_HDR_SZ - 7)) { | ||
2456 | err = -EFAULT; | ||
2457 | goto out_err; | ||
2458 | } | ||
2459 | |||
2460 | - ename = &req->rc->sdata[req->rc->offset]; | ||
2461 | + ename = &req->rc.sdata[req->rc.offset]; | ||
2462 | if (len > inline_len) { | ||
2463 | /* We have error in external buffer */ | ||
2464 | if (!copy_from_iter_full(ename + inline_len, | ||
2465 | @@ -629,7 +621,7 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, | ||
2466 | } | ||
2467 | } | ||
2468 | ename = NULL; | ||
2469 | - err = p9pdu_readf(req->rc, c->proto_version, "s?d", | ||
2470 | + err = p9pdu_readf(&req->rc, c->proto_version, "s?d", | ||
2471 | &ename, &ecode); | ||
2472 | if (err) | ||
2473 | goto out_err; | ||
2474 | @@ -645,7 +637,7 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, | ||
2475 | } | ||
2476 | kfree(ename); | ||
2477 | } else { | ||
2478 | - err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode); | ||
2479 | + err = p9pdu_readf(&req->rc, c->proto_version, "d", &ecode); | ||
2480 | err = -ecode; | ||
2481 | |||
2482 | p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode); | ||
2483 | @@ -678,7 +670,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq) | ||
2484 | int16_t oldtag; | ||
2485 | int err; | ||
2486 | |||
2487 | - err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1); | ||
2488 | + err = p9_parse_header(&oldreq->tc, NULL, NULL, &oldtag, 1); | ||
2489 | if (err) | ||
2490 | return err; | ||
2491 | |||
2492 | @@ -692,11 +684,12 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq) | ||
2493 | * if we haven't received a response for oldreq, | ||
2494 | * remove it from the list | ||
2495 | */ | ||
2496 | - if (oldreq->status == REQ_STATUS_SENT) | ||
2497 | + if (oldreq->status == REQ_STATUS_SENT) { | ||
2498 | if (c->trans_mod->cancelled) | ||
2499 | c->trans_mod->cancelled(c, oldreq); | ||
2500 | + } | ||
2501 | |||
2502 | - p9_free_req(c, req); | ||
2503 | + p9_tag_remove(c, req); | ||
2504 | return 0; | ||
2505 | } | ||
2506 | |||
2507 | @@ -704,7 +697,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c, | ||
2508 | int8_t type, int req_size, | ||
2509 | const char *fmt, va_list ap) | ||
2510 | { | ||
2511 | - int tag, err; | ||
2512 | + int err; | ||
2513 | struct p9_req_t *req; | ||
2514 | |||
2515 | p9_debug(P9_DEBUG_MUX, "client %p op %d\n", c, type); | ||
2516 | @@ -717,27 +710,22 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c, | ||
2517 | if ((c->status == BeginDisconnect) && (type != P9_TCLUNK)) | ||
2518 | return ERR_PTR(-EIO); | ||
2519 | |||
2520 | - tag = P9_NOTAG; | ||
2521 | - if (type != P9_TVERSION) { | ||
2522 | - tag = p9_idpool_get(c->tagpool); | ||
2523 | - if (tag < 0) | ||
2524 | - return ERR_PTR(-ENOMEM); | ||
2525 | - } | ||
2526 | - | ||
2527 | - req = p9_tag_alloc(c, tag, req_size); | ||
2528 | + req = p9_tag_alloc(c, type, req_size); | ||
2529 | if (IS_ERR(req)) | ||
2530 | return req; | ||
2531 | |||
2532 | /* marshall the data */ | ||
2533 | - p9pdu_prepare(req->tc, tag, type); | ||
2534 | - err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap); | ||
2535 | + p9pdu_prepare(&req->tc, req->tc.tag, type); | ||
2536 | + err = p9pdu_vwritef(&req->tc, c->proto_version, fmt, ap); | ||
2537 | if (err) | ||
2538 | goto reterr; | ||
2539 | - p9pdu_finalize(c, req->tc); | ||
2540 | - trace_9p_client_req(c, type, tag); | ||
2541 | + p9pdu_finalize(c, &req->tc); | ||
2542 | + trace_9p_client_req(c, type, req->tc.tag); | ||
2543 | return req; | ||
2544 | reterr: | ||
2545 | - p9_free_req(c, req); | ||
2546 | + p9_tag_remove(c, req); | ||
2547 | + /* We have to put also the 2nd reference as it won't be used */ | ||
2548 | + p9_req_put(req); | ||
2549 | return ERR_PTR(err); | ||
2550 | } | ||
2551 | |||
2552 | @@ -747,7 +735,7 @@ reterr: | ||
2553 | * @type: type of request | ||
2554 | * @fmt: protocol format string (see protocol.c) | ||
2555 | * | ||
2556 | - * Returns request structure (which client must free using p9_free_req) | ||
2557 | + * Returns request structure (which client must free using p9_tag_remove) | ||
2558 | */ | ||
2559 | |||
2560 | static struct p9_req_t * | ||
2561 | @@ -772,6 +760,8 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) | ||
2562 | |||
2563 | err = c->trans_mod->request(c, req); | ||
2564 | if (err < 0) { | ||
2565 | + /* write won't happen */ | ||
2566 | + p9_req_put(req); | ||
2567 | if (err != -ERESTARTSYS && err != -EFAULT) | ||
2568 | c->status = Disconnected; | ||
2569 | goto recalc_sigpending; | ||
2570 | @@ -819,11 +809,11 @@ recalc_sigpending: | ||
2571 | goto reterr; | ||
2572 | |||
2573 | err = p9_check_errors(c, req); | ||
2574 | - trace_9p_client_res(c, type, req->rc->tag, err); | ||
2575 | + trace_9p_client_res(c, type, req->rc.tag, err); | ||
2576 | if (!err) | ||
2577 | return req; | ||
2578 | reterr: | ||
2579 | - p9_free_req(c, req); | ||
2580 | + p9_tag_remove(c, req); | ||
2581 | return ERR_PTR(safe_errno(err)); | ||
2582 | } | ||
2583 | |||
2584 | @@ -838,7 +828,7 @@ reterr: | ||
2585 | * @hdrlen: reader header size, This is the size of response protocol data | ||
2586 | * @fmt: protocol format string (see protocol.c) | ||
2587 | * | ||
2588 | - * Returns request structure (which client must free using p9_free_req) | ||
2589 | + * Returns request structure (which client must free using p9_tag_remove) | ||
2590 | */ | ||
2591 | static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type, | ||
2592 | struct iov_iter *uidata, | ||
2593 | @@ -901,11 +891,11 @@ recalc_sigpending: | ||
2594 | goto reterr; | ||
2595 | |||
2596 | err = p9_check_zc_errors(c, req, uidata, in_hdrlen); | ||
2597 | - trace_9p_client_res(c, type, req->rc->tag, err); | ||
2598 | + trace_9p_client_res(c, type, req->rc.tag, err); | ||
2599 | if (!err) | ||
2600 | return req; | ||
2601 | reterr: | ||
2602 | - p9_free_req(c, req); | ||
2603 | + p9_tag_remove(c, req); | ||
2604 | return ERR_PTR(safe_errno(err)); | ||
2605 | } | ||
2606 | |||
2607 | @@ -984,10 +974,10 @@ static int p9_client_version(struct p9_client *c) | ||
2608 | if (IS_ERR(req)) | ||
2609 | return PTR_ERR(req); | ||
2610 | |||
2611 | - err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version); | ||
2612 | + err = p9pdu_readf(&req->rc, c->proto_version, "ds", &msize, &version); | ||
2613 | if (err) { | ||
2614 | p9_debug(P9_DEBUG_9P, "version error %d\n", err); | ||
2615 | - trace_9p_protocol_dump(c, req->rc); | ||
2616 | + trace_9p_protocol_dump(c, &req->rc); | ||
2617 | goto error; | ||
2618 | } | ||
2619 | |||
2620 | @@ -1016,7 +1006,7 @@ static int p9_client_version(struct p9_client *c) | ||
2621 | |||
2622 | error: | ||
2623 | kfree(version); | ||
2624 | - p9_free_req(c, req); | ||
2625 | + p9_tag_remove(c, req); | ||
2626 | |||
2627 | return err; | ||
2628 | } | ||
2629 | @@ -1034,20 +1024,18 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) | ||
2630 | |||
2631 | clnt->trans_mod = NULL; | ||
2632 | clnt->trans = NULL; | ||
2633 | + clnt->fcall_cache = NULL; | ||
2634 | |||
2635 | client_id = utsname()->nodename; | ||
2636 | memcpy(clnt->name, client_id, strlen(client_id) + 1); | ||
2637 | |||
2638 | spin_lock_init(&clnt->lock); | ||
2639 | idr_init(&clnt->fids); | ||
2640 | - | ||
2641 | - err = p9_tag_init(clnt); | ||
2642 | - if (err < 0) | ||
2643 | - goto free_client; | ||
2644 | + idr_init(&clnt->reqs); | ||
2645 | |||
2646 | err = parse_opts(options, clnt); | ||
2647 | if (err < 0) | ||
2648 | - goto destroy_tagpool; | ||
2649 | + goto free_client; | ||
2650 | |||
2651 | if (!clnt->trans_mod) | ||
2652 | clnt->trans_mod = v9fs_get_default_trans(); | ||
2653 | @@ -1056,7 +1044,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) | ||
2654 | err = -EPROTONOSUPPORT; | ||
2655 | p9_debug(P9_DEBUG_ERROR, | ||
2656 | "No transport defined or default transport\n"); | ||
2657 | - goto destroy_tagpool; | ||
2658 | + goto free_client; | ||
2659 | } | ||
2660 | |||
2661 | p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n", | ||
2662 | @@ -1080,14 +1068,21 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) | ||
2663 | if (err) | ||
2664 | goto close_trans; | ||
2665 | |||
2666 | + /* P9_HDRSZ + 4 is the smallest packet header we can have that is | ||
2667 | + * followed by data accessed from userspace by read | ||
2668 | + */ | ||
2669 | + clnt->fcall_cache = | ||
2670 | + kmem_cache_create_usercopy("9p-fcall-cache", clnt->msize, | ||
2671 | + 0, 0, P9_HDRSZ + 4, | ||
2672 | + clnt->msize - (P9_HDRSZ + 4), | ||
2673 | + NULL); | ||
2674 | + | ||
2675 | return clnt; | ||
2676 | |||
2677 | close_trans: | ||
2678 | clnt->trans_mod->close(clnt); | ||
2679 | put_trans: | ||
2680 | v9fs_put_trans(clnt->trans_mod); | ||
2681 | -destroy_tagpool: | ||
2682 | - p9_idpool_destroy(clnt->tagpool); | ||
2683 | free_client: | ||
2684 | kfree(clnt); | ||
2685 | return ERR_PTR(err); | ||
2686 | @@ -1113,6 +1108,7 @@ void p9_client_destroy(struct p9_client *clnt) | ||
2687 | |||
2688 | p9_tag_cleanup(clnt); | ||
2689 | |||
2690 | + kmem_cache_destroy(clnt->fcall_cache); | ||
2691 | kfree(clnt); | ||
2692 | } | ||
2693 | EXPORT_SYMBOL(p9_client_destroy); | ||
2694 | @@ -1156,10 +1152,10 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | ||
2695 | goto error; | ||
2696 | } | ||
2697 | |||
2698 | - err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid); | ||
2699 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", &qid); | ||
2700 | if (err) { | ||
2701 | - trace_9p_protocol_dump(clnt, req->rc); | ||
2702 | - p9_free_req(clnt, req); | ||
2703 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
2704 | + p9_tag_remove(clnt, req); | ||
2705 | goto error; | ||
2706 | } | ||
2707 | |||
2708 | @@ -1168,7 +1164,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | ||
2709 | |||
2710 | memmove(&fid->qid, &qid, sizeof(struct p9_qid)); | ||
2711 | |||
2712 | - p9_free_req(clnt, req); | ||
2713 | + p9_tag_remove(clnt, req); | ||
2714 | return fid; | ||
2715 | |||
2716 | error: | ||
2717 | @@ -1213,13 +1209,13 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname, | ||
2718 | goto error; | ||
2719 | } | ||
2720 | |||
2721 | - err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids); | ||
2722 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "R", &nwqids, &wqids); | ||
2723 | if (err) { | ||
2724 | - trace_9p_protocol_dump(clnt, req->rc); | ||
2725 | - p9_free_req(clnt, req); | ||
2726 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
2727 | + p9_tag_remove(clnt, req); | ||
2728 | goto clunk_fid; | ||
2729 | } | ||
2730 | - p9_free_req(clnt, req); | ||
2731 | + p9_tag_remove(clnt, req); | ||
2732 | |||
2733 | p9_debug(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids); | ||
2734 | |||
2735 | @@ -1280,9 +1276,9 @@ int p9_client_open(struct p9_fid *fid, int mode) | ||
2736 | goto error; | ||
2737 | } | ||
2738 | |||
2739 | - err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); | ||
2740 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", &qid, &iounit); | ||
2741 | if (err) { | ||
2742 | - trace_9p_protocol_dump(clnt, req->rc); | ||
2743 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
2744 | goto free_and_error; | ||
2745 | } | ||
2746 | |||
2747 | @@ -1294,7 +1290,7 @@ int p9_client_open(struct p9_fid *fid, int mode) | ||
2748 | fid->iounit = iounit; | ||
2749 | |||
2750 | free_and_error: | ||
2751 | - p9_free_req(clnt, req); | ||
2752 | + p9_tag_remove(clnt, req); | ||
2753 | error: | ||
2754 | return err; | ||
2755 | } | ||
2756 | @@ -1324,9 +1320,9 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32 | ||
2757 | goto error; | ||
2758 | } | ||
2759 | |||
2760 | - err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit); | ||
2761 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", qid, &iounit); | ||
2762 | if (err) { | ||
2763 | - trace_9p_protocol_dump(clnt, req->rc); | ||
2764 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
2765 | goto free_and_error; | ||
2766 | } | ||
2767 | |||
2768 | @@ -1339,7 +1335,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32 | ||
2769 | ofid->iounit = iounit; | ||
2770 | |||
2771 | free_and_error: | ||
2772 | - p9_free_req(clnt, req); | ||
2773 | + p9_tag_remove(clnt, req); | ||
2774 | error: | ||
2775 | return err; | ||
2776 | } | ||
2777 | @@ -1369,9 +1365,9 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode, | ||
2778 | goto error; | ||
2779 | } | ||
2780 | |||
2781 | - err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); | ||
2782 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", &qid, &iounit); | ||
2783 | if (err) { | ||
2784 | - trace_9p_protocol_dump(clnt, req->rc); | ||
2785 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
2786 | goto free_and_error; | ||
2787 | } | ||
2788 | |||
2789 | @@ -1384,7 +1380,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode, | ||
2790 | fid->iounit = iounit; | ||
2791 | |||
2792 | free_and_error: | ||
2793 | - p9_free_req(clnt, req); | ||
2794 | + p9_tag_remove(clnt, req); | ||
2795 | error: | ||
2796 | return err; | ||
2797 | } | ||
2798 | @@ -1408,9 +1404,9 @@ int p9_client_symlink(struct p9_fid *dfid, const char *name, | ||
2799 | goto error; | ||
2800 | } | ||
2801 | |||
2802 | - err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); | ||
2803 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid); | ||
2804 | if (err) { | ||
2805 | - trace_9p_protocol_dump(clnt, req->rc); | ||
2806 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
2807 | goto free_and_error; | ||
2808 | } | ||
2809 | |||
2810 | @@ -1418,7 +1414,7 @@ int p9_client_symlink(struct p9_fid *dfid, const char *name, | ||
2811 | qid->type, (unsigned long long)qid->path, qid->version); | ||
2812 | |||
2813 | free_and_error: | ||
2814 | - p9_free_req(clnt, req); | ||
2815 | + p9_tag_remove(clnt, req); | ||
2816 | error: | ||
2817 | return err; | ||
2818 | } | ||
2819 | @@ -1438,7 +1434,7 @@ int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, const char *newna | ||
2820 | return PTR_ERR(req); | ||
2821 | |||
2822 | p9_debug(P9_DEBUG_9P, "<<< RLINK\n"); | ||
2823 | - p9_free_req(clnt, req); | ||
2824 | + p9_tag_remove(clnt, req); | ||
2825 | return 0; | ||
2826 | } | ||
2827 | EXPORT_SYMBOL(p9_client_link); | ||
2828 | @@ -1462,7 +1458,7 @@ int p9_client_fsync(struct p9_fid *fid, int datasync) | ||
2829 | |||
2830 | p9_debug(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid); | ||
2831 | |||
2832 | - p9_free_req(clnt, req); | ||
2833 | + p9_tag_remove(clnt, req); | ||
2834 | |||
2835 | error: | ||
2836 | return err; | ||
2837 | @@ -1497,7 +1493,7 @@ again: | ||
2838 | |||
2839 | p9_debug(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid); | ||
2840 | |||
2841 | - p9_free_req(clnt, req); | ||
2842 | + p9_tag_remove(clnt, req); | ||
2843 | error: | ||
2844 | /* | ||
2845 | * Fid is not valid even after a failed clunk | ||
2846 | @@ -1531,7 +1527,7 @@ int p9_client_remove(struct p9_fid *fid) | ||
2847 | |||
2848 | p9_debug(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid); | ||
2849 | |||
2850 | - p9_free_req(clnt, req); | ||
2851 | + p9_tag_remove(clnt, req); | ||
2852 | error: | ||
2853 | if (err == -ERESTARTSYS) | ||
2854 | p9_client_clunk(fid); | ||
2855 | @@ -1558,7 +1554,7 @@ int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags) | ||
2856 | } | ||
2857 | p9_debug(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name); | ||
2858 | |||
2859 | - p9_free_req(clnt, req); | ||
2860 | + p9_tag_remove(clnt, req); | ||
2861 | error: | ||
2862 | return err; | ||
2863 | } | ||
2864 | @@ -1606,11 +1602,11 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err) | ||
2865 | break; | ||
2866 | } | ||
2867 | |||
2868 | - *err = p9pdu_readf(req->rc, clnt->proto_version, | ||
2869 | + *err = p9pdu_readf(&req->rc, clnt->proto_version, | ||
2870 | "D", &count, &dataptr); | ||
2871 | if (*err) { | ||
2872 | - trace_9p_protocol_dump(clnt, req->rc); | ||
2873 | - p9_free_req(clnt, req); | ||
2874 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
2875 | + p9_tag_remove(clnt, req); | ||
2876 | break; | ||
2877 | } | ||
2878 | if (rsize < count) { | ||
2879 | @@ -1620,7 +1616,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err) | ||
2880 | |||
2881 | p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count); | ||
2882 | if (!count) { | ||
2883 | - p9_free_req(clnt, req); | ||
2884 | + p9_tag_remove(clnt, req); | ||
2885 | break; | ||
2886 | } | ||
2887 | |||
2888 | @@ -1630,7 +1626,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err) | ||
2889 | offset += n; | ||
2890 | if (n != count) { | ||
2891 | *err = -EFAULT; | ||
2892 | - p9_free_req(clnt, req); | ||
2893 | + p9_tag_remove(clnt, req); | ||
2894 | break; | ||
2895 | } | ||
2896 | } else { | ||
2897 | @@ -1638,7 +1634,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err) | ||
2898 | total += count; | ||
2899 | offset += count; | ||
2900 | } | ||
2901 | - p9_free_req(clnt, req); | ||
2902 | + p9_tag_remove(clnt, req); | ||
2903 | } | ||
2904 | return total; | ||
2905 | } | ||
2906 | @@ -1679,10 +1675,10 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err) | ||
2907 | break; | ||
2908 | } | ||
2909 | |||
2910 | - *err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count); | ||
2911 | + *err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &count); | ||
2912 | if (*err) { | ||
2913 | - trace_9p_protocol_dump(clnt, req->rc); | ||
2914 | - p9_free_req(clnt, req); | ||
2915 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
2916 | + p9_tag_remove(clnt, req); | ||
2917 | break; | ||
2918 | } | ||
2919 | if (rsize < count) { | ||
2920 | @@ -1692,7 +1688,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err) | ||
2921 | |||
2922 | p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count); | ||
2923 | |||
2924 | - p9_free_req(clnt, req); | ||
2925 | + p9_tag_remove(clnt, req); | ||
2926 | iov_iter_advance(from, count); | ||
2927 | total += count; | ||
2928 | offset += count; | ||
2929 | @@ -1723,10 +1719,10 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid) | ||
2930 | goto error; | ||
2931 | } | ||
2932 | |||
2933 | - err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret); | ||
2934 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "wS", &ignored, ret); | ||
2935 | if (err) { | ||
2936 | - trace_9p_protocol_dump(clnt, req->rc); | ||
2937 | - p9_free_req(clnt, req); | ||
2938 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
2939 | + p9_tag_remove(clnt, req); | ||
2940 | goto error; | ||
2941 | } | ||
2942 | |||
2943 | @@ -1743,7 +1739,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid) | ||
2944 | from_kgid(&init_user_ns, ret->n_gid), | ||
2945 | from_kuid(&init_user_ns, ret->n_muid)); | ||
2946 | |||
2947 | - p9_free_req(clnt, req); | ||
2948 | + p9_tag_remove(clnt, req); | ||
2949 | return ret; | ||
2950 | |||
2951 | error: | ||
2952 | @@ -1776,10 +1772,10 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, | ||
2953 | goto error; | ||
2954 | } | ||
2955 | |||
2956 | - err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret); | ||
2957 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "A", ret); | ||
2958 | if (err) { | ||
2959 | - trace_9p_protocol_dump(clnt, req->rc); | ||
2960 | - p9_free_req(clnt, req); | ||
2961 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
2962 | + p9_tag_remove(clnt, req); | ||
2963 | goto error; | ||
2964 | } | ||
2965 | |||
2966 | @@ -1804,7 +1800,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, | ||
2967 | ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec, | ||
2968 | ret->st_gen, ret->st_data_version); | ||
2969 | |||
2970 | - p9_free_req(clnt, req); | ||
2971 | + p9_tag_remove(clnt, req); | ||
2972 | return ret; | ||
2973 | |||
2974 | error: | ||
2975 | @@ -1873,7 +1869,7 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) | ||
2976 | |||
2977 | p9_debug(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid); | ||
2978 | |||
2979 | - p9_free_req(clnt, req); | ||
2980 | + p9_tag_remove(clnt, req); | ||
2981 | error: | ||
2982 | return err; | ||
2983 | } | ||
2984 | @@ -1905,7 +1901,7 @@ int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr) | ||
2985 | goto error; | ||
2986 | } | ||
2987 | p9_debug(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid); | ||
2988 | - p9_free_req(clnt, req); | ||
2989 | + p9_tag_remove(clnt, req); | ||
2990 | error: | ||
2991 | return err; | ||
2992 | } | ||
2993 | @@ -1928,12 +1924,12 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb) | ||
2994 | goto error; | ||
2995 | } | ||
2996 | |||
2997 | - err = p9pdu_readf(req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type, | ||
2998 | - &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail, | ||
2999 | - &sb->files, &sb->ffree, &sb->fsid, &sb->namelen); | ||
3000 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type, | ||
3001 | + &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail, | ||
3002 | + &sb->files, &sb->ffree, &sb->fsid, &sb->namelen); | ||
3003 | if (err) { | ||
3004 | - trace_9p_protocol_dump(clnt, req->rc); | ||
3005 | - p9_free_req(clnt, req); | ||
3006 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
3007 | + p9_tag_remove(clnt, req); | ||
3008 | goto error; | ||
3009 | } | ||
3010 | |||
3011 | @@ -1944,7 +1940,7 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb) | ||
3012 | sb->blocks, sb->bfree, sb->bavail, sb->files, sb->ffree, | ||
3013 | sb->fsid, (long int)sb->namelen); | ||
3014 | |||
3015 | - p9_free_req(clnt, req); | ||
3016 | + p9_tag_remove(clnt, req); | ||
3017 | error: | ||
3018 | return err; | ||
3019 | } | ||
3020 | @@ -1972,7 +1968,7 @@ int p9_client_rename(struct p9_fid *fid, | ||
3021 | |||
3022 | p9_debug(P9_DEBUG_9P, "<<< RRENAME fid %d\n", fid->fid); | ||
3023 | |||
3024 | - p9_free_req(clnt, req); | ||
3025 | + p9_tag_remove(clnt, req); | ||
3026 | error: | ||
3027 | return err; | ||
3028 | } | ||
3029 | @@ -2002,7 +1998,7 @@ int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name, | ||
3030 | p9_debug(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n", | ||
3031 | newdirfid->fid, new_name); | ||
3032 | |||
3033 | - p9_free_req(clnt, req); | ||
3034 | + p9_tag_remove(clnt, req); | ||
3035 | error: | ||
3036 | return err; | ||
3037 | } | ||
3038 | @@ -2036,13 +2032,13 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid, | ||
3039 | err = PTR_ERR(req); | ||
3040 | goto error; | ||
3041 | } | ||
3042 | - err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size); | ||
3043 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "q", attr_size); | ||
3044 | if (err) { | ||
3045 | - trace_9p_protocol_dump(clnt, req->rc); | ||
3046 | - p9_free_req(clnt, req); | ||
3047 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
3048 | + p9_tag_remove(clnt, req); | ||
3049 | goto clunk_fid; | ||
3050 | } | ||
3051 | - p9_free_req(clnt, req); | ||
3052 | + p9_tag_remove(clnt, req); | ||
3053 | p9_debug(P9_DEBUG_9P, "<<< RXATTRWALK fid %d size %llu\n", | ||
3054 | attr_fid->fid, *attr_size); | ||
3055 | return attr_fid; | ||
3056 | @@ -2076,7 +2072,7 @@ int p9_client_xattrcreate(struct p9_fid *fid, const char *name, | ||
3057 | goto error; | ||
3058 | } | ||
3059 | p9_debug(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid); | ||
3060 | - p9_free_req(clnt, req); | ||
3061 | + p9_tag_remove(clnt, req); | ||
3062 | error: | ||
3063 | return err; | ||
3064 | } | ||
3065 | @@ -2124,9 +2120,9 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) | ||
3066 | goto error; | ||
3067 | } | ||
3068 | |||
3069 | - err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); | ||
3070 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "D", &count, &dataptr); | ||
3071 | if (err) { | ||
3072 | - trace_9p_protocol_dump(clnt, req->rc); | ||
3073 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
3074 | goto free_and_error; | ||
3075 | } | ||
3076 | if (rsize < count) { | ||
3077 | @@ -2139,11 +2135,11 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) | ||
3078 | if (non_zc) | ||
3079 | memmove(data, dataptr, count); | ||
3080 | |||
3081 | - p9_free_req(clnt, req); | ||
3082 | + p9_tag_remove(clnt, req); | ||
3083 | return count; | ||
3084 | |||
3085 | free_and_error: | ||
3086 | - p9_free_req(clnt, req); | ||
3087 | + p9_tag_remove(clnt, req); | ||
3088 | error: | ||
3089 | return err; | ||
3090 | } | ||
3091 | @@ -2165,16 +2161,16 @@ int p9_client_mknod_dotl(struct p9_fid *fid, const char *name, int mode, | ||
3092 | if (IS_ERR(req)) | ||
3093 | return PTR_ERR(req); | ||
3094 | |||
3095 | - err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); | ||
3096 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid); | ||
3097 | if (err) { | ||
3098 | - trace_9p_protocol_dump(clnt, req->rc); | ||
3099 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
3100 | goto error; | ||
3101 | } | ||
3102 | p9_debug(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type, | ||
3103 | (unsigned long long)qid->path, qid->version); | ||
3104 | |||
3105 | error: | ||
3106 | - p9_free_req(clnt, req); | ||
3107 | + p9_tag_remove(clnt, req); | ||
3108 | return err; | ||
3109 | |||
3110 | } | ||
3111 | @@ -2196,16 +2192,16 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode, | ||
3112 | if (IS_ERR(req)) | ||
3113 | return PTR_ERR(req); | ||
3114 | |||
3115 | - err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); | ||
3116 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid); | ||
3117 | if (err) { | ||
3118 | - trace_9p_protocol_dump(clnt, req->rc); | ||
3119 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
3120 | goto error; | ||
3121 | } | ||
3122 | p9_debug(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type, | ||
3123 | (unsigned long long)qid->path, qid->version); | ||
3124 | |||
3125 | error: | ||
3126 | - p9_free_req(clnt, req); | ||
3127 | + p9_tag_remove(clnt, req); | ||
3128 | return err; | ||
3129 | |||
3130 | } | ||
3131 | @@ -2231,14 +2227,14 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status) | ||
3132 | if (IS_ERR(req)) | ||
3133 | return PTR_ERR(req); | ||
3134 | |||
3135 | - err = p9pdu_readf(req->rc, clnt->proto_version, "b", status); | ||
3136 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "b", status); | ||
3137 | if (err) { | ||
3138 | - trace_9p_protocol_dump(clnt, req->rc); | ||
3139 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
3140 | goto error; | ||
3141 | } | ||
3142 | p9_debug(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status); | ||
3143 | error: | ||
3144 | - p9_free_req(clnt, req); | ||
3145 | + p9_tag_remove(clnt, req); | ||
3146 | return err; | ||
3147 | |||
3148 | } | ||
3149 | @@ -2262,18 +2258,18 @@ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock) | ||
3150 | if (IS_ERR(req)) | ||
3151 | return PTR_ERR(req); | ||
3152 | |||
3153 | - err = p9pdu_readf(req->rc, clnt->proto_version, "bqqds", &glock->type, | ||
3154 | - &glock->start, &glock->length, &glock->proc_id, | ||
3155 | - &glock->client_id); | ||
3156 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "bqqds", &glock->type, | ||
3157 | + &glock->start, &glock->length, &glock->proc_id, | ||
3158 | + &glock->client_id); | ||
3159 | if (err) { | ||
3160 | - trace_9p_protocol_dump(clnt, req->rc); | ||
3161 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
3162 | goto error; | ||
3163 | } | ||
3164 | p9_debug(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld " | ||
3165 | "proc_id %d client_id %s\n", glock->type, glock->start, | ||
3166 | glock->length, glock->proc_id, glock->client_id); | ||
3167 | error: | ||
3168 | - p9_free_req(clnt, req); | ||
3169 | + p9_tag_remove(clnt, req); | ||
3170 | return err; | ||
3171 | } | ||
3172 | EXPORT_SYMBOL(p9_client_getlock_dotl); | ||
3173 | @@ -2292,14 +2288,25 @@ int p9_client_readlink(struct p9_fid *fid, char **target) | ||
3174 | if (IS_ERR(req)) | ||
3175 | return PTR_ERR(req); | ||
3176 | |||
3177 | - err = p9pdu_readf(req->rc, clnt->proto_version, "s", target); | ||
3178 | + err = p9pdu_readf(&req->rc, clnt->proto_version, "s", target); | ||
3179 | if (err) { | ||
3180 | - trace_9p_protocol_dump(clnt, req->rc); | ||
3181 | + trace_9p_protocol_dump(clnt, &req->rc); | ||
3182 | goto error; | ||
3183 | } | ||
3184 | p9_debug(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target); | ||
3185 | error: | ||
3186 | - p9_free_req(clnt, req); | ||
3187 | + p9_tag_remove(clnt, req); | ||
3188 | return err; | ||
3189 | } | ||
3190 | EXPORT_SYMBOL(p9_client_readlink); | ||
3191 | + | ||
3192 | +int __init p9_client_init(void) | ||
3193 | +{ | ||
3194 | + p9_req_cache = KMEM_CACHE(p9_req_t, SLAB_TYPESAFE_BY_RCU); | ||
3195 | + return p9_req_cache ? 0 : -ENOMEM; | ||
3196 | +} | ||
3197 | + | ||
3198 | +void __exit p9_client_exit(void) | ||
3199 | +{ | ||
3200 | + kmem_cache_destroy(p9_req_cache); | ||
3201 | +} | ||
3202 | diff --git a/net/9p/mod.c b/net/9p/mod.c | ||
3203 | index 253ba824a325..0da56d6af73b 100644 | ||
3204 | --- a/net/9p/mod.c | ||
3205 | +++ b/net/9p/mod.c | ||
3206 | @@ -171,11 +171,17 @@ void v9fs_put_trans(struct p9_trans_module *m) | ||
3207 | */ | ||
3208 | static int __init init_p9(void) | ||
3209 | { | ||
3210 | + int ret; | ||
3211 | + | ||
3212 | + ret = p9_client_init(); | ||
3213 | + if (ret) | ||
3214 | + return ret; | ||
3215 | + | ||
3216 | p9_error_init(); | ||
3217 | pr_info("Installing 9P2000 support\n"); | ||
3218 | p9_trans_fd_init(); | ||
3219 | |||
3220 | - return 0; | ||
3221 | + return ret; | ||
3222 | } | ||
3223 | |||
3224 | /** | ||
3225 | @@ -188,6 +194,7 @@ static void __exit exit_p9(void) | ||
3226 | pr_info("Unloading 9P2000 support\n"); | ||
3227 | |||
3228 | p9_trans_fd_exit(); | ||
3229 | + p9_client_exit(); | ||
3230 | } | ||
3231 | |||
3232 | module_init(init_p9) | ||
3233 | diff --git a/net/9p/protocol.c b/net/9p/protocol.c | ||
3234 | index b4d80c533f89..462ba144cb39 100644 | ||
3235 | --- a/net/9p/protocol.c | ||
3236 | +++ b/net/9p/protocol.c | ||
3237 | @@ -623,13 +623,19 @@ int p9dirent_read(struct p9_client *clnt, char *buf, int len, | ||
3238 | if (ret) { | ||
3239 | p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret); | ||
3240 | trace_9p_protocol_dump(clnt, &fake_pdu); | ||
3241 | - goto out; | ||
3242 | + return ret; | ||
3243 | } | ||
3244 | |||
3245 | - strcpy(dirent->d_name, nameptr); | ||
3246 | + ret = strscpy(dirent->d_name, nameptr, sizeof(dirent->d_name)); | ||
3247 | + if (ret < 0) { | ||
3248 | + p9_debug(P9_DEBUG_ERROR, | ||
3249 | + "On the wire dirent name too long: %s\n", | ||
3250 | + nameptr); | ||
3251 | + kfree(nameptr); | ||
3252 | + return ret; | ||
3253 | + } | ||
3254 | kfree(nameptr); | ||
3255 | |||
3256 | -out: | ||
3257 | return fake_pdu.offset; | ||
3258 | } | ||
3259 | EXPORT_SYMBOL(p9dirent_read); | ||
3260 | diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c | ||
3261 | index b718db2085b2..3dff68f05fb9 100644 | ||
3262 | --- a/net/9p/trans_common.c | ||
3263 | +++ b/net/9p/trans_common.c | ||
3264 | @@ -14,6 +14,7 @@ | ||
3265 | |||
3266 | #include <linux/mm.h> | ||
3267 | #include <linux/module.h> | ||
3268 | +#include "trans_common.h" | ||
3269 | |||
3270 | /** | ||
3271 | * p9_release_pages - Release pages after the transaction. | ||
3272 | diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c | ||
3273 | index e2ef3c782c53..f868cf6fba79 100644 | ||
3274 | --- a/net/9p/trans_fd.c | ||
3275 | +++ b/net/9p/trans_fd.c | ||
3276 | @@ -131,7 +131,8 @@ struct p9_conn { | ||
3277 | int err; | ||
3278 | struct list_head req_list; | ||
3279 | struct list_head unsent_req_list; | ||
3280 | - struct p9_req_t *req; | ||
3281 | + struct p9_req_t *rreq; | ||
3282 | + struct p9_req_t *wreq; | ||
3283 | char tmp_buf[7]; | ||
3284 | struct p9_fcall rc; | ||
3285 | int wpos; | ||
3286 | @@ -291,7 +292,6 @@ static void p9_read_work(struct work_struct *work) | ||
3287 | __poll_t n; | ||
3288 | int err; | ||
3289 | struct p9_conn *m; | ||
3290 | - int status = REQ_STATUS_ERROR; | ||
3291 | |||
3292 | m = container_of(work, struct p9_conn, rq); | ||
3293 | |||
3294 | @@ -322,7 +322,7 @@ static void p9_read_work(struct work_struct *work) | ||
3295 | m->rc.offset += err; | ||
3296 | |||
3297 | /* header read in */ | ||
3298 | - if ((!m->req) && (m->rc.offset == m->rc.capacity)) { | ||
3299 | + if ((!m->rreq) && (m->rc.offset == m->rc.capacity)) { | ||
3300 | p9_debug(P9_DEBUG_TRANS, "got new header\n"); | ||
3301 | |||
3302 | /* Header size */ | ||
3303 | @@ -346,23 +346,23 @@ static void p9_read_work(struct work_struct *work) | ||
3304 | "mux %p pkt: size: %d bytes tag: %d\n", | ||
3305 | m, m->rc.size, m->rc.tag); | ||
3306 | |||
3307 | - m->req = p9_tag_lookup(m->client, m->rc.tag); | ||
3308 | - if (!m->req || (m->req->status != REQ_STATUS_SENT)) { | ||
3309 | + m->rreq = p9_tag_lookup(m->client, m->rc.tag); | ||
3310 | + if (!m->rreq || (m->rreq->status != REQ_STATUS_SENT)) { | ||
3311 | p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", | ||
3312 | m->rc.tag); | ||
3313 | err = -EIO; | ||
3314 | goto error; | ||
3315 | } | ||
3316 | |||
3317 | - if (m->req->rc == NULL) { | ||
3318 | + if (!m->rreq->rc.sdata) { | ||
3319 | p9_debug(P9_DEBUG_ERROR, | ||
3320 | "No recv fcall for tag %d (req %p), disconnecting!\n", | ||
3321 | - m->rc.tag, m->req); | ||
3322 | - m->req = NULL; | ||
3323 | + m->rc.tag, m->rreq); | ||
3324 | + m->rreq = NULL; | ||
3325 | err = -EIO; | ||
3326 | goto error; | ||
3327 | } | ||
3328 | - m->rc.sdata = (char *)m->req->rc + sizeof(struct p9_fcall); | ||
3329 | + m->rc.sdata = m->rreq->rc.sdata; | ||
3330 | memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity); | ||
3331 | m->rc.capacity = m->rc.size; | ||
3332 | } | ||
3333 | @@ -370,20 +370,27 @@ static void p9_read_work(struct work_struct *work) | ||
3334 | /* packet is read in | ||
3335 | * not an else because some packets (like clunk) have no payload | ||
3336 | */ | ||
3337 | - if ((m->req) && (m->rc.offset == m->rc.capacity)) { | ||
3338 | + if ((m->rreq) && (m->rc.offset == m->rc.capacity)) { | ||
3339 | p9_debug(P9_DEBUG_TRANS, "got new packet\n"); | ||
3340 | - m->req->rc->size = m->rc.offset; | ||
3341 | + m->rreq->rc.size = m->rc.offset; | ||
3342 | spin_lock(&m->client->lock); | ||
3343 | - if (m->req->status != REQ_STATUS_ERROR) | ||
3344 | - status = REQ_STATUS_RCVD; | ||
3345 | - list_del(&m->req->req_list); | ||
3346 | - /* update req->status while holding client->lock */ | ||
3347 | - p9_client_cb(m->client, m->req, status); | ||
3348 | + if (m->rreq->status == REQ_STATUS_SENT) { | ||
3349 | + list_del(&m->rreq->req_list); | ||
3350 | + p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD); | ||
3351 | + } else { | ||
3352 | + spin_unlock(&m->client->lock); | ||
3353 | + p9_debug(P9_DEBUG_ERROR, | ||
3354 | + "Request tag %d errored out while we were reading the reply\n", | ||
3355 | + m->rc.tag); | ||
3356 | + err = -EIO; | ||
3357 | + goto error; | ||
3358 | + } | ||
3359 | spin_unlock(&m->client->lock); | ||
3360 | m->rc.sdata = NULL; | ||
3361 | m->rc.offset = 0; | ||
3362 | m->rc.capacity = 0; | ||
3363 | - m->req = NULL; | ||
3364 | + p9_req_put(m->rreq); | ||
3365 | + m->rreq = NULL; | ||
3366 | } | ||
3367 | |||
3368 | end_clear: | ||
3369 | @@ -469,9 +476,11 @@ static void p9_write_work(struct work_struct *work) | ||
3370 | p9_debug(P9_DEBUG_TRANS, "move req %p\n", req); | ||
3371 | list_move_tail(&req->req_list, &m->req_list); | ||
3372 | |||
3373 | - m->wbuf = req->tc->sdata; | ||
3374 | - m->wsize = req->tc->size; | ||
3375 | + m->wbuf = req->tc.sdata; | ||
3376 | + m->wsize = req->tc.size; | ||
3377 | m->wpos = 0; | ||
3378 | + p9_req_get(req); | ||
3379 | + m->wreq = req; | ||
3380 | spin_unlock(&m->client->lock); | ||
3381 | } | ||
3382 | |||
3383 | @@ -492,8 +501,11 @@ static void p9_write_work(struct work_struct *work) | ||
3384 | } | ||
3385 | |||
3386 | m->wpos += err; | ||
3387 | - if (m->wpos == m->wsize) | ||
3388 | + if (m->wpos == m->wsize) { | ||
3389 | m->wpos = m->wsize = 0; | ||
3390 | + p9_req_put(m->wreq); | ||
3391 | + m->wreq = NULL; | ||
3392 | + } | ||
3393 | |||
3394 | end_clear: | ||
3395 | clear_bit(Wworksched, &m->wsched); | ||
3396 | @@ -663,7 +675,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) | ||
3397 | struct p9_conn *m = &ts->conn; | ||
3398 | |||
3399 | p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", | ||
3400 | - m, current, req->tc, req->tc->id); | ||
3401 | + m, current, &req->tc, req->tc.id); | ||
3402 | if (m->err < 0) | ||
3403 | return m->err; | ||
3404 | |||
3405 | @@ -694,6 +706,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) | ||
3406 | if (req->status == REQ_STATUS_UNSENT) { | ||
3407 | list_del(&req->req_list); | ||
3408 | req->status = REQ_STATUS_FLSHD; | ||
3409 | + p9_req_put(req); | ||
3410 | ret = 0; | ||
3411 | } | ||
3412 | spin_unlock(&client->lock); | ||
3413 | @@ -711,6 +724,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) | ||
3414 | spin_lock(&client->lock); | ||
3415 | list_del(&req->req_list); | ||
3416 | spin_unlock(&client->lock); | ||
3417 | + p9_req_put(req); | ||
3418 | |||
3419 | return 0; | ||
3420 | } | ||
3421 | @@ -862,7 +876,15 @@ static void p9_conn_destroy(struct p9_conn *m) | ||
3422 | |||
3423 | p9_mux_poll_stop(m); | ||
3424 | cancel_work_sync(&m->rq); | ||
3425 | + if (m->rreq) { | ||
3426 | + p9_req_put(m->rreq); | ||
3427 | + m->rreq = NULL; | ||
3428 | + } | ||
3429 | cancel_work_sync(&m->wq); | ||
3430 | + if (m->wreq) { | ||
3431 | + p9_req_put(m->wreq); | ||
3432 | + m->wreq = NULL; | ||
3433 | + } | ||
3434 | |||
3435 | p9_conn_cancel(m, -ECONNRESET); | ||
3436 | |||
3437 | diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c | ||
3438 | index b513cffeeb3c..119103bfa82e 100644 | ||
3439 | --- a/net/9p/trans_rdma.c | ||
3440 | +++ b/net/9p/trans_rdma.c | ||
3441 | @@ -122,7 +122,7 @@ struct p9_rdma_context { | ||
3442 | dma_addr_t busa; | ||
3443 | union { | ||
3444 | struct p9_req_t *req; | ||
3445 | - struct p9_fcall *rc; | ||
3446 | + struct p9_fcall rc; | ||
3447 | }; | ||
3448 | }; | ||
3449 | |||
3450 | @@ -274,8 +274,7 @@ p9_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event) | ||
3451 | case RDMA_CM_EVENT_DISCONNECTED: | ||
3452 | if (rdma) | ||
3453 | rdma->state = P9_RDMA_CLOSED; | ||
3454 | - if (c) | ||
3455 | - c->status = Disconnected; | ||
3456 | + c->status = Disconnected; | ||
3457 | break; | ||
3458 | |||
3459 | case RDMA_CM_EVENT_TIMEWAIT_EXIT: | ||
3460 | @@ -320,8 +319,8 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc) | ||
3461 | if (wc->status != IB_WC_SUCCESS) | ||
3462 | goto err_out; | ||
3463 | |||
3464 | - c->rc->size = wc->byte_len; | ||
3465 | - err = p9_parse_header(c->rc, NULL, NULL, &tag, 1); | ||
3466 | + c->rc.size = wc->byte_len; | ||
3467 | + err = p9_parse_header(&c->rc, NULL, NULL, &tag, 1); | ||
3468 | if (err) | ||
3469 | goto err_out; | ||
3470 | |||
3471 | @@ -331,12 +330,13 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc) | ||
3472 | |||
3473 | /* Check that we have not yet received a reply for this request. | ||
3474 | */ | ||
3475 | - if (unlikely(req->rc)) { | ||
3476 | + if (unlikely(req->rc.sdata)) { | ||
3477 | pr_err("Duplicate reply for request %d", tag); | ||
3478 | goto err_out; | ||
3479 | } | ||
3480 | |||
3481 | - req->rc = c->rc; | ||
3482 | + req->rc.size = c->rc.size; | ||
3483 | + req->rc.sdata = c->rc.sdata; | ||
3484 | p9_client_cb(client, req, REQ_STATUS_RCVD); | ||
3485 | |||
3486 | out: | ||
3487 | @@ -361,9 +361,10 @@ send_done(struct ib_cq *cq, struct ib_wc *wc) | ||
3488 | container_of(wc->wr_cqe, struct p9_rdma_context, cqe); | ||
3489 | |||
3490 | ib_dma_unmap_single(rdma->cm_id->device, | ||
3491 | - c->busa, c->req->tc->size, | ||
3492 | + c->busa, c->req->tc.size, | ||
3493 | DMA_TO_DEVICE); | ||
3494 | up(&rdma->sq_sem); | ||
3495 | + p9_req_put(c->req); | ||
3496 | kfree(c); | ||
3497 | } | ||
3498 | |||
3499 | @@ -401,7 +402,7 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c) | ||
3500 | struct ib_sge sge; | ||
3501 | |||
3502 | c->busa = ib_dma_map_single(rdma->cm_id->device, | ||
3503 | - c->rc->sdata, client->msize, | ||
3504 | + c->rc.sdata, client->msize, | ||
3505 | DMA_FROM_DEVICE); | ||
3506 | if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) | ||
3507 | goto error; | ||
3508 | @@ -443,9 +444,9 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | ||
3509 | **/ | ||
3510 | if (unlikely(atomic_read(&rdma->excess_rc) > 0)) { | ||
3511 | if ((atomic_sub_return(1, &rdma->excess_rc) >= 0)) { | ||
3512 | - /* Got one ! */ | ||
3513 | - kfree(req->rc); | ||
3514 | - req->rc = NULL; | ||
3515 | + /* Got one! */ | ||
3516 | + p9_fcall_fini(&req->rc); | ||
3517 | + req->rc.sdata = NULL; | ||
3518 | goto dont_need_post_recv; | ||
3519 | } else { | ||
3520 | /* We raced and lost. */ | ||
3521 | @@ -459,7 +460,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | ||
3522 | err = -ENOMEM; | ||
3523 | goto recv_error; | ||
3524 | } | ||
3525 | - rpl_context->rc = req->rc; | ||
3526 | + rpl_context->rc.sdata = req->rc.sdata; | ||
3527 | |||
3528 | /* | ||
3529 | * Post a receive buffer for this request. We need to ensure | ||
3530 | @@ -475,11 +476,11 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | ||
3531 | |||
3532 | err = post_recv(client, rpl_context); | ||
3533 | if (err) { | ||
3534 | - p9_debug(P9_DEBUG_FCALL, "POST RECV failed\n"); | ||
3535 | + p9_debug(P9_DEBUG_ERROR, "POST RECV failed: %d\n", err); | ||
3536 | goto recv_error; | ||
3537 | } | ||
3538 | /* remove posted receive buffer from request structure */ | ||
3539 | - req->rc = NULL; | ||
3540 | + req->rc.sdata = NULL; | ||
3541 | |||
3542 | dont_need_post_recv: | ||
3543 | /* Post the request */ | ||
3544 | @@ -491,7 +492,7 @@ dont_need_post_recv: | ||
3545 | c->req = req; | ||
3546 | |||
3547 | c->busa = ib_dma_map_single(rdma->cm_id->device, | ||
3548 | - c->req->tc->sdata, c->req->tc->size, | ||
3549 | + c->req->tc.sdata, c->req->tc.size, | ||
3550 | DMA_TO_DEVICE); | ||
3551 | if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) { | ||
3552 | err = -EIO; | ||
3553 | @@ -501,7 +502,7 @@ dont_need_post_recv: | ||
3554 | c->cqe.done = send_done; | ||
3555 | |||
3556 | sge.addr = c->busa; | ||
3557 | - sge.length = c->req->tc->size; | ||
3558 | + sge.length = c->req->tc.size; | ||
3559 | sge.lkey = rdma->pd->local_dma_lkey; | ||
3560 | |||
3561 | wr.next = NULL; | ||
3562 | @@ -544,7 +545,7 @@ dont_need_post_recv: | ||
3563 | recv_error: | ||
3564 | kfree(rpl_context); | ||
3565 | spin_lock_irqsave(&rdma->req_lock, flags); | ||
3566 | - if (rdma->state < P9_RDMA_CLOSING) { | ||
3567 | + if (err != -EINTR && rdma->state < P9_RDMA_CLOSING) { | ||
3568 | rdma->state = P9_RDMA_CLOSING; | ||
3569 | spin_unlock_irqrestore(&rdma->req_lock, flags); | ||
3570 | rdma_disconnect(rdma->cm_id); | ||
3571 | diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c | ||
3572 | index 7728b0acde09..eb596c2ed546 100644 | ||
3573 | --- a/net/9p/trans_virtio.c | ||
3574 | +++ b/net/9p/trans_virtio.c | ||
3575 | @@ -155,7 +155,7 @@ static void req_done(struct virtqueue *vq) | ||
3576 | } | ||
3577 | |||
3578 | if (len) { | ||
3579 | - req->rc->size = len; | ||
3580 | + req->rc.size = len; | ||
3581 | p9_client_cb(chan->client, req, REQ_STATUS_RCVD); | ||
3582 | } | ||
3583 | } | ||
3584 | @@ -207,6 +207,13 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req) | ||
3585 | return 1; | ||
3586 | } | ||
3587 | |||
3588 | +/* Reply won't come, so drop req ref */ | ||
3589 | +static int p9_virtio_cancelled(struct p9_client *client, struct p9_req_t *req) | ||
3590 | +{ | ||
3591 | + p9_req_put(req); | ||
3592 | + return 0; | ||
3593 | +} | ||
3594 | + | ||
3595 | /** | ||
3596 | * pack_sg_list_p - Just like pack_sg_list. Instead of taking a buffer, | ||
3597 | * this takes a list of pages. | ||
3598 | @@ -273,12 +280,12 @@ req_retry: | ||
3599 | out_sgs = in_sgs = 0; | ||
3600 | /* Handle out VirtIO ring buffers */ | ||
3601 | out = pack_sg_list(chan->sg, 0, | ||
3602 | - VIRTQUEUE_NUM, req->tc->sdata, req->tc->size); | ||
3603 | + VIRTQUEUE_NUM, req->tc.sdata, req->tc.size); | ||
3604 | if (out) | ||
3605 | sgs[out_sgs++] = chan->sg; | ||
3606 | |||
3607 | in = pack_sg_list(chan->sg, out, | ||
3608 | - VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity); | ||
3609 | + VIRTQUEUE_NUM, req->rc.sdata, req->rc.capacity); | ||
3610 | if (in) | ||
3611 | sgs[out_sgs + in_sgs++] = chan->sg + out; | ||
3612 | |||
3613 | @@ -404,6 +411,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, | ||
3614 | struct scatterlist *sgs[4]; | ||
3615 | size_t offs; | ||
3616 | int need_drop = 0; | ||
3617 | + int kicked = 0; | ||
3618 | |||
3619 | p9_debug(P9_DEBUG_TRANS, "virtio request\n"); | ||
3620 | |||
3621 | @@ -411,29 +419,33 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, | ||
3622 | __le32 sz; | ||
3623 | int n = p9_get_mapped_pages(chan, &out_pages, uodata, | ||
3624 | outlen, &offs, &need_drop); | ||
3625 | - if (n < 0) | ||
3626 | - return n; | ||
3627 | + if (n < 0) { | ||
3628 | + err = n; | ||
3629 | + goto err_out; | ||
3630 | + } | ||
3631 | out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE); | ||
3632 | if (n != outlen) { | ||
3633 | __le32 v = cpu_to_le32(n); | ||
3634 | - memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4); | ||
3635 | + memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4); | ||
3636 | outlen = n; | ||
3637 | } | ||
3638 | /* The size field of the message must include the length of the | ||
3639 | * header and the length of the data. We didn't actually know | ||
3640 | * the length of the data until this point so add it in now. | ||
3641 | */ | ||
3642 | - sz = cpu_to_le32(req->tc->size + outlen); | ||
3643 | - memcpy(&req->tc->sdata[0], &sz, sizeof(sz)); | ||
3644 | + sz = cpu_to_le32(req->tc.size + outlen); | ||
3645 | + memcpy(&req->tc.sdata[0], &sz, sizeof(sz)); | ||
3646 | } else if (uidata) { | ||
3647 | int n = p9_get_mapped_pages(chan, &in_pages, uidata, | ||
3648 | inlen, &offs, &need_drop); | ||
3649 | - if (n < 0) | ||
3650 | - return n; | ||
3651 | + if (n < 0) { | ||
3652 | + err = n; | ||
3653 | + goto err_out; | ||
3654 | + } | ||
3655 | in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE); | ||
3656 | if (n != inlen) { | ||
3657 | __le32 v = cpu_to_le32(n); | ||
3658 | - memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4); | ||
3659 | + memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4); | ||
3660 | inlen = n; | ||
3661 | } | ||
3662 | } | ||
3663 | @@ -445,7 +457,7 @@ req_retry_pinned: | ||
3664 | |||
3665 | /* out data */ | ||
3666 | out = pack_sg_list(chan->sg, 0, | ||
3667 | - VIRTQUEUE_NUM, req->tc->sdata, req->tc->size); | ||
3668 | + VIRTQUEUE_NUM, req->tc.sdata, req->tc.size); | ||
3669 | |||
3670 | if (out) | ||
3671 | sgs[out_sgs++] = chan->sg; | ||
3672 | @@ -464,7 +476,7 @@ req_retry_pinned: | ||
3673 | * alloced memory and payload onto the user buffer. | ||
3674 | */ | ||
3675 | in = pack_sg_list(chan->sg, out, | ||
3676 | - VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len); | ||
3677 | + VIRTQUEUE_NUM, req->rc.sdata, in_hdr_len); | ||
3678 | if (in) | ||
3679 | sgs[out_sgs + in_sgs++] = chan->sg + out; | ||
3680 | |||
3681 | @@ -498,6 +510,7 @@ req_retry_pinned: | ||
3682 | } | ||
3683 | virtqueue_kick(chan->vq); | ||
3684 | spin_unlock_irqrestore(&chan->lock, flags); | ||
3685 | + kicked = 1; | ||
3686 | p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n"); | ||
3687 | err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD); | ||
3688 | /* | ||
3689 | @@ -518,6 +531,10 @@ err_out: | ||
3690 | } | ||
3691 | kvfree(in_pages); | ||
3692 | kvfree(out_pages); | ||
3693 | + if (!kicked) { | ||
3694 | + /* reply won't come */ | ||
3695 | + p9_req_put(req); | ||
3696 | + } | ||
3697 | return err; | ||
3698 | } | ||
3699 | |||
3700 | @@ -750,6 +767,7 @@ static struct p9_trans_module p9_virtio_trans = { | ||
3701 | .request = p9_virtio_request, | ||
3702 | .zc_request = p9_virtio_zc_request, | ||
3703 | .cancel = p9_virtio_cancel, | ||
3704 | + .cancelled = p9_virtio_cancelled, | ||
3705 | /* | ||
3706 | * We leave one entry for input and one entry for response | ||
3707 | * headers. We also skip one more entry to accomodate, address | ||
3708 | diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c | ||
3709 | index c2d54ac76bfd..e2fbf3677b9b 100644 | ||
3710 | --- a/net/9p/trans_xen.c | ||
3711 | +++ b/net/9p/trans_xen.c | ||
3712 | @@ -141,7 +141,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req) | ||
3713 | struct xen_9pfs_front_priv *priv = NULL; | ||
3714 | RING_IDX cons, prod, masked_cons, masked_prod; | ||
3715 | unsigned long flags; | ||
3716 | - u32 size = p9_req->tc->size; | ||
3717 | + u32 size = p9_req->tc.size; | ||
3718 | struct xen_9pfs_dataring *ring; | ||
3719 | int num; | ||
3720 | |||
3721 | @@ -154,7 +154,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req) | ||
3722 | if (!priv || priv->client != client) | ||
3723 | return -EINVAL; | ||
3724 | |||
3725 | - num = p9_req->tc->tag % priv->num_rings; | ||
3726 | + num = p9_req->tc.tag % priv->num_rings; | ||
3727 | ring = &priv->rings[num]; | ||
3728 | |||
3729 | again: | ||
3730 | @@ -176,7 +176,7 @@ again: | ||
3731 | masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE); | ||
3732 | masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE); | ||
3733 | |||
3734 | - xen_9pfs_write_packet(ring->data.out, p9_req->tc->sdata, size, | ||
3735 | + xen_9pfs_write_packet(ring->data.out, p9_req->tc.sdata, size, | ||
3736 | &masked_prod, masked_cons, XEN_9PFS_RING_SIZE); | ||
3737 | |||
3738 | p9_req->status = REQ_STATUS_SENT; | ||
3739 | @@ -185,6 +185,7 @@ again: | ||
3740 | ring->intf->out_prod = prod; | ||
3741 | spin_unlock_irqrestore(&ring->lock, flags); | ||
3742 | notify_remote_via_irq(ring->irq); | ||
3743 | + p9_req_put(p9_req); | ||
3744 | |||
3745 | return 0; | ||
3746 | } | ||
3747 | @@ -229,12 +230,12 @@ static void p9_xen_response(struct work_struct *work) | ||
3748 | continue; | ||
3749 | } | ||
3750 | |||
3751 | - memcpy(req->rc, &h, sizeof(h)); | ||
3752 | - req->rc->offset = 0; | ||
3753 | + memcpy(&req->rc, &h, sizeof(h)); | ||
3754 | + req->rc.offset = 0; | ||
3755 | |||
3756 | masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE); | ||
3757 | /* Then, read the whole packet (including the header) */ | ||
3758 | - xen_9pfs_read_packet(req->rc->sdata, ring->data.in, h.size, | ||
3759 | + xen_9pfs_read_packet(req->rc.sdata, ring->data.in, h.size, | ||
3760 | masked_prod, &masked_cons, | ||
3761 | XEN_9PFS_RING_SIZE); | ||
3762 | |||
3763 | @@ -391,8 +392,8 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev, | ||
3764 | unsigned int max_rings, max_ring_order, len = 0; | ||
3765 | |||
3766 | versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len); | ||
3767 | - if (!len) | ||
3768 | - return -EINVAL; | ||
3769 | + if (IS_ERR(versions)) | ||
3770 | + return PTR_ERR(versions); | ||
3771 | if (strcmp(versions, "1")) { | ||
3772 | kfree(versions); | ||
3773 | return -EINVAL; | ||
3774 | diff --git a/net/core/filter.c b/net/core/filter.c | ||
3775 | index eb81e9db4093..34ec9324737b 100644 | ||
3776 | --- a/net/core/filter.c | ||
3777 | +++ b/net/core/filter.c | ||
3778 | @@ -5558,6 +5558,7 @@ static bool sock_addr_is_valid_access(int off, int size, | ||
3779 | case BPF_CGROUP_INET4_BIND: | ||
3780 | case BPF_CGROUP_INET4_CONNECT: | ||
3781 | case BPF_CGROUP_UDP4_SENDMSG: | ||
3782 | + case BPF_CGROUP_UDP4_RECVMSG: | ||
3783 | break; | ||
3784 | default: | ||
3785 | return false; | ||
3786 | @@ -5568,6 +5569,7 @@ static bool sock_addr_is_valid_access(int off, int size, | ||
3787 | case BPF_CGROUP_INET6_BIND: | ||
3788 | case BPF_CGROUP_INET6_CONNECT: | ||
3789 | case BPF_CGROUP_UDP6_SENDMSG: | ||
3790 | + case BPF_CGROUP_UDP6_RECVMSG: | ||
3791 | break; | ||
3792 | default: | ||
3793 | return false; | ||
3794 | diff --git a/net/core/sock.c b/net/core/sock.c | ||
3795 | index c9668dcb5eb9..9c32e8eb64da 100644 | ||
3796 | --- a/net/core/sock.c | ||
3797 | +++ b/net/core/sock.c | ||
3798 | @@ -1348,9 +1348,6 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | ||
3799 | { | ||
3800 | u32 meminfo[SK_MEMINFO_VARS]; | ||
3801 | |||
3802 | - if (get_user(len, optlen)) | ||
3803 | - return -EFAULT; | ||
3804 | - | ||
3805 | sk_get_meminfo(sk, meminfo); | ||
3806 | |||
3807 | len = min_t(unsigned int, len, sizeof(meminfo)); | ||
3808 | diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c | ||
3809 | index 711a5c75bd4b..21800979ed62 100644 | ||
3810 | --- a/net/ipv4/raw.c | ||
3811 | +++ b/net/ipv4/raw.c | ||
3812 | @@ -202,7 +202,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) | ||
3813 | } | ||
3814 | sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol, | ||
3815 | iph->saddr, iph->daddr, | ||
3816 | - skb->dev->ifindex, sdif); | ||
3817 | + dif, sdif); | ||
3818 | } | ||
3819 | out: | ||
3820 | read_unlock(&raw_v4_hashinfo.lock); | ||
3821 | diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c | ||
3822 | index e45a5e19e509..6ab68b06fa39 100644 | ||
3823 | --- a/net/ipv4/udp.c | ||
3824 | +++ b/net/ipv4/udp.c | ||
3825 | @@ -542,7 +542,11 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb, | ||
3826 | struct sock *udp4_lib_lookup_skb(struct sk_buff *skb, | ||
3827 | __be16 sport, __be16 dport) | ||
3828 | { | ||
3829 | - return __udp4_lib_lookup_skb(skb, sport, dport, &udp_table); | ||
3830 | + const struct iphdr *iph = ip_hdr(skb); | ||
3831 | + | ||
3832 | + return __udp4_lib_lookup(dev_net(skb->dev), iph->saddr, sport, | ||
3833 | + iph->daddr, dport, inet_iif(skb), | ||
3834 | + inet_sdif(skb), &udp_table, NULL); | ||
3835 | } | ||
3836 | EXPORT_SYMBOL_GPL(udp4_lib_lookup_skb); | ||
3837 | |||
3838 | @@ -1720,6 +1724,10 @@ try_again: | ||
3839 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; | ||
3840 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); | ||
3841 | *addr_len = sizeof(*sin); | ||
3842 | + | ||
3843 | + if (cgroup_bpf_enabled) | ||
3844 | + BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, | ||
3845 | + (struct sockaddr *)sin); | ||
3846 | } | ||
3847 | if (inet->cmsg_flags) | ||
3848 | ip_cmsg_recv_offset(msg, sk, skb, sizeof(struct udphdr), off); | ||
3849 | diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c | ||
3850 | index cab8b2b647f9..164f1d01273c 100644 | ||
3851 | --- a/net/ipv6/udp.c | ||
3852 | +++ b/net/ipv6/udp.c | ||
3853 | @@ -282,7 +282,7 @@ struct sock *udp6_lib_lookup_skb(struct sk_buff *skb, | ||
3854 | |||
3855 | return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport, | ||
3856 | &iph->daddr, dport, inet6_iif(skb), | ||
3857 | - inet6_sdif(skb), &udp_table, skb); | ||
3858 | + inet6_sdif(skb), &udp_table, NULL); | ||
3859 | } | ||
3860 | EXPORT_SYMBOL_GPL(udp6_lib_lookup_skb); | ||
3861 | |||
3862 | @@ -419,6 +419,10 @@ try_again: | ||
3863 | inet6_iif(skb)); | ||
3864 | } | ||
3865 | *addr_len = sizeof(*sin6); | ||
3866 | + | ||
3867 | + if (cgroup_bpf_enabled) | ||
3868 | + BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, | ||
3869 | + (struct sockaddr *)sin6); | ||
3870 | } | ||
3871 | |||
3872 | if (np->rxopt.all) | ||
3873 | @@ -478,7 +482,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | ||
3874 | struct net *net = dev_net(skb->dev); | ||
3875 | |||
3876 | sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, | ||
3877 | - inet6_iif(skb), 0, udptable, skb); | ||
3878 | + inet6_iif(skb), 0, udptable, NULL); | ||
3879 | if (!sk) { | ||
3880 | __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), | ||
3881 | ICMP6_MIB_INERRORS); | ||
3882 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c | ||
3883 | index d98fcf926166..93b5a4200585 100644 | ||
3884 | --- a/net/packet/af_packet.c | ||
3885 | +++ b/net/packet/af_packet.c | ||
3886 | @@ -2399,6 +2399,9 @@ static void tpacket_destruct_skb(struct sk_buff *skb) | ||
3887 | |||
3888 | ts = __packet_set_timestamp(po, ph, skb); | ||
3889 | __packet_set_status(po, ph, TP_STATUS_AVAILABLE | ts); | ||
3890 | + | ||
3891 | + if (!packet_read_pending(&po->tx_ring)) | ||
3892 | + complete(&po->skb_completion); | ||
3893 | } | ||
3894 | |||
3895 | sock_wfree(skb); | ||
3896 | @@ -2594,7 +2597,7 @@ static int tpacket_parse_header(struct packet_sock *po, void *frame, | ||
3897 | |||
3898 | static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | ||
3899 | { | ||
3900 | - struct sk_buff *skb; | ||
3901 | + struct sk_buff *skb = NULL; | ||
3902 | struct net_device *dev; | ||
3903 | struct virtio_net_hdr *vnet_hdr = NULL; | ||
3904 | struct sockcm_cookie sockc; | ||
3905 | @@ -2609,6 +2612,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | ||
3906 | int len_sum = 0; | ||
3907 | int status = TP_STATUS_AVAILABLE; | ||
3908 | int hlen, tlen, copylen = 0; | ||
3909 | + long timeo = 0; | ||
3910 | |||
3911 | mutex_lock(&po->pg_vec_lock); | ||
3912 | |||
3913 | @@ -2655,12 +2659,21 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | ||
3914 | if ((size_max > dev->mtu + reserve + VLAN_HLEN) && !po->has_vnet_hdr) | ||
3915 | size_max = dev->mtu + reserve + VLAN_HLEN; | ||
3916 | |||
3917 | + reinit_completion(&po->skb_completion); | ||
3918 | + | ||
3919 | do { | ||
3920 | ph = packet_current_frame(po, &po->tx_ring, | ||
3921 | TP_STATUS_SEND_REQUEST); | ||
3922 | if (unlikely(ph == NULL)) { | ||
3923 | - if (need_wait && need_resched()) | ||
3924 | - schedule(); | ||
3925 | + if (need_wait && skb) { | ||
3926 | + timeo = sock_sndtimeo(&po->sk, msg->msg_flags & MSG_DONTWAIT); | ||
3927 | + timeo = wait_for_completion_interruptible_timeout(&po->skb_completion, timeo); | ||
3928 | + if (timeo <= 0) { | ||
3929 | + err = !timeo ? -ETIMEDOUT : -ERESTARTSYS; | ||
3930 | + goto out_put; | ||
3931 | + } | ||
3932 | + } | ||
3933 | + /* check for additional frames */ | ||
3934 | continue; | ||
3935 | } | ||
3936 | |||
3937 | @@ -3216,6 +3229,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, | ||
3938 | sock_init_data(sock, sk); | ||
3939 | |||
3940 | po = pkt_sk(sk); | ||
3941 | + init_completion(&po->skb_completion); | ||
3942 | sk->sk_family = PF_PACKET; | ||
3943 | po->num = proto; | ||
3944 | po->xmit = dev_queue_xmit; | ||
3945 | @@ -4302,7 +4316,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | ||
3946 | req3->tp_sizeof_priv || | ||
3947 | req3->tp_feature_req_word) { | ||
3948 | err = -EINVAL; | ||
3949 | - goto out; | ||
3950 | + goto out_free_pg_vec; | ||
3951 | } | ||
3952 | } | ||
3953 | break; | ||
3954 | @@ -4366,6 +4380,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | ||
3955 | prb_shutdown_retire_blk_timer(po, rb_queue); | ||
3956 | } | ||
3957 | |||
3958 | +out_free_pg_vec: | ||
3959 | if (pg_vec) | ||
3960 | free_pg_vec(pg_vec, order, req->tp_block_nr); | ||
3961 | out: | ||
3962 | diff --git a/net/packet/internal.h b/net/packet/internal.h | ||
3963 | index 3bb7c5fb3bff..c70a2794456f 100644 | ||
3964 | --- a/net/packet/internal.h | ||
3965 | +++ b/net/packet/internal.h | ||
3966 | @@ -128,6 +128,7 @@ struct packet_sock { | ||
3967 | unsigned int tp_hdrlen; | ||
3968 | unsigned int tp_reserve; | ||
3969 | unsigned int tp_tstamp; | ||
3970 | + struct completion skb_completion; | ||
3971 | struct net_device __rcu *cached_dev; | ||
3972 | int (*xmit)(struct sk_buff *skb); | ||
3973 | struct packet_type prot_hook ____cacheline_aligned_in_smp; | ||
3974 | diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c | ||
3975 | index 40c7eb941bc9..c99114eaf42e 100644 | ||
3976 | --- a/net/sctp/endpointola.c | ||
3977 | +++ b/net/sctp/endpointola.c | ||
3978 | @@ -126,10 +126,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | ||
3979 | /* Initialize the bind addr area */ | ||
3980 | sctp_bind_addr_init(&ep->base.bind_addr, 0); | ||
3981 | |||
3982 | - /* Remember who we are attached to. */ | ||
3983 | - ep->base.sk = sk; | ||
3984 | - sock_hold(ep->base.sk); | ||
3985 | - | ||
3986 | /* Create the lists of associations. */ | ||
3987 | INIT_LIST_HEAD(&ep->asocs); | ||
3988 | |||
3989 | @@ -167,6 +163,10 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | ||
3990 | ep->prsctp_enable = net->sctp.prsctp_enable; | ||
3991 | ep->reconf_enable = net->sctp.reconf_enable; | ||
3992 | |||
3993 | + /* Remember who we are attached to. */ | ||
3994 | + ep->base.sk = sk; | ||
3995 | + sock_hold(ep->base.sk); | ||
3996 | + | ||
3997 | return ep; | ||
3998 | |||
3999 | nomem_hmacs: | ||
4000 | diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c | ||
4001 | index 1fc812ba9871..7e4553dbc3c7 100644 | ||
4002 | --- a/net/sunrpc/clnt.c | ||
4003 | +++ b/net/sunrpc/clnt.c | ||
4004 | @@ -1558,7 +1558,6 @@ call_reserveresult(struct rpc_task *task) | ||
4005 | task->tk_status = 0; | ||
4006 | if (status >= 0) { | ||
4007 | if (task->tk_rqstp) { | ||
4008 | - xprt_request_init(task); | ||
4009 | task->tk_action = call_refresh; | ||
4010 | return; | ||
4011 | } | ||
4012 | diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c | ||
4013 | index d066aae3cb6d..3581168e6b99 100644 | ||
4014 | --- a/net/sunrpc/xprt.c | ||
4015 | +++ b/net/sunrpc/xprt.c | ||
4016 | @@ -1257,6 +1257,55 @@ void xprt_free(struct rpc_xprt *xprt) | ||
4017 | } | ||
4018 | EXPORT_SYMBOL_GPL(xprt_free); | ||
4019 | |||
4020 | +static __be32 | ||
4021 | +xprt_alloc_xid(struct rpc_xprt *xprt) | ||
4022 | +{ | ||
4023 | + __be32 xid; | ||
4024 | + | ||
4025 | + spin_lock(&xprt->reserve_lock); | ||
4026 | + xid = (__force __be32)xprt->xid++; | ||
4027 | + spin_unlock(&xprt->reserve_lock); | ||
4028 | + return xid; | ||
4029 | +} | ||
4030 | + | ||
4031 | +static void | ||
4032 | +xprt_init_xid(struct rpc_xprt *xprt) | ||
4033 | +{ | ||
4034 | + xprt->xid = prandom_u32(); | ||
4035 | +} | ||
4036 | + | ||
4037 | +static void | ||
4038 | +xprt_request_init(struct rpc_task *task) | ||
4039 | +{ | ||
4040 | + struct rpc_xprt *xprt = task->tk_xprt; | ||
4041 | + struct rpc_rqst *req = task->tk_rqstp; | ||
4042 | + | ||
4043 | + INIT_LIST_HEAD(&req->rq_list); | ||
4044 | + req->rq_timeout = task->tk_client->cl_timeout->to_initval; | ||
4045 | + req->rq_task = task; | ||
4046 | + req->rq_xprt = xprt; | ||
4047 | + req->rq_buffer = NULL; | ||
4048 | + req->rq_xid = xprt_alloc_xid(xprt); | ||
4049 | + req->rq_connect_cookie = xprt->connect_cookie - 1; | ||
4050 | + req->rq_bytes_sent = 0; | ||
4051 | + req->rq_snd_buf.len = 0; | ||
4052 | + req->rq_snd_buf.buflen = 0; | ||
4053 | + req->rq_rcv_buf.len = 0; | ||
4054 | + req->rq_rcv_buf.buflen = 0; | ||
4055 | + req->rq_release_snd_buf = NULL; | ||
4056 | + xprt_reset_majortimeo(req); | ||
4057 | + dprintk("RPC: %5u reserved req %p xid %08x\n", task->tk_pid, | ||
4058 | + req, ntohl(req->rq_xid)); | ||
4059 | +} | ||
4060 | + | ||
4061 | +static void | ||
4062 | +xprt_do_reserve(struct rpc_xprt *xprt, struct rpc_task *task) | ||
4063 | +{ | ||
4064 | + xprt->ops->alloc_slot(xprt, task); | ||
4065 | + if (task->tk_rqstp != NULL) | ||
4066 | + xprt_request_init(task); | ||
4067 | +} | ||
4068 | + | ||
4069 | /** | ||
4070 | * xprt_reserve - allocate an RPC request slot | ||
4071 | * @task: RPC task requesting a slot allocation | ||
4072 | @@ -1276,7 +1325,7 @@ void xprt_reserve(struct rpc_task *task) | ||
4073 | task->tk_timeout = 0; | ||
4074 | task->tk_status = -EAGAIN; | ||
4075 | if (!xprt_throttle_congested(xprt, task)) | ||
4076 | - xprt->ops->alloc_slot(xprt, task); | ||
4077 | + xprt_do_reserve(xprt, task); | ||
4078 | } | ||
4079 | |||
4080 | /** | ||
4081 | @@ -1298,45 +1347,7 @@ void xprt_retry_reserve(struct rpc_task *task) | ||
4082 | |||
4083 | task->tk_timeout = 0; | ||
4084 | task->tk_status = -EAGAIN; | ||
4085 | - xprt->ops->alloc_slot(xprt, task); | ||
4086 | -} | ||
4087 | - | ||
4088 | -static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) | ||
4089 | -{ | ||
4090 | - __be32 xid; | ||
4091 | - | ||
4092 | - spin_lock(&xprt->reserve_lock); | ||
4093 | - xid = (__force __be32)xprt->xid++; | ||
4094 | - spin_unlock(&xprt->reserve_lock); | ||
4095 | - return xid; | ||
4096 | -} | ||
4097 | - | ||
4098 | -static inline void xprt_init_xid(struct rpc_xprt *xprt) | ||
4099 | -{ | ||
4100 | - xprt->xid = prandom_u32(); | ||
4101 | -} | ||
4102 | - | ||
4103 | -void xprt_request_init(struct rpc_task *task) | ||
4104 | -{ | ||
4105 | - struct rpc_xprt *xprt = task->tk_xprt; | ||
4106 | - struct rpc_rqst *req = task->tk_rqstp; | ||
4107 | - | ||
4108 | - INIT_LIST_HEAD(&req->rq_list); | ||
4109 | - req->rq_timeout = task->tk_client->cl_timeout->to_initval; | ||
4110 | - req->rq_task = task; | ||
4111 | - req->rq_xprt = xprt; | ||
4112 | - req->rq_buffer = NULL; | ||
4113 | - req->rq_xid = xprt_alloc_xid(xprt); | ||
4114 | - req->rq_connect_cookie = xprt->connect_cookie - 1; | ||
4115 | - req->rq_bytes_sent = 0; | ||
4116 | - req->rq_snd_buf.len = 0; | ||
4117 | - req->rq_snd_buf.buflen = 0; | ||
4118 | - req->rq_rcv_buf.len = 0; | ||
4119 | - req->rq_rcv_buf.buflen = 0; | ||
4120 | - req->rq_release_snd_buf = NULL; | ||
4121 | - xprt_reset_majortimeo(req); | ||
4122 | - dprintk("RPC: %5u reserved req %p xid %08x\n", task->tk_pid, | ||
4123 | - req, ntohl(req->rq_xid)); | ||
4124 | + xprt_do_reserve(xprt, task); | ||
4125 | } | ||
4126 | |||
4127 | /** | ||
4128 | diff --git a/net/tipc/core.c b/net/tipc/core.c | ||
4129 | index 3ecca3b88bf8..eb0f701f9bf1 100644 | ||
4130 | --- a/net/tipc/core.c | ||
4131 | +++ b/net/tipc/core.c | ||
4132 | @@ -132,7 +132,7 @@ static int __init tipc_init(void) | ||
4133 | if (err) | ||
4134 | goto out_sysctl; | ||
4135 | |||
4136 | - err = register_pernet_subsys(&tipc_net_ops); | ||
4137 | + err = register_pernet_device(&tipc_net_ops); | ||
4138 | if (err) | ||
4139 | goto out_pernet; | ||
4140 | |||
4141 | @@ -140,7 +140,7 @@ static int __init tipc_init(void) | ||
4142 | if (err) | ||
4143 | goto out_socket; | ||
4144 | |||
4145 | - err = register_pernet_subsys(&tipc_topsrv_net_ops); | ||
4146 | + err = register_pernet_device(&tipc_topsrv_net_ops); | ||
4147 | if (err) | ||
4148 | goto out_pernet_topsrv; | ||
4149 | |||
4150 | @@ -151,11 +151,11 @@ static int __init tipc_init(void) | ||
4151 | pr_info("Started in single node mode\n"); | ||
4152 | return 0; | ||
4153 | out_bearer: | ||
4154 | - unregister_pernet_subsys(&tipc_topsrv_net_ops); | ||
4155 | + unregister_pernet_device(&tipc_topsrv_net_ops); | ||
4156 | out_pernet_topsrv: | ||
4157 | tipc_socket_stop(); | ||
4158 | out_socket: | ||
4159 | - unregister_pernet_subsys(&tipc_net_ops); | ||
4160 | + unregister_pernet_device(&tipc_net_ops); | ||
4161 | out_pernet: | ||
4162 | tipc_unregister_sysctl(); | ||
4163 | out_sysctl: | ||
4164 | @@ -170,9 +170,9 @@ out_netlink: | ||
4165 | static void __exit tipc_exit(void) | ||
4166 | { | ||
4167 | tipc_bearer_cleanup(); | ||
4168 | - unregister_pernet_subsys(&tipc_topsrv_net_ops); | ||
4169 | + unregister_pernet_device(&tipc_topsrv_net_ops); | ||
4170 | tipc_socket_stop(); | ||
4171 | - unregister_pernet_subsys(&tipc_net_ops); | ||
4172 | + unregister_pernet_device(&tipc_net_ops); | ||
4173 | tipc_netlink_stop(); | ||
4174 | tipc_netlink_compat_stop(); | ||
4175 | tipc_unregister_sysctl(); | ||
4176 | diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c | ||
4177 | index 588d5aa14c41..85ebb675600c 100644 | ||
4178 | --- a/net/tipc/netlink_compat.c | ||
4179 | +++ b/net/tipc/netlink_compat.c | ||
4180 | @@ -445,7 +445,11 @@ static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd, | ||
4181 | if (!bearer) | ||
4182 | return -EMSGSIZE; | ||
4183 | |||
4184 | - len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME); | ||
4185 | + len = TLV_GET_DATA_LEN(msg->req); | ||
4186 | + if (len <= 0) | ||
4187 | + return -EINVAL; | ||
4188 | + | ||
4189 | + len = min_t(int, len, TIPC_MAX_BEARER_NAME); | ||
4190 | if (!string_is_valid(name, len)) | ||
4191 | return -EINVAL; | ||
4192 | |||
4193 | @@ -537,7 +541,11 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, | ||
4194 | |||
4195 | name = (char *)TLV_DATA(msg->req); | ||
4196 | |||
4197 | - len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME); | ||
4198 | + len = TLV_GET_DATA_LEN(msg->req); | ||
4199 | + if (len <= 0) | ||
4200 | + return -EINVAL; | ||
4201 | + | ||
4202 | + len = min_t(int, len, TIPC_MAX_BEARER_NAME); | ||
4203 | if (!string_is_valid(name, len)) | ||
4204 | return -EINVAL; | ||
4205 | |||
4206 | @@ -815,7 +823,11 @@ static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd, | ||
4207 | if (!link) | ||
4208 | return -EMSGSIZE; | ||
4209 | |||
4210 | - len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME); | ||
4211 | + len = TLV_GET_DATA_LEN(msg->req); | ||
4212 | + if (len <= 0) | ||
4213 | + return -EINVAL; | ||
4214 | + | ||
4215 | + len = min_t(int, len, TIPC_MAX_BEARER_NAME); | ||
4216 | if (!string_is_valid(name, len)) | ||
4217 | return -EINVAL; | ||
4218 | |||
4219 | diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c | ||
4220 | index da2d311476ab..382c84d9339d 100644 | ||
4221 | --- a/net/tipc/udp_media.c | ||
4222 | +++ b/net/tipc/udp_media.c | ||
4223 | @@ -176,7 +176,6 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, | ||
4224 | goto tx_error; | ||
4225 | } | ||
4226 | |||
4227 | - skb->dev = rt->dst.dev; | ||
4228 | ttl = ip4_dst_hoplimit(&rt->dst); | ||
4229 | udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr, | ||
4230 | dst->ipv4.s_addr, 0, ttl, 0, src->port, | ||
4231 | @@ -195,10 +194,9 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, | ||
4232 | if (err) | ||
4233 | goto tx_error; | ||
4234 | ttl = ip6_dst_hoplimit(ndst); | ||
4235 | - err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, | ||
4236 | - ndst->dev, &src->ipv6, | ||
4237 | - &dst->ipv6, 0, ttl, 0, src->port, | ||
4238 | - dst->port, false); | ||
4239 | + err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL, | ||
4240 | + &src->ipv6, &dst->ipv6, 0, ttl, 0, | ||
4241 | + src->port, dst->port, false); | ||
4242 | #endif | ||
4243 | } | ||
4244 | return err; | ||
4245 | diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c | ||
4246 | index 1c41b4eaf73c..3d29d0524a89 100644 | ||
4247 | --- a/tools/perf/builtin-help.c | ||
4248 | +++ b/tools/perf/builtin-help.c | ||
4249 | @@ -189,7 +189,7 @@ static void add_man_viewer(const char *name) | ||
4250 | while (*p) | ||
4251 | p = &((*p)->next); | ||
4252 | *p = zalloc(sizeof(**p) + len + 1); | ||
4253 | - strncpy((*p)->name, name, len); | ||
4254 | + strcpy((*p)->name, name); | ||
4255 | } | ||
4256 | |||
4257 | static int supported_man_viewer(const char *name, size_t len) | ||
4258 | diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c | ||
4259 | index 4ca799aadb4e..93d6b7240285 100644 | ||
4260 | --- a/tools/perf/ui/tui/helpline.c | ||
4261 | +++ b/tools/perf/ui/tui/helpline.c | ||
4262 | @@ -24,7 +24,7 @@ static void tui_helpline__push(const char *msg) | ||
4263 | SLsmg_set_color(0); | ||
4264 | SLsmg_write_nstring((char *)msg, SLtt_Screen_Cols); | ||
4265 | SLsmg_refresh(); | ||
4266 | - strncpy(ui_helpline__current, msg, sz)[sz - 1] = '\0'; | ||
4267 | + strlcpy(ui_helpline__current, msg, sz); | ||
4268 | } | ||
4269 | |||
4270 | static int tui_helpline__show(const char *format, va_list ap) | ||
4271 | diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c | ||
4272 | index bd9226bc5945..b9a82598e2ac 100644 | ||
4273 | --- a/tools/perf/util/header.c | ||
4274 | +++ b/tools/perf/util/header.c | ||
4275 | @@ -3562,7 +3562,7 @@ perf_event__synthesize_event_update_name(struct perf_tool *tool, | ||
4276 | if (ev == NULL) | ||
4277 | return -ENOMEM; | ||
4278 | |||
4279 | - strncpy(ev->data, evsel->name, len); | ||
4280 | + strlcpy(ev->data, evsel->name, len + 1); | ||
4281 | err = process(tool, (union perf_event*) ev, NULL, NULL); | ||
4282 | free(ev); | ||
4283 | return err; | ||
4284 | diff --git a/tools/testing/selftests/bpf/test_lpm_map.c b/tools/testing/selftests/bpf/test_lpm_map.c | ||
4285 | index 02d7c871862a..006be3963977 100644 | ||
4286 | --- a/tools/testing/selftests/bpf/test_lpm_map.c | ||
4287 | +++ b/tools/testing/selftests/bpf/test_lpm_map.c | ||
4288 | @@ -573,13 +573,13 @@ static void test_lpm_get_next_key(void) | ||
4289 | |||
4290 | /* add one more element (total two) */ | ||
4291 | key_p->prefixlen = 24; | ||
4292 | - inet_pton(AF_INET, "192.168.0.0", key_p->data); | ||
4293 | + inet_pton(AF_INET, "192.168.128.0", key_p->data); | ||
4294 | assert(bpf_map_update_elem(map_fd, key_p, &value, 0) == 0); | ||
4295 | |||
4296 | memset(key_p, 0, key_size); | ||
4297 | assert(bpf_map_get_next_key(map_fd, NULL, key_p) == 0); | ||
4298 | assert(key_p->prefixlen == 24 && key_p->data[0] == 192 && | ||
4299 | - key_p->data[1] == 168 && key_p->data[2] == 0); | ||
4300 | + key_p->data[1] == 168 && key_p->data[2] == 128); | ||
4301 | |||
4302 | memset(next_key_p, 0, key_size); | ||
4303 | assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0); | ||
4304 | @@ -592,7 +592,7 @@ static void test_lpm_get_next_key(void) | ||
4305 | |||
4306 | /* Add one more element (total three) */ | ||
4307 | key_p->prefixlen = 24; | ||
4308 | - inet_pton(AF_INET, "192.168.128.0", key_p->data); | ||
4309 | + inet_pton(AF_INET, "192.168.0.0", key_p->data); | ||
4310 | assert(bpf_map_update_elem(map_fd, key_p, &value, 0) == 0); | ||
4311 | |||
4312 | memset(key_p, 0, key_size); | ||
4313 | @@ -643,6 +643,41 @@ static void test_lpm_get_next_key(void) | ||
4314 | assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == -1 && | ||
4315 | errno == ENOENT); | ||
4316 | |||
4317 | + /* Add one more element (total five) */ | ||
4318 | + key_p->prefixlen = 28; | ||
4319 | + inet_pton(AF_INET, "192.168.1.128", key_p->data); | ||
4320 | + assert(bpf_map_update_elem(map_fd, key_p, &value, 0) == 0); | ||
4321 | + | ||
4322 | + memset(key_p, 0, key_size); | ||
4323 | + assert(bpf_map_get_next_key(map_fd, NULL, key_p) == 0); | ||
4324 | + assert(key_p->prefixlen == 24 && key_p->data[0] == 192 && | ||
4325 | + key_p->data[1] == 168 && key_p->data[2] == 0); | ||
4326 | + | ||
4327 | + memset(next_key_p, 0, key_size); | ||
4328 | + assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0); | ||
4329 | + assert(next_key_p->prefixlen == 28 && next_key_p->data[0] == 192 && | ||
4330 | + next_key_p->data[1] == 168 && next_key_p->data[2] == 1 && | ||
4331 | + next_key_p->data[3] == 128); | ||
4332 | + | ||
4333 | + memcpy(key_p, next_key_p, key_size); | ||
4334 | + assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0); | ||
4335 | + assert(next_key_p->prefixlen == 24 && next_key_p->data[0] == 192 && | ||
4336 | + next_key_p->data[1] == 168 && next_key_p->data[2] == 1); | ||
4337 | + | ||
4338 | + memcpy(key_p, next_key_p, key_size); | ||
4339 | + assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0); | ||
4340 | + assert(next_key_p->prefixlen == 24 && next_key_p->data[0] == 192 && | ||
4341 | + next_key_p->data[1] == 168 && next_key_p->data[2] == 128); | ||
4342 | + | ||
4343 | + memcpy(key_p, next_key_p, key_size); | ||
4344 | + assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0); | ||
4345 | + assert(next_key_p->prefixlen == 16 && next_key_p->data[0] == 192 && | ||
4346 | + next_key_p->data[1] == 168); | ||
4347 | + | ||
4348 | + memcpy(key_p, next_key_p, key_size); | ||
4349 | + assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == -1 && | ||
4350 | + errno == ENOENT); | ||
4351 | + | ||
4352 | /* no exact matching key should return the first one in post order */ | ||
4353 | key_p->prefixlen = 22; | ||
4354 | inet_pton(AF_INET, "192.168.1.0", key_p->data); |