Contents of /trunk/kernel-alx/patches-4.19/0156-4.19.57-all-fixes.patch
Parent Directory | Revision Log
Revision 3435 -
(show 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 | 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); |