tools/testing/selftests/net/mptcp/mptcp_join.sh 34aa6e3bccd8 ("selftests: mptcp: add ip mptcp wrappers") 857898eb4b28 ("selftests: mptcp: add missing join check") 6ef84b1517e0 ("selftests: mptcp: more robust signal race test") https://lore.kernel.org/all/20220221131842.468893-1-broonie@kernel.org/ drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.h drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/ct.c fb7e76ea3f3b6 ("net/mlx5e: TC, Skip redundant ct clear actions") c63741b426e11 ("net/mlx5e: Fix MPLSoUDP encap to use MPLS action information") 09bf97923224f ("net/mlx5e: TC, Move pedit_headers_action to parse_attr") 84ba8062e383 ("net/mlx5e: Test CT and SAMPLE on flow attr") efe6f961cd2e ("net/mlx5e: CT, Don't set flow flag CT for ct clear flow") 3b49a7edec1d ("net/mlx5e: TC, Reject rules with multiple CT actions")
Unified · Split
| @@ -468,6 +468,7 @@ Description: · 467 unmodified lines | ||
| 468 | 468 | auto: Charge normally, respect thresholds |
| 469 | 469 | inhibit-charge: Do not charge while AC is attached |
| 470 | 470 | force-discharge: Force discharge while AC is attached |
| 471 | + ================ ==================================== | |
| 471 | 472 | |
| 472 | 473 | What: /sys/class/power_supply/<supply_name>/technology |
| 473 | 474 | Date: May 2007 |
| @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: SiFive GPIO controller |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Yash Shah <yash.shah@sifive.com> | |
| 11 | 10 | - Paul Walmsley <paul.walmsley@sifive.com> |
| 12 | 11 | |
| 13 | 12 | properties: |
| @@ -20,7 +20,7 @@ description: | · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | maintainers: |
| 22 | 22 | - Kishon Vijay Abraham I <kishon@ti.com> |
| 23 | − - Roger Quadros <rogerq@ti.com | |
| 23 | + - Roger Quadros <rogerq@kernel.org> | |
| 24 | 24 | |
| 25 | 25 | properties: |
| 26 | 26 | compatible: |
| @@ -8,7 +8,7 @@ title: OMAP USB2 PHY · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | 10 | - Kishon Vijay Abraham I <kishon@ti.com> |
| 11 | − - Roger Quadros <rogerq@ti.com> | |
| 11 | + - Roger Quadros <rogerq@kernel.org> | |
| 12 | 12 | |
| 13 | 13 | properties: |
| 14 | 14 | compatible: |
| @@ -8,7 +8,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 7 unmodified lines | ||
| 8 | 8 | title: SiFive PWM controller |
| 9 | 9 | |
| 10 | 10 | maintainers: |
| 11 | − - Yash Shah <yash.shah@sifive.com> | |
| 12 | 11 | - Sagar Kadam <sagar.kadam@sifive.com> |
| 13 | 12 | - Paul Walmsley <paul.walmsley@sifive.com> |
| 14 | 13 | |
| @@ -9,7 +9,6 @@ title: SiFive L2 Cache Controller · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | maintainers: |
| 11 | 11 | - Sagar Kadam <sagar.kadam@sifive.com> |
| 12 | − - Yash Shah <yash.shah@sifive.com> | |
| 13 | 12 | - Paul Walmsley <paul.walmsley@sifive.com> |
| 14 | 13 | |
| 15 | 14 | description: |
| @@ -8,6 +8,7 @@ title: Audio codec controlled by ChromeOS EC · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | 10 | - Cheng-Yi Chiang <cychiang@chromium.org> |
| 11 | + - Tzung-Bi Shih <tzungbi@google.com> | |
| 11 | 12 | |
| 12 | 13 | description: | |
| 13 | 14 | Google's ChromeOS EC codec is a digital mic codec provided by the |
| @@ -7,7 +7,7 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#" · 6 unmodified lines | ||
| 7 | 7 | title: Bindings for the TI wrapper module for the Cadence USBSS-DRD controller |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Roger Quadros <rogerq@ti.com> | |
| 10 | + - Roger Quadros <rogerq@kernel.org> | |
| 11 | 11 | |
| 12 | 12 | properties: |
| 13 | 13 | compatible: |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: TI Keystone Soc USB Controller |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Roger Quadros <rogerq@ti.com> | |
| 10 | + - Roger Quadros <rogerq@kernel.org> | |
| 11 | 11 | |
| 12 | 12 | properties: |
| 13 | 13 | compatible: |
| @@ -4549,6 +4549,7 @@ F: drivers/platform/chrome/ · 4548 unmodified lines | ||
| 4549 | 4549 | |
| 4550 | 4550 | CHROMEOS EC CODEC DRIVER |
| 4551 | 4551 | M: Cheng-Yi Chiang <cychiang@chromium.org> |
| 4552 | +M: Tzung-Bi Shih <tzungbi@google.com> | |
| 4552 | 4553 | R: Guenter Roeck <groeck@chromium.org> |
| 4553 | 4554 | S: Maintained |
| 4554 | 4555 | F: Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml |
| @@ -7012,12 +7013,6 @@ L: linux-edac@vger.kernel.org · 2457 unmodified lines | ||
| 7012 | 7013 | S: Maintained |
| 7013 | 7014 | F: drivers/edac/sb_edac.c |
| 7014 | 7015 | |
| 7015 | −EDAC-SIFIVE | |
| 7016 | −M: Yash Shah <yash.shah@sifive.com> | |
| 7017 | −L: linux-edac@vger.kernel.org | |
| 7018 | −S: Supported | |
| 7019 | −F: drivers/edac/sifive_edac.c | |
| 7020 | − | |
| 7021 | 7016 | EDAC-SKYLAKE |
| 7022 | 7017 | M: Tony Luck <tony.luck@intel.com> |
| 7023 | 7018 | L: linux-edac@vger.kernel.org |
| @@ -9264,6 +9259,15 @@ S: Maintained · 2240 unmodified lines | ||
| 9264 | 9259 | W: https://github.com/o2genum/ideapad-slidebar |
| 9265 | 9260 | F: drivers/input/misc/ideapad_slidebar.c |
| 9266 | 9261 | |
| 9262 | +IDMAPPED MOUNTS | |
| 9263 | +M: Christian Brauner <brauner@kernel.org> | |
| 9264 | +L: linux-fsdevel@vger.kernel.org | |
| 9265 | +S: Maintained | |
| 9266 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux.git | |
| 9267 | +F: Documentation/filesystems/idmappings.rst | |
| 9268 | +F: tools/testing/selftests/mount_setattr/ | |
| 9269 | +F: include/linux/mnt_idmapping.h | |
| 9270 | + | |
| 9267 | 9271 | IDT VersaClock 5 CLOCK DRIVER |
| 9268 | 9272 | M: Luca Ceresoli <luca@lucaceresoli.net> |
| 9269 | 9273 | S: Maintained |
| @@ -16000,14 +16004,6 @@ F: Documentation/devicetree/bindings/misc/qcom,fastrpc.txt · 6730 unmodified lines | ||
| 16000 | 16004 | F: drivers/misc/fastrpc.c |
| 16001 | 16005 | F: include/uapi/misc/fastrpc.h |
| 16002 | 16006 | |
| 16003 | −QUALCOMM GENERIC INTERFACE I2C DRIVER | |
| 16004 | −M: Akash Asthana <akashast@codeaurora.org> | |
| 16005 | −M: Mukesh Savaliya <msavaliy@codeaurora.org> | |
| 16006 | −L: linux-i2c@vger.kernel.org | |
| 16007 | −L: linux-arm-msm@vger.kernel.org | |
| 16008 | −S: Supported | |
| 16009 | −F: drivers/i2c/busses/i2c-qcom-geni.c | |
| 16010 | − | |
| 16011 | 16007 | QUALCOMM HEXAGON ARCHITECTURE |
| 16012 | 16008 | M: Brian Cain <bcain@codeaurora.org> |
| 16013 | 16009 | L: linux-hexagon@vger.kernel.org |
| @@ -16079,8 +16075,8 @@ F: Documentation/devicetree/bindings/mtd/qcom,nandc.yaml · 65 unmodified lines | ||
| 16079 | 16075 | F: drivers/mtd/nand/raw/qcom_nandc.c |
| 16080 | 16076 | |
| 16081 | 16077 | QUALCOMM RMNET DRIVER |
| 16082 | −M: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> | |
| 16083 | −M: Sean Tranchetti <stranche@codeaurora.org> | |
| 16078 | +M: Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com> | |
| 16079 | +M: Sean Tranchetti <quic_stranche@quicinc.com> | |
| 16084 | 16080 | L: netdev@vger.kernel.org |
| 16085 | 16081 | S: Maintained |
| 16086 | 16082 | F: Documentation/networking/device_drivers/cellular/qualcomm/rmnet.rst |
| @@ -16372,6 +16368,7 @@ F: drivers/watchdog/realtek_otto_wdt.c · 285 unmodified lines | ||
| 16372 | 16368 | |
| 16373 | 16369 | REALTEK RTL83xx SMI DSA ROUTER CHIPS |
| 16374 | 16370 | M: Linus Walleij <linus.walleij@linaro.org> |
| 16371 | +M: Alvin Šipraga <alsi@bang-olufsen.dk> | |
| 16375 | 16372 | S: Maintained |
| 16376 | 16373 | F: Documentation/devicetree/bindings/net/dsa/realtek-smi.txt |
| 16377 | 16374 | F: drivers/net/dsa/realtek/* |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 17 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc4 | |
| 5 | +EXTRAVERSION = -rc5 | |
| 6 | 6 | NAME = Superb Owl |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -106,7 +106,7 @@ · 105 unmodified lines | ||
| 106 | 106 | msr_s SYS_ICC_SRE_EL2, x0 |
| 107 | 107 | isb // Make sure SRE is now set |
| 108 | 108 | mrs_s x0, SYS_ICC_SRE_EL2 // Read SRE back, |
| 109 | − tbz x0, #0, 1f // and check that it sticks | |
| 109 | + tbz x0, #0, .Lskip_gicv3_\@ // and check that it sticks | |
| 110 | 110 | msr_s SYS_ICH_HCR_EL2, xzr // Reset ICC_HCR_EL2 to defaults |
| 111 | 111 | .Lskip_gicv3_\@: |
| 112 | 112 | .endm |
| @@ -340,7 +340,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop) · 339 unmodified lines | ||
| 340 | 340 | : "r" (val), "r" (regs->ior), "r" (regs->isr) |
| 341 | 341 | : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); |
| 342 | 342 | |
| 343 | − return 0; | |
| 343 | + return ret; | |
| 344 | 344 | } |
| 345 | 345 | static int emulate_std(struct pt_regs *regs, int frreg, int flop) |
| 346 | 346 | { |
| @@ -397,7 +397,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) · 50 unmodified lines | ||
| 397 | 397 | __asm__ __volatile__ ( |
| 398 | 398 | " mtsp %4, %%sr1\n" |
| 399 | 399 | " zdep %2, 29, 2, %%r19\n" |
| 400 | −" dep %%r0, 31, 2, %2\n" | |
| 400 | +" dep %%r0, 31, 2, %3\n" | |
| 401 | 401 | " mtsar %%r19\n" |
| 402 | 402 | " zvdepi -2, 32, %%r19\n" |
| 403 | 403 | "1: ldw 0(%%sr1,%3),%%r20\n" |
| @@ -409,7 +409,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) · 5 unmodified lines | ||
| 409 | 409 | " andcm %%r21, %%r19, %%r21\n" |
| 410 | 410 | " or %1, %%r20, %1\n" |
| 411 | 411 | " or %2, %%r21, %2\n" |
| 412 | −"3: stw %1,0(%%sr1,%1)\n" | |
| 412 | +"3: stw %1,0(%%sr1,%3)\n" | |
| 413 | 413 | "4: stw %%r1,4(%%sr1,%3)\n" |
| 414 | 414 | "5: stw %2,8(%%sr1,%3)\n" |
| 415 | 415 | " copy %%r0, %0\n" |
| @@ -596,7 +596,6 @@ void handle_unaligned(struct pt_regs *regs) · 180 unmodified lines | ||
| 596 | 596 | ret = ERR_NOTHANDLED; /* "undefined", but lets kill them. */ |
| 597 | 597 | break; |
| 598 | 598 | } |
| 599 | −#ifdef CONFIG_PA20 | |
| 600 | 599 | switch (regs->iir & OPCODE2_MASK) |
| 601 | 600 | { |
| 602 | 601 | case OPCODE_FLDD_L: |
| @@ -607,22 +606,23 @@ void handle_unaligned(struct pt_regs *regs) · 4 unmodified lines | ||
| 607 | 606 | flop=1; |
| 608 | 607 | ret = emulate_std(regs, R2(regs->iir),1); |
| 609 | 608 | break; |
| 609 | +#ifdef CONFIG_PA20 | |
| 610 | 610 | case OPCODE_LDD_L: |
| 611 | 611 | ret = emulate_ldd(regs, R2(regs->iir),0); |
| 612 | 612 | break; |
| 613 | 613 | case OPCODE_STD_L: |
| 614 | 614 | ret = emulate_std(regs, R2(regs->iir),0); |
| 615 | 615 | break; |
| 616 | − } | |
| 617 | 616 | #endif |
| 617 | + } | |
| 618 | 618 | switch (regs->iir & OPCODE3_MASK) |
| 619 | 619 | { |
| 620 | 620 | case OPCODE_FLDW_L: |
| 621 | 621 | flop=1; |
| 622 | − ret = emulate_ldw(regs, R2(regs->iir),0); | |
| 622 | + ret = emulate_ldw(regs, R2(regs->iir), 1); | |
| 623 | 623 | break; |
| 624 | 624 | case OPCODE_LDW_M: |
| 625 | − ret = emulate_ldw(regs, R2(regs->iir),1); | |
| 625 | + ret = emulate_ldw(regs, R2(regs->iir), 0); | |
| 626 | 626 | break; |
| 627 | 627 | |
| 628 | 628 | case OPCODE_FSTW_L: |
| @@ -421,14 +421,14 @@ InstructionTLBMiss: · 420 unmodified lines | ||
| 421 | 421 | */ |
| 422 | 422 | /* Get PTE (linux-style) and check access */ |
| 423 | 423 | mfspr r3,SPRN_IMISS |
| 424 | −#ifdef CONFIG_MODULES | |
| 424 | +#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE) | |
| 425 | 425 | lis r1, TASK_SIZE@h /* check if kernel address */ |
| 426 | 426 | cmplw 0,r1,r3 |
| 427 | 427 | #endif |
| 428 | 428 | mfspr r2, SPRN_SDR1 |
| 429 | 429 | li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER |
| 430 | 430 | rlwinm r2, r2, 28, 0xfffff000 |
| 431 | −#ifdef CONFIG_MODULES | |
| 431 | +#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE) | |
| 432 | 432 | bgt- 112f |
| 433 | 433 | lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ |
| 434 | 434 | li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC |
| @@ -3264,12 +3264,14 @@ void emulate_update_regs(struct pt_regs *regs, struct instruction_op *op) · 3263 unmodified lines | ||
| 3264 | 3264 | case BARRIER_EIEIO: |
| 3265 | 3265 | eieio(); |
| 3266 | 3266 | break; |
| 3267 | +#ifdef CONFIG_PPC64 | |
| 3267 | 3268 | case BARRIER_LWSYNC: |
| 3268 | 3269 | asm volatile("lwsync" : : : "memory"); |
| 3269 | 3270 | break; |
| 3270 | 3271 | case BARRIER_PTESYNC: |
| 3271 | 3272 | asm volatile("ptesync" : : : "memory"); |
| 3272 | 3273 | break; |
| 3274 | +#endif | |
| 3273 | 3275 | } |
| 3274 | 3276 | break; |
| 3275 | 3277 | |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * Copyright (c) 2020 Western Digital Corporation or its affiliates. |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | +#include <linux/bits.h> | |
| 8 | 9 | #include <linux/init.h> |
| 9 | 10 | #include <linux/pm.h> |
| 10 | 11 | #include <linux/reboot.h> |
| @@ -85,7 +86,7 @@ static unsigned long __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mas · 74 unmodified lines | ||
| 85 | 86 | pr_warn("Unable to send any request to hartid > BITS_PER_LONG for SBI v0.1\n"); |
| 86 | 87 | break; |
| 87 | 88 | } |
| 88 | − hmask |= 1 << hartid; | |
| 89 | + hmask |= BIT(hartid); | |
| 89 | 90 | } |
| 90 | 91 | |
| 91 | 92 | return hmask; |
| @@ -160,7 +161,7 @@ static int __sbi_send_ipi_v01(const struct cpumask *cpu_mask) · 68 unmodified lines | ||
| 160 | 161 | { |
| 161 | 162 | unsigned long hart_mask; |
| 162 | 163 | |
| 163 | − if (!cpu_mask) | |
| 164 | + if (!cpu_mask || cpumask_empty(cpu_mask)) | |
| 164 | 165 | cpu_mask = cpu_online_mask; |
| 165 | 166 | hart_mask = __sbi_v01_cpumask_to_hartmask(cpu_mask); |
| 166 | 167 | |
| @@ -176,7 +177,7 @@ static int __sbi_rfence_v01(int fid, const struct cpumask *cpu_mask, · 9 unmodified lines | ||
| 176 | 177 | int result = 0; |
| 177 | 178 | unsigned long hart_mask; |
| 178 | 179 | |
| 179 | − if (!cpu_mask) | |
| 180 | + if (!cpu_mask || cpumask_empty(cpu_mask)) | |
| 180 | 181 | cpu_mask = cpu_online_mask; |
| 181 | 182 | hart_mask = __sbi_v01_cpumask_to_hartmask(cpu_mask); |
| 182 | 183 | |
| @@ -249,26 +250,37 @@ static void __sbi_set_timer_v02(uint64_t stime_value) · 66 unmodified lines | ||
| 249 | 250 | |
| 250 | 251 | static int __sbi_send_ipi_v02(const struct cpumask *cpu_mask) |
| 251 | 252 | { |
| 252 | − unsigned long hartid, cpuid, hmask = 0, hbase = 0; | |
| 253 | + unsigned long hartid, cpuid, hmask = 0, hbase = 0, htop = 0; | |
| 253 | 254 | struct sbiret ret = {0}; |
| 254 | 255 | int result; |
| 255 | 256 | |
| 256 | − if (!cpu_mask) | |
| 257 | + if (!cpu_mask || cpumask_empty(cpu_mask)) | |
| 257 | 258 | cpu_mask = cpu_online_mask; |
| 258 | 259 | |
| 259 | 260 | for_each_cpu(cpuid, cpu_mask) { |
| 260 | 261 | hartid = cpuid_to_hartid_map(cpuid); |
| 261 | − if (hmask && ((hbase + BITS_PER_LONG) <= hartid)) { | |
| 262 | − ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, | |
| 263 | − hmask, hbase, 0, 0, 0, 0); | |
| 264 | − if (ret.error) | |
| 265 | − goto ecall_failed; | |
| 266 | − hmask = 0; | |
| 267 | − hbase = 0; | |
| 262 | + if (hmask) { | |
| 263 | + if (hartid + BITS_PER_LONG <= htop || | |
| 264 | + hbase + BITS_PER_LONG <= hartid) { | |
| 265 | + ret = sbi_ecall(SBI_EXT_IPI, | |
| 266 | + SBI_EXT_IPI_SEND_IPI, hmask, | |
| 267 | + hbase, 0, 0, 0, 0); | |
| 268 | + if (ret.error) | |
| 269 | + goto ecall_failed; | |
| 270 | + hmask = 0; | |
| 271 | + } else if (hartid < hbase) { | |
| 272 | + /* shift the mask to fit lower hartid */ | |
| 273 | + hmask <<= hbase - hartid; | |
| 274 | + hbase = hartid; | |
| 275 | + } | |
| 268 | 276 | } |
| 269 | − if (!hmask) | |
| 277 | + if (!hmask) { | |
| 270 | 278 | hbase = hartid; |
| 271 | − hmask |= 1UL << (hartid - hbase); | |
| 279 | + htop = hartid; | |
| 280 | + } else if (hartid > htop) { | |
| 281 | + htop = hartid; | |
| 282 | + } | |
| 283 | + hmask |= BIT(hartid - hbase); | |
| 272 | 284 | } |
| 273 | 285 | |
| 274 | 286 | if (hmask) { |
| @@ -344,25 +356,35 @@ static int __sbi_rfence_v02(int fid, const struct cpumask *cpu_mask, · 69 unmodified lines | ||
| 344 | 356 | unsigned long start, unsigned long size, |
| 345 | 357 | unsigned long arg4, unsigned long arg5) |
| 346 | 358 | { |
| 347 | − unsigned long hartid, cpuid, hmask = 0, hbase = 0; | |
| 359 | + unsigned long hartid, cpuid, hmask = 0, hbase = 0, htop = 0; | |
| 348 | 360 | int result; |
| 349 | 361 | |
| 350 | − if (!cpu_mask) | |
| 362 | + if (!cpu_mask || cpumask_empty(cpu_mask)) | |
| 351 | 363 | cpu_mask = cpu_online_mask; |
| 352 | 364 | |
| 353 | 365 | for_each_cpu(cpuid, cpu_mask) { |
| 354 | 366 | hartid = cpuid_to_hartid_map(cpuid); |
| 355 | − if (hmask && ((hbase + BITS_PER_LONG) <= hartid)) { | |
| 356 | − result = __sbi_rfence_v02_call(fid, hmask, hbase, | |
| 357 | − start, size, arg4, arg5); | |
| 358 | − if (result) | |
| 359 | − return result; | |
| 360 | − hmask = 0; | |
| 361 | − hbase = 0; | |
| 367 | + if (hmask) { | |
| 368 | + if (hartid + BITS_PER_LONG <= htop || | |
| 369 | + hbase + BITS_PER_LONG <= hartid) { | |
| 370 | + result = __sbi_rfence_v02_call(fid, hmask, | |
| 371 | + hbase, start, size, arg4, arg5); | |
| 372 | + if (result) | |
| 373 | + return result; | |
| 374 | + hmask = 0; | |
| 375 | + } else if (hartid < hbase) { | |
| 376 | + /* shift the mask to fit lower hartid */ | |
| 377 | + hmask <<= hbase - hartid; | |
| 378 | + hbase = hartid; | |
| 379 | + } | |
| 362 | 380 | } |
| 363 | − if (!hmask) | |
| 381 | + if (!hmask) { | |
| 364 | 382 | hbase = hartid; |
| 365 | − hmask |= 1UL << (hartid - hbase); | |
| 383 | + htop = hartid; | |
| 384 | + } else if (hartid > htop) { | |
| 385 | + htop = hartid; | |
| 386 | + } | |
| 387 | + hmask |= BIT(hartid - hbase); | |
| 366 | 388 | } |
| 367 | 389 | |
| 368 | 390 | if (hmask) { |
| @@ -344,10 +344,8 @@ static void sgx_reclaim_pages(void) · 343 unmodified lines | ||
| 344 | 344 | { |
| 345 | 345 | struct sgx_epc_page *chunk[SGX_NR_TO_SCAN]; |
| 346 | 346 | struct sgx_backing backing[SGX_NR_TO_SCAN]; |
| 347 | − struct sgx_epc_section *section; | |
| 348 | 347 | struct sgx_encl_page *encl_page; |
| 349 | 348 | struct sgx_epc_page *epc_page; |
| 350 | − struct sgx_numa_node *node; | |
| 351 | 349 | pgoff_t page_index; |
| 352 | 350 | int cnt = 0; |
| 353 | 351 | int ret; |
| @@ -418,13 +416,7 @@ skip: · 64 unmodified lines | ||
| 418 | 416 | kref_put(&encl_page->encl->refcount, sgx_encl_release); |
| 419 | 417 | epc_page->flags &= ~SGX_EPC_PAGE_RECLAIMER_TRACKED; |
| 420 | 418 | |
| 421 | − section = &sgx_epc_sections[epc_page->section]; | |
| 422 | − node = section->node; | |
| 423 | − | |
| 424 | − spin_lock(&node->lock); | |
| 425 | − list_add_tail(&epc_page->list, &node->free_page_list); | |
| 426 | − spin_unlock(&node->lock); | |
| 427 | − atomic_long_inc(&sgx_nr_free_pages); | |
| 419 | + sgx_free_epc_page(epc_page); | |
| 428 | 420 | } |
| 429 | 421 | } |
| 430 | 422 | |
| @@ -91,11 +91,9 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, · 90 unmodified lines | ||
| 91 | 91 | const void *kbuf, const void __user *ubuf) |
| 92 | 92 | { |
| 93 | 93 | struct fpu *fpu = &target->thread.fpu; |
| 94 | − struct user32_fxsr_struct newstate; | |
| 94 | + struct fxregs_state newstate; | |
| 95 | 95 | int ret; |
| 96 | 96 | |
| 97 | − BUILD_BUG_ON(sizeof(newstate) != sizeof(struct fxregs_state)); | |
| 98 | − | |
| 99 | 97 | if (!cpu_feature_enabled(X86_FEATURE_FXSR)) |
| 100 | 98 | return -ENODEV; |
| 101 | 99 | |
| @@ -116,9 +114,10 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, · 14 unmodified lines | ||
| 116 | 114 | /* Copy the state */ |
| 117 | 115 | memcpy(&fpu->fpstate->regs.fxsave, &newstate, sizeof(newstate)); |
| 118 | 116 | |
| 119 | − /* Clear xmm8..15 */ | |
| 117 | + /* Clear xmm8..15 for 32-bit callers */ | |
| 120 | 118 | BUILD_BUG_ON(sizeof(fpu->__fpstate.regs.fxsave.xmm_space) != 16 * 16); |
| 121 | − memset(&fpu->fpstate->regs.fxsave.xmm_space[8], 0, 8 * 16); | |
| 119 | + if (in_ia32_syscall()) | |
| 120 | + memset(&fpu->fpstate->regs.fxsave.xmm_space[8*4], 0, 8 * 16); | |
| 122 | 121 | |
| 123 | 122 | /* Mark FP and SSE as in use when XSAVE is enabled */ |
| 124 | 123 | if (use_xsave()) |
| @@ -1224,7 +1224,7 @@ static struct user_regset x86_64_regsets[] __ro_after_init = { · 1223 unmodified lines | ||
| 1224 | 1224 | }, |
| 1225 | 1225 | [REGSET_FP] = { |
| 1226 | 1226 | .core_note_type = NT_PRFPREG, |
| 1227 | − .n = sizeof(struct user_i387_struct) / sizeof(long), | |
| 1227 | + .n = sizeof(struct fxregs_state) / sizeof(long), | |
| 1228 | 1228 | .size = sizeof(long), .align = sizeof(long), |
| 1229 | 1229 | .active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set |
| 1230 | 1230 | }, |
| @@ -1271,7 +1271,7 @@ static struct user_regset x86_32_regsets[] __ro_after_init = { · 40 unmodified lines | ||
| 1271 | 1271 | }, |
| 1272 | 1272 | [REGSET_XFP] = { |
| 1273 | 1273 | .core_note_type = NT_PRXFPREG, |
| 1274 | − .n = sizeof(struct user32_fxsr_struct) / sizeof(u32), | |
| 1274 | + .n = sizeof(struct fxregs_state) / sizeof(u32), | |
| 1275 | 1275 | .size = sizeof(u32), .align = sizeof(u32), |
| 1276 | 1276 | .active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set |
| 1277 | 1277 | }, |
| @@ -7018,6 +7018,8 @@ static void bfq_exit_queue(struct elevator_queue *e) · 7017 unmodified lines | ||
| 7018 | 7018 | spin_unlock_irq(&bfqd->lock); |
| 7019 | 7019 | #endif |
| 7020 | 7020 | |
| 7021 | + wbt_enable_default(bfqd->queue); | |
| 7022 | + | |
| 7021 | 7023 | kfree(bfqd); |
| 7022 | 7024 | } |
| 7023 | 7025 | |
| @@ -284,13 +284,6 @@ void blk_queue_start_drain(struct request_queue *q) · 283 unmodified lines | ||
| 284 | 284 | wake_up_all(&q->mq_freeze_wq); |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | −void blk_set_queue_dying(struct request_queue *q) | |
| 288 | −{ | |
| 289 | − blk_queue_flag_set(QUEUE_FLAG_DYING, q); | |
| 290 | − blk_queue_start_drain(q); | |
| 291 | −} | |
| 292 | −EXPORT_SYMBOL_GPL(blk_set_queue_dying); | |
| 293 | − | |
| 294 | 287 | /** |
| 295 | 288 | * blk_cleanup_queue - shutdown a request queue |
| 296 | 289 | * @q: request queue to shutdown |
| @@ -308,7 +301,8 @@ void blk_cleanup_queue(struct request_queue *q) · 11 unmodified lines | ||
| 308 | 301 | WARN_ON_ONCE(blk_queue_registered(q)); |
| 309 | 302 | |
| 310 | 303 | /* mark @q DYING, no new request or merges will be allowed afterwards */ |
| 311 | − blk_set_queue_dying(q); | |
| 304 | + blk_queue_flag_set(QUEUE_FLAG_DYING, q); | |
| 305 | + blk_queue_start_drain(q); | |
| 312 | 306 | |
| 313 | 307 | blk_queue_flag_set(QUEUE_FLAG_NOMERGES, q); |
| 314 | 308 | blk_queue_flag_set(QUEUE_FLAG_NOXMERGES, q); |
| @@ -446,7 +446,7 @@ static struct bio *bio_copy_kern(struct request_queue *q, void *data, · 445 unmodified lines | ||
| 446 | 446 | if (bytes > len) |
| 447 | 447 | bytes = len; |
| 448 | 448 | |
| 449 | − page = alloc_page(GFP_NOIO | gfp_mask); | |
| 449 | + page = alloc_page(GFP_NOIO | __GFP_ZERO | gfp_mask); | |
| 450 | 450 | if (!page) |
| 451 | 451 | goto cleanup; |
| 452 | 452 | |
| @@ -736,6 +736,10 @@ static void blk_complete_request(struct request *req) · 735 unmodified lines | ||
| 736 | 736 | |
| 737 | 737 | /* Completion has already been traced */ |
| 738 | 738 | bio_clear_flag(bio, BIO_TRACE_COMPLETION); |
| 739 | + | |
| 740 | + if (req_op(req) == REQ_OP_ZONE_APPEND) | |
| 741 | + bio->bi_iter.bi_sector = req->__sector; | |
| 742 | + | |
| 739 | 743 | if (!is_flush) |
| 740 | 744 | bio_endio(bio); |
| 741 | 745 | bio = next; |
| @@ -525,8 +525,6 @@ void elv_unregister_queue(struct request_queue *q) · 524 unmodified lines | ||
| 525 | 525 | kobject_del(&e->kobj); |
| 526 | 526 | |
| 527 | 527 | e->registered = 0; |
| 528 | − /* Re-enable throttling in case elevator disabled it */ | |
| 529 | − wbt_enable_default(q); | |
| 530 | 528 | } |
| 531 | 529 | } |
| 532 | 530 | |
| @@ -289,6 +289,8 @@ static void blkdev_bio_end_io_async(struct bio *bio) · 288 unmodified lines | ||
| 289 | 289 | struct kiocb *iocb = dio->iocb; |
| 290 | 290 | ssize_t ret; |
| 291 | 291 | |
| 292 | + WRITE_ONCE(iocb->private, NULL); | |
| 293 | + | |
| 292 | 294 | if (likely(!bio->bi_status)) { |
| 293 | 295 | ret = dio->size; |
| 294 | 296 | iocb->ki_pos += ret; |
| @@ -548,6 +548,20 @@ out_free_ext_minor: · 547 unmodified lines | ||
| 548 | 548 | } |
| 549 | 549 | EXPORT_SYMBOL(device_add_disk); |
| 550 | 550 | |
| 551 | +/** | |
| 552 | + * blk_mark_disk_dead - mark a disk as dead | |
| 553 | + * @disk: disk to mark as dead | |
| 554 | + * | |
| 555 | + * Mark as disk as dead (e.g. surprise removed) and don't accept any new I/O | |
| 556 | + * to this disk. | |
| 557 | + */ | |
| 558 | +void blk_mark_disk_dead(struct gendisk *disk) | |
| 559 | +{ | |
| 560 | + set_bit(GD_DEAD, &disk->state); | |
| 561 | + blk_queue_start_drain(disk->queue); | |
| 562 | +} | |
| 563 | +EXPORT_SYMBOL_GPL(blk_mark_disk_dead); | |
| 564 | + | |
| 551 | 565 | /** |
| 552 | 566 | * del_gendisk - remove the gendisk |
| 553 | 567 | * @disk: the struct gendisk to remove |
| @@ -96,6 +96,11 @@ static const struct dmi_system_id processor_power_dmi_table[] = { · 95 unmodified lines | ||
| 96 | 96 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
| 97 | 97 | DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")}, |
| 98 | 98 | (void *)1}, |
| 99 | + /* T40 can not handle C3 idle state */ | |
| 100 | + { set_max_cstate, "IBM ThinkPad T40", { | |
| 101 | + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | |
| 102 | + DMI_MATCH(DMI_PRODUCT_NAME, "23737CU")}, | |
| 103 | + (void *)2}, | |
| 99 | 104 | {}, |
| 100 | 105 | }; |
| 101 | 106 | |
| @@ -400,7 +400,7 @@ int __init_or_acpilib acpi_table_parse_entries_array( · 399 unmodified lines | ||
| 400 | 400 | |
| 401 | 401 | acpi_get_table(id, instance, &table_header); |
| 402 | 402 | if (!table_header) { |
| 403 | − pr_warn("%4.4s not present\n", id); | |
| 403 | + pr_debug("%4.4s not present\n", id); | |
| 404 | 404 | return -ENODEV; |
| 405 | 405 | } |
| 406 | 406 | |
| @@ -79,6 +79,7 @@ · 78 unmodified lines | ||
| 79 | 79 | #include <linux/ioprio.h> |
| 80 | 80 | #include <linux/blk-cgroup.h> |
| 81 | 81 | #include <linux/sched/mm.h> |
| 82 | +#include <linux/statfs.h> | |
| 82 | 83 | |
| 83 | 84 | #include "loop.h" |
| 84 | 85 | |
| @@ -774,8 +775,13 @@ static void loop_config_discard(struct loop_device *lo) · 689 unmodified lines | ||
| 774 | 775 | granularity = 0; |
| 775 | 776 | |
| 776 | 777 | } else { |
| 778 | + struct kstatfs sbuf; | |
| 779 | + | |
| 777 | 780 | max_discard_sectors = UINT_MAX >> 9; |
| 778 | − granularity = inode->i_sb->s_blocksize; | |
| 781 | + if (!vfs_statfs(&file->f_path, &sbuf)) | |
| 782 | + granularity = sbuf.f_bsize; | |
| 783 | + else | |
| 784 | + max_discard_sectors = 0; | |
| 779 | 785 | } |
| 780 | 786 | |
| 781 | 787 | if (max_discard_sectors) { |
| @@ -4112,7 +4112,7 @@ static void mtip_pci_remove(struct pci_dev *pdev) · 4111 unmodified lines | ||
| 4112 | 4112 | "Completion workers still active!\n"); |
| 4113 | 4113 | } |
| 4114 | 4114 | |
| 4115 | − blk_set_queue_dying(dd->queue); | |
| 4115 | + blk_mark_disk_dead(dd->disk); | |
| 4116 | 4116 | set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); |
| 4117 | 4117 | |
| 4118 | 4118 | /* Clean up the block layer. */ |
| @@ -7185,7 +7185,7 @@ static ssize_t do_rbd_remove(struct bus_type *bus, · 7184 unmodified lines | ||
| 7185 | 7185 | * IO to complete/fail. |
| 7186 | 7186 | */ |
| 7187 | 7187 | blk_mq_freeze_queue(rbd_dev->disk->queue); |
| 7188 | − blk_set_queue_dying(rbd_dev->disk->queue); | |
| 7188 | + blk_mark_disk_dead(rbd_dev->disk); | |
| 7189 | 7189 | } |
| 7190 | 7190 | |
| 7191 | 7191 | del_gendisk(rbd_dev->disk); |
| @@ -2126,7 +2126,7 @@ static void blkfront_closing(struct blkfront_info *info) · 2125 unmodified lines | ||
| 2126 | 2126 | |
| 2127 | 2127 | /* No more blkif_request(). */ |
| 2128 | 2128 | blk_mq_stop_hw_queues(info->rq); |
| 2129 | − blk_set_queue_dying(info->rq); | |
| 2129 | + blk_mark_disk_dead(info->gd); | |
| 2130 | 2130 | set_capacity(info->gd, 0); |
| 2131 | 2131 | |
| 2132 | 2132 | for_each_rinfo(info, rinfo, i) { |
| @@ -1681,8 +1681,10 @@ static void at_xdmac_tasklet(struct tasklet_struct *t) · 1680 unmodified lines | ||
| 1681 | 1681 | __func__, atchan->irq_status); |
| 1682 | 1682 | |
| 1683 | 1683 | if (!(atchan->irq_status & AT_XDMAC_CIS_LIS) && |
| 1684 | − !(atchan->irq_status & error_mask)) | |
| 1684 | + !(atchan->irq_status & error_mask)) { | |
| 1685 | + spin_unlock_irq(&atchan->lock); | |
| 1685 | 1686 | return; |
| 1687 | + } | |
| 1686 | 1688 | |
| 1687 | 1689 | if (atchan->irq_status & error_mask) |
| 1688 | 1690 | at_xdmac_handle_error(atchan); |
| @@ -207,7 +207,7 @@ int pt_core_init(struct pt_device *pt) · 206 unmodified lines | ||
| 207 | 207 | if (!cmd_q->qbase) { |
| 208 | 208 | dev_err(dev, "unable to allocate command queue\n"); |
| 209 | 209 | ret = -ENOMEM; |
| 210 | − goto e_dma_alloc; | |
| 210 | + goto e_destroy_pool; | |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | 213 | cmd_q->qidx = 0; |
| @@ -229,8 +229,10 @@ int pt_core_init(struct pt_device *pt) · 15 unmodified lines | ||
| 229 | 229 | |
| 230 | 230 | /* Request an irq */ |
| 231 | 231 | ret = request_irq(pt->pt_irq, pt_core_irq_handler, 0, dev_name(pt->dev), pt); |
| 232 | − if (ret) | |
| 233 | − goto e_pool; | |
| 232 | + if (ret) { | |
| 233 | + dev_err(dev, "unable to allocate an IRQ\n"); | |
| 234 | + goto e_free_dma; | |
| 235 | + } | |
| 234 | 236 | |
| 235 | 237 | /* Update the device registers with queue information. */ |
| 236 | 238 | cmd_q->qcontrol &= ~CMD_Q_SIZE; |
| @@ -250,21 +252,20 @@ int pt_core_init(struct pt_device *pt) · 13 unmodified lines | ||
| 250 | 252 | /* Register the DMA engine support */ |
| 251 | 253 | ret = pt_dmaengine_register(pt); |
| 252 | 254 | if (ret) |
| 253 | − goto e_dmaengine; | |
| 255 | + goto e_free_irq; | |
| 254 | 256 | |
| 255 | 257 | /* Set up debugfs entries */ |
| 256 | 258 | ptdma_debugfs_setup(pt); |
| 257 | 259 | |
| 258 | 260 | return 0; |
| 259 | 261 | |
| 260 | −e_dmaengine: | |
| 262 | +e_free_irq: | |
| 261 | 263 | free_irq(pt->pt_irq, pt); |
| 262 | 264 | |
| 263 | −e_dma_alloc: | |
| 265 | +e_free_dma: | |
| 264 | 266 | dma_free_coherent(dev, cmd_q->qsize, cmd_q->qbase, cmd_q->qbase_dma); |
| 265 | 267 | |
| 266 | −e_pool: | |
| 267 | − dev_err(dev, "unable to allocate an IRQ\n"); | |
| 268 | +e_destroy_pool: | |
| 268 | 269 | dma_pool_destroy(pt->cmd_q.dma_pool); |
| 269 | 270 | |
| 270 | 271 | return ret; |
| @@ -1868,8 +1868,13 @@ static int rcar_dmac_probe(struct platform_device *pdev) · 1867 unmodified lines | ||
| 1868 | 1868 | |
| 1869 | 1869 | dmac->dev = &pdev->dev; |
| 1870 | 1870 | platform_set_drvdata(pdev, dmac); |
| 1871 | − dma_set_max_seg_size(dmac->dev, RCAR_DMATCR_MASK); | |
| 1872 | − dma_set_mask_and_coherent(dmac->dev, DMA_BIT_MASK(40)); | |
| 1871 | + ret = dma_set_max_seg_size(dmac->dev, RCAR_DMATCR_MASK); | |
| 1872 | + if (ret) | |
| 1873 | + return ret; | |
| 1874 | + | |
| 1875 | + ret = dma_set_mask_and_coherent(dmac->dev, DMA_BIT_MASK(40)); | |
| 1876 | + if (ret) | |
| 1877 | + return ret; | |
| 1873 | 1878 | |
| 1874 | 1879 | ret = rcar_dmac_parse_of(&pdev->dev, dmac); |
| 1875 | 1880 | if (ret < 0) |
| @@ -115,8 +115,10 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx) · 114 unmodified lines | ||
| 115 | 115 | ret = pm_runtime_get(schan->dev); |
| 116 | 116 | |
| 117 | 117 | spin_unlock_irq(&schan->chan_lock); |
| 118 | − if (ret < 0) | |
| 118 | + if (ret < 0) { | |
| 119 | 119 | dev_err(schan->dev, "%s(): GET = %d\n", __func__, ret); |
| 120 | + pm_runtime_put(schan->dev); | |
| 121 | + } | |
| 120 | 122 | |
| 121 | 123 | pm_runtime_barrier(schan->dev); |
| 122 | 124 | |
| @@ -292,10 +292,12 @@ static int stm32_dmamux_probe(struct platform_device *pdev) · 291 unmodified lines | ||
| 292 | 292 | ret = of_dma_router_register(node, stm32_dmamux_route_allocate, |
| 293 | 293 | &stm32_dmamux->dmarouter); |
| 294 | 294 | if (ret) |
| 295 | − goto err_clk; | |
| 295 | + goto pm_disable; | |
| 296 | 296 | |
| 297 | 297 | return 0; |
| 298 | 298 | |
| 299 | +pm_disable: | |
| 300 | + pm_runtime_disable(&pdev->dev); | |
| 299 | 301 | err_clk: |
| 300 | 302 | clk_disable_unprepare(stm32_dmamux->clk); |
| 301 | 303 | |
| @@ -215,7 +215,7 @@ void *edac_align_ptr(void **p, unsigned int size, int n_elems) · 214 unmodified lines | ||
| 215 | 215 | else |
| 216 | 216 | return (char *)ptr; |
| 217 | 217 | |
| 218 | − r = (unsigned long)p % align; | |
| 218 | + r = (unsigned long)ptr % align; | |
| 219 | 219 | |
| 220 | 220 | if (r == 0) |
| 221 | 221 | return (char *)ptr; |
| @@ -2057,6 +2057,10 @@ static int sdma_v4_0_suspend(void *handle) · 2056 unmodified lines | ||
| 2057 | 2057 | { |
| 2058 | 2058 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 2059 | 2059 | |
| 2060 | + /* SMU saves SDMA state for us */ | |
| 2061 | + if (adev->in_s0ix) | |
| 2062 | + return 0; | |
| 2063 | + | |
| 2060 | 2064 | return sdma_v4_0_hw_fini(adev); |
| 2061 | 2065 | } |
| 2062 | 2066 | |
| @@ -2064,6 +2068,10 @@ static int sdma_v4_0_resume(void *handle) · 1 unmodified line | ||
| 2064 | 2068 | { |
| 2065 | 2069 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 2066 | 2070 | |
| 2071 | + /* SMU restores SDMA state for us */ | |
| 2072 | + if (adev->in_s0ix) | |
| 2073 | + return 0; | |
| 2074 | + | |
| 2067 | 2075 | return sdma_v4_0_hw_init(adev); |
| 2068 | 2076 | } |
| 2069 | 2077 | |
| @@ -1238,21 +1238,37 @@ static int sienna_cichlid_populate_umd_state_clk(struct smu_context *smu) · 1237 unmodified lines | ||
| 1238 | 1238 | &dpm_context->dpm_tables.soc_table; |
| 1239 | 1239 | struct smu_umd_pstate_table *pstate_table = |
| 1240 | 1240 | &smu->pstate_table; |
| 1241 | + struct amdgpu_device *adev = smu->adev; | |
| 1241 | 1242 | |
| 1242 | 1243 | pstate_table->gfxclk_pstate.min = gfx_table->min; |
| 1243 | 1244 | pstate_table->gfxclk_pstate.peak = gfx_table->max; |
| 1244 | − if (gfx_table->max >= SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK) | |
| 1245 | − pstate_table->gfxclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK; | |
| 1246 | 1245 | |
| 1247 | 1246 | pstate_table->uclk_pstate.min = mem_table->min; |
| 1248 | 1247 | pstate_table->uclk_pstate.peak = mem_table->max; |
| 1249 | − if (mem_table->max >= SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK) | |
| 1250 | − pstate_table->uclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK; | |
| 1251 | 1248 | |
| 1252 | 1249 | pstate_table->socclk_pstate.min = soc_table->min; |
| 1253 | 1250 | pstate_table->socclk_pstate.peak = soc_table->max; |
| 1254 | − if (soc_table->max >= SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK) | |
| 1251 | + | |
| 1252 | + switch (adev->asic_type) { | |
| 1253 | + case CHIP_SIENNA_CICHLID: | |
| 1254 | + case CHIP_NAVY_FLOUNDER: | |
| 1255 | + pstate_table->gfxclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK; | |
| 1256 | + pstate_table->uclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK; | |
| 1255 | 1257 | pstate_table->socclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK; |
| 1258 | + break; | |
| 1259 | + case CHIP_DIMGREY_CAVEFISH: | |
| 1260 | + pstate_table->gfxclk_pstate.standard = DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_GFXCLK; | |
| 1261 | + pstate_table->uclk_pstate.standard = DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_MEMCLK; | |
| 1262 | + pstate_table->socclk_pstate.standard = DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_SOCCLK; | |
| 1263 | + break; | |
| 1264 | + case CHIP_BEIGE_GOBY: | |
| 1265 | + pstate_table->gfxclk_pstate.standard = BEIGE_GOBY_UMD_PSTATE_PROFILING_GFXCLK; | |
| 1266 | + pstate_table->uclk_pstate.standard = BEIGE_GOBY_UMD_PSTATE_PROFILING_MEMCLK; | |
| 1267 | + pstate_table->socclk_pstate.standard = BEIGE_GOBY_UMD_PSTATE_PROFILING_SOCCLK; | |
| 1268 | + break; | |
| 1269 | + default: | |
| 1270 | + break; | |
| 1271 | + } | |
| 1256 | 1272 | |
| 1257 | 1273 | return 0; |
| 1258 | 1274 | } |
| @@ -33,6 +33,14 @@ typedef enum { · 32 unmodified lines | ||
| 33 | 33 | #define SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK 960 |
| 34 | 34 | #define SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK 1000 |
| 35 | 35 | |
| 36 | +#define DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_GFXCLK 1950 | |
| 37 | +#define DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_SOCCLK 960 | |
| 38 | +#define DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_MEMCLK 676 | |
| 39 | + | |
| 40 | +#define BEIGE_GOBY_UMD_PSTATE_PROFILING_GFXCLK 2200 | |
| 41 | +#define BEIGE_GOBY_UMD_PSTATE_PROFILING_SOCCLK 960 | |
| 42 | +#define BEIGE_GOBY_UMD_PSTATE_PROFILING_MEMCLK 1000 | |
| 43 | + | |
| 36 | 44 | extern void sienna_cichlid_set_ppt_funcs(struct smu_context *smu); |
| 37 | 45 | |
| 38 | 46 | #endif |
| @@ -282,14 +282,9 @@ static int yellow_carp_post_smu_init(struct smu_context *smu) · 281 unmodified lines | ||
| 282 | 282 | |
| 283 | 283 | static int yellow_carp_mode_reset(struct smu_context *smu, int type) |
| 284 | 284 | { |
| 285 | − int ret = 0, index = 0; | |
| 286 | − | |
| 287 | − index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, | |
| 288 | − SMU_MSG_GfxDeviceDriverReset); | |
| 289 | − if (index < 0) | |
| 290 | − return index == -EACCES ? 0 : index; | |
| 285 | + int ret = 0; | |
| 291 | 286 | |
| 292 | − ret = smu_cmn_send_smc_msg_with_param(smu, (uint16_t)index, type, NULL); | |
| 287 | + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, type, NULL); | |
| 293 | 288 | if (ret) |
| 294 | 289 | dev_err(smu->adev->dev, "Failed to mode reset!\n"); |
| 295 | 290 | |
| @@ -76,15 +76,17 @@ int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, · 75 unmodified lines | ||
| 76 | 76 | state->mode_blob = NULL; |
| 77 | 77 | |
| 78 | 78 | if (mode) { |
| 79 | + struct drm_property_blob *blob; | |
| 80 | + | |
| 79 | 81 | drm_mode_convert_to_umode(&umode, mode); |
| 80 | − state->mode_blob = | |
| 81 | − drm_property_create_blob(state->crtc->dev, | |
| 82 | − sizeof(umode), | |
| 83 | − &umode); | |
| 84 | − if (IS_ERR(state->mode_blob)) | |
| 85 | − return PTR_ERR(state->mode_blob); | |
| 82 | + blob = drm_property_create_blob(crtc->dev, | |
| 83 | + sizeof(umode), &umode); | |
| 84 | + if (IS_ERR(blob)) | |
| 85 | + return PTR_ERR(blob); | |
| 86 | 86 | |
| 87 | 87 | drm_mode_copy(&state->mode, mode); |
| 88 | + | |
| 89 | + state->mode_blob = blob; | |
| 88 | 90 | state->enable = true; |
| 89 | 91 | drm_dbg_atomic(crtc->dev, |
| 90 | 92 | "Set [MODE:%s] for [CRTC:%d:%s] state %p\n", |
| @@ -512,6 +512,7 @@ int drm_gem_cma_mmap(struct drm_gem_cma_object *cma_obj, struct vm_area_struct * · 511 unmodified lines | ||
| 512 | 512 | */ |
| 513 | 513 | vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); |
| 514 | 514 | vma->vm_flags &= ~VM_PFNMAP; |
| 515 | + vma->vm_flags |= VM_DONTEXPAND; | |
| 515 | 516 | |
| 516 | 517 | if (cma_obj->map_noncoherent) { |
| 517 | 518 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
| @@ -101,6 +101,7 @@ config DRM_I915_USERPTR · 100 unmodified lines | ||
| 101 | 101 | config DRM_I915_GVT |
| 102 | 102 | bool "Enable Intel GVT-g graphics virtualization host support" |
| 103 | 103 | depends on DRM_I915 |
| 104 | + depends on X86 | |
| 104 | 105 | depends on 64BIT |
| 105 | 106 | default n |
| 106 | 107 | help |
| @@ -1115,7 +1115,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, · 1114 unmodified lines | ||
| 1115 | 1115 | |
| 1116 | 1116 | /* Wa_22010751166: icl, ehl, tgl, dg1, rkl */ |
| 1117 | 1117 | if (DISPLAY_VER(i915) >= 11 && |
| 1118 | − (plane_state->view.color_plane[0].y + drm_rect_height(&plane_state->uapi.src)) & 3) { | |
| 1118 | + (plane_state->view.color_plane[0].y + | |
| 1119 | + (drm_rect_height(&plane_state->uapi.src) >> 16)) & 3) { | |
| 1119 | 1120 | plane_state->no_fbc_reason = "plane end Y offset misaligned"; |
| 1120 | 1121 | return false; |
| 1121 | 1122 | } |
| @@ -360,6 +360,21 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, · 359 unmodified lines | ||
| 360 | 360 | port++; |
| 361 | 361 | } |
| 362 | 362 | |
| 363 | + /* | |
| 364 | + * The port numbering and mapping here is bizarre. The now-obsolete | |
| 365 | + * swsci spec supports ports numbered [0..4]. Port E is handled as a | |
| 366 | + * special case, but port F and beyond are not. The functionality is | |
| 367 | + * supposed to be obsolete for new platforms. Just bail out if the port | |
| 368 | + * number is out of bounds after mapping. | |
| 369 | + */ | |
| 370 | + if (port > 4) { | |
| 371 | + drm_dbg_kms(&dev_priv->drm, | |
| 372 | + "[ENCODER:%d:%s] port %c (index %u) out of bounds for display power state notification\n", | |
| 373 | + intel_encoder->base.base.id, intel_encoder->base.name, | |
| 374 | + port_name(intel_encoder->port), port); | |
| 375 | + return -EINVAL; | |
| 376 | + } | |
| 377 | + | |
| 363 | 378 | if (!enable) |
| 364 | 379 | parm |= 4 << 8; |
| 365 | 380 | |
| @@ -842,11 +842,9 @@ void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj) · 841 unmodified lines | ||
| 842 | 842 | } else if (obj->mm.madv != I915_MADV_WILLNEED) { |
| 843 | 843 | bo->priority = I915_TTM_PRIO_PURGE; |
| 844 | 844 | } else if (!i915_gem_object_has_pages(obj)) { |
| 845 | − if (bo->priority < I915_TTM_PRIO_HAS_PAGES) | |
| 846 | − bo->priority = I915_TTM_PRIO_HAS_PAGES; | |
| 845 | + bo->priority = I915_TTM_PRIO_NO_PAGES; | |
| 847 | 846 | } else { |
| 848 | − if (bo->priority > I915_TTM_PRIO_NO_PAGES) | |
| 849 | − bo->priority = I915_TTM_PRIO_NO_PAGES; | |
| 847 | + bo->priority = I915_TTM_PRIO_HAS_PAGES; | |
| 850 | 848 | } |
| 851 | 849 | |
| 852 | 850 | ttm_bo_move_to_lru_tail(bo, bo->resource, NULL); |
| @@ -1148,7 +1148,7 @@ static inline void ppgtt_generate_shadow_entry(struct intel_gvt_gtt_entry *se, · 1147 unmodified lines | ||
| 1148 | 1148 | ops->set_pfn(se, s->shadow_page.mfn); |
| 1149 | 1149 | } |
| 1150 | 1150 | |
| 1151 | −/** | |
| 1151 | +/* | |
| 1152 | 1152 | * Check if can do 2M page |
| 1153 | 1153 | * @vgpu: target vgpu |
| 1154 | 1154 | * @entry: target pfn's gtt entry |
| @@ -2193,7 +2193,7 @@ static int emulate_ggtt_mmio_read(struct intel_vgpu *vgpu, · 1038 unmodified lines | ||
| 2193 | 2193 | } |
| 2194 | 2194 | |
| 2195 | 2195 | /** |
| 2196 | − * intel_vgpu_emulate_gtt_mmio_read - emulate GTT MMIO register read | |
| 2196 | + * intel_vgpu_emulate_ggtt_mmio_read - emulate GTT MMIO register read | |
| 2197 | 2197 | * @vgpu: a vGPU |
| 2198 | 2198 | * @off: register offset |
| 2199 | 2199 | * @p_data: data will be returned to guest |
| @@ -4853,7 +4853,7 @@ static bool check_mbus_joined(u8 active_pipes, · 4852 unmodified lines | ||
| 4853 | 4853 | { |
| 4854 | 4854 | int i; |
| 4855 | 4855 | |
| 4856 | − for (i = 0; i < dbuf_slices[i].active_pipes; i++) { | |
| 4856 | + for (i = 0; dbuf_slices[i].active_pipes != 0; i++) { | |
| 4857 | 4857 | if (dbuf_slices[i].active_pipes == active_pipes) |
| 4858 | 4858 | return dbuf_slices[i].join_mbus; |
| 4859 | 4859 | } |
| @@ -4870,7 +4870,7 @@ static u8 compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus, · 10 unmodified lines | ||
| 4870 | 4870 | { |
| 4871 | 4871 | int i; |
| 4872 | 4872 | |
| 4873 | − for (i = 0; i < dbuf_slices[i].active_pipes; i++) { | |
| 4873 | + for (i = 0; dbuf_slices[i].active_pipes != 0; i++) { | |
| 4874 | 4874 | if (dbuf_slices[i].active_pipes == active_pipes && |
| 4875 | 4875 | dbuf_slices[i].join_mbus == join_mbus) |
| 4876 | 4876 | return dbuf_slices[i].dbuf_mask[pipe]; |
| @@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev) · 785 unmodified lines | ||
| 786 | 786 | mtk_dsi_poweroff(dsi); |
| 787 | 787 | } |
| 788 | 788 | |
| 789 | +static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi) | |
| 790 | +{ | |
| 791 | + int ret; | |
| 792 | + | |
| 793 | + ret = drm_simple_encoder_init(drm, &dsi->encoder, | |
| 794 | + DRM_MODE_ENCODER_DSI); | |
| 795 | + if (ret) { | |
| 796 | + DRM_ERROR("Failed to encoder init to drm\n"); | |
| 797 | + return ret; | |
| 798 | + } | |
| 799 | + | |
| 800 | + dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev); | |
| 801 | + | |
| 802 | + ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, | |
| 803 | + DRM_BRIDGE_ATTACH_NO_CONNECTOR); | |
| 804 | + if (ret) | |
| 805 | + goto err_cleanup_encoder; | |
| 806 | + | |
| 807 | + dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder); | |
| 808 | + if (IS_ERR(dsi->connector)) { | |
| 809 | + DRM_ERROR("Unable to create bridge connector\n"); | |
| 810 | + ret = PTR_ERR(dsi->connector); | |
| 811 | + goto err_cleanup_encoder; | |
| 812 | + } | |
| 813 | + drm_connector_attach_encoder(dsi->connector, &dsi->encoder); | |
| 814 | + | |
| 815 | + return 0; | |
| 816 | + | |
| 817 | +err_cleanup_encoder: | |
| 818 | + drm_encoder_cleanup(&dsi->encoder); | |
| 819 | + return ret; | |
| 820 | +} | |
| 821 | + | |
| 822 | +static int mtk_dsi_bind(struct device *dev, struct device *master, void *data) | |
| 823 | +{ | |
| 824 | + int ret; | |
| 825 | + struct drm_device *drm = data; | |
| 826 | + struct mtk_dsi *dsi = dev_get_drvdata(dev); | |
| 827 | + | |
| 828 | + ret = mtk_dsi_encoder_init(drm, dsi); | |
| 829 | + if (ret) | |
| 830 | + return ret; | |
| 831 | + | |
| 832 | + return device_reset_optional(dev); | |
| 833 | +} | |
| 834 | + | |
| 835 | +static void mtk_dsi_unbind(struct device *dev, struct device *master, | |
| 836 | + void *data) | |
| 837 | +{ | |
| 838 | + struct mtk_dsi *dsi = dev_get_drvdata(dev); | |
| 839 | + | |
| 840 | + drm_encoder_cleanup(&dsi->encoder); | |
| 841 | +} | |
| 842 | + | |
| 843 | +static const struct component_ops mtk_dsi_component_ops = { | |
| 844 | + .bind = mtk_dsi_bind, | |
| 845 | + .unbind = mtk_dsi_unbind, | |
| 846 | +}; | |
| 847 | + | |
| 789 | 848 | static int mtk_dsi_host_attach(struct mipi_dsi_host *host, |
| 790 | 849 | struct mipi_dsi_device *device) |
| 791 | 850 | { |
| 792 | 851 | struct mtk_dsi *dsi = host_to_dsi(host); |
| 852 | + struct device *dev = host->dev; | |
| 853 | + int ret; | |
| 793 | 854 | |
| 794 | 855 | dsi->lanes = device->lanes; |
| 795 | 856 | dsi->format = device->format; |
| 796 | 857 | dsi->mode_flags = device->mode_flags; |
| 858 | + dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0); | |
| 859 | + if (IS_ERR(dsi->next_bridge)) | |
| 860 | + return PTR_ERR(dsi->next_bridge); | |
| 861 | + | |
| 862 | + drm_bridge_add(&dsi->bridge); | |
| 863 | + | |
| 864 | + ret = component_add(host->dev, &mtk_dsi_component_ops); | |
| 865 | + if (ret) { | |
| 866 | + DRM_ERROR("failed to add dsi_host component: %d\n", ret); | |
| 867 | + drm_bridge_remove(&dsi->bridge); | |
| 868 | + return ret; | |
| 869 | + } | |
| 797 | 870 | |
| 798 | 871 | return 0; |
| 799 | 872 | } |
| 800 | 873 | |
| 874 | +static int mtk_dsi_host_detach(struct mipi_dsi_host *host, | |
| 875 | + struct mipi_dsi_device *device) | |
| 876 | +{ | |
| 877 | + struct mtk_dsi *dsi = host_to_dsi(host); | |
| 878 | + | |
| 879 | + component_del(host->dev, &mtk_dsi_component_ops); | |
| 880 | + drm_bridge_remove(&dsi->bridge); | |
| 881 | + return 0; | |
| 882 | +} | |
| 883 | + | |
| 801 | 884 | static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi) |
| 802 | 885 | { |
| 803 | 886 | int ret; |
| @@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host, · 134 unmodified lines | ||
| 938 | 1021 | |
| 939 | 1022 | static const struct mipi_dsi_host_ops mtk_dsi_ops = { |
| 940 | 1023 | .attach = mtk_dsi_host_attach, |
| 1024 | + .detach = mtk_dsi_host_detach, | |
| 941 | 1025 | .transfer = mtk_dsi_host_transfer, |
| 942 | 1026 | }; |
| 943 | 1027 | |
| 944 | −static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi) | |
| 945 | −{ | |
| 946 | − int ret; | |
| 947 | − | |
| 948 | − ret = drm_simple_encoder_init(drm, &dsi->encoder, | |
| 949 | − DRM_MODE_ENCODER_DSI); | |
| 950 | − if (ret) { | |
| 951 | − DRM_ERROR("Failed to encoder init to drm\n"); | |
| 952 | − return ret; | |
| 953 | − } | |
| 954 | − | |
| 955 | − dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev); | |
| 956 | − | |
| 957 | − ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, | |
| 958 | − DRM_BRIDGE_ATTACH_NO_CONNECTOR); | |
| 959 | − if (ret) | |
| 960 | − goto err_cleanup_encoder; | |
| 961 | − | |
| 962 | − dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder); | |
| 963 | − if (IS_ERR(dsi->connector)) { | |
| 964 | − DRM_ERROR("Unable to create bridge connector\n"); | |
| 965 | − ret = PTR_ERR(dsi->connector); | |
| 966 | − goto err_cleanup_encoder; | |
| 967 | − } | |
| 968 | − drm_connector_attach_encoder(dsi->connector, &dsi->encoder); | |
| 969 | − | |
| 970 | − return 0; | |
| 971 | − | |
| 972 | −err_cleanup_encoder: | |
| 973 | − drm_encoder_cleanup(&dsi->encoder); | |
| 974 | − return ret; | |
| 975 | −} | |
| 976 | − | |
| 977 | −static int mtk_dsi_bind(struct device *dev, struct device *master, void *data) | |
| 978 | −{ | |
| 979 | − int ret; | |
| 980 | − struct drm_device *drm = data; | |
| 981 | − struct mtk_dsi *dsi = dev_get_drvdata(dev); | |
| 982 | − | |
| 983 | − ret = mtk_dsi_encoder_init(drm, dsi); | |
| 984 | − if (ret) | |
| 985 | − return ret; | |
| 986 | − | |
| 987 | − return device_reset_optional(dev); | |
| 988 | −} | |
| 989 | − | |
| 990 | −static void mtk_dsi_unbind(struct device *dev, struct device *master, | |
| 991 | − void *data) | |
| 992 | −{ | |
| 993 | − struct mtk_dsi *dsi = dev_get_drvdata(dev); | |
| 994 | − | |
| 995 | − drm_encoder_cleanup(&dsi->encoder); | |
| 996 | −} | |
| 997 | − | |
| 998 | −static const struct component_ops mtk_dsi_component_ops = { | |
| 999 | − .bind = mtk_dsi_bind, | |
| 1000 | − .unbind = mtk_dsi_unbind, | |
| 1001 | −}; | |
| 1002 | − | |
| 1003 | 1028 | static int mtk_dsi_probe(struct platform_device *pdev) |
| 1004 | 1029 | { |
| 1005 | 1030 | struct mtk_dsi *dsi; |
| 1006 | 1031 | struct device *dev = &pdev->dev; |
| 1007 | − struct drm_panel *panel; | |
| 1008 | 1032 | struct resource *regs; |
| 1009 | 1033 | int irq_num; |
| 1010 | 1034 | int ret; |
| @@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 1021 | 1045 | return ret; |
| 1022 | 1046 | } |
| 1023 | 1047 | |
| 1024 | − ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, | |
| 1025 | − &panel, &dsi->next_bridge); | |
| 1026 | − if (ret) | |
| 1027 | − goto err_unregister_host; | |
| 1028 | − | |
| 1029 | − if (panel) { | |
| 1030 | − dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel); | |
| 1031 | − if (IS_ERR(dsi->next_bridge)) { | |
| 1032 | − ret = PTR_ERR(dsi->next_bridge); | |
| 1033 | − goto err_unregister_host; | |
| 1034 | − } | |
| 1035 | − } | |
| 1036 | − | |
| 1037 | 1048 | dsi->driver_data = of_device_get_match_data(dev); |
| 1038 | 1049 | |
| 1039 | 1050 | dsi->engine_clk = devm_clk_get(dev, "engine"); |
| @@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev) · 58 unmodified lines | ||
| 1098 | 1109 | dsi->bridge.of_node = dev->of_node; |
| 1099 | 1110 | dsi->bridge.type = DRM_MODE_CONNECTOR_DSI; |
| 1100 | 1111 | |
| 1101 | − drm_bridge_add(&dsi->bridge); | |
| 1102 | − | |
| 1103 | − ret = component_add(&pdev->dev, &mtk_dsi_component_ops); | |
| 1104 | − if (ret) { | |
| 1105 | − dev_err(&pdev->dev, "failed to add component: %d\n", ret); | |
| 1106 | − goto err_unregister_host; | |
| 1107 | − } | |
| 1108 | − | |
| 1109 | 1112 | return 0; |
| 1110 | 1113 | |
| 1111 | 1114 | err_unregister_host: |
| @@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev) · 6 unmodified lines | ||
| 1118 | 1121 | struct mtk_dsi *dsi = platform_get_drvdata(pdev); |
| 1119 | 1122 | |
| 1120 | 1123 | mtk_output_dsi_disable(dsi); |
| 1121 | − drm_bridge_remove(&dsi->bridge); | |
| 1122 | − component_del(&pdev->dev, &mtk_dsi_component_ops); | |
| 1123 | 1124 | mipi_dsi_host_unregister(&dsi->host); |
| 1124 | 1125 | |
| 1125 | 1126 | return 0; |
| @@ -198,7 +198,8 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, · 197 unmodified lines | ||
| 198 | 198 | * so don't register a backlight device |
| 199 | 199 | */ |
| 200 | 200 | if ((rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) && |
| 201 | − (rdev->pdev->device == 0x6741)) | |
| 201 | + (rdev->pdev->device == 0x6741) && | |
| 202 | + !dmi_match(DMI_PRODUCT_NAME, "iMac12,1")) | |
| 202 | 203 | return; |
| 203 | 204 | |
| 204 | 205 | if (!radeon_encoder->enc_priv) |
| @@ -214,12 +214,14 @@ static int hwmon_thermal_add_sensor(struct device *dev, int index) · 213 unmodified lines | ||
| 214 | 214 | |
| 215 | 215 | tzd = devm_thermal_zone_of_sensor_register(dev, index, tdata, |
| 216 | 216 | &hwmon_thermal_ops); |
| 217 | − /* | |
| 218 | − * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV, | |
| 219 | − * so ignore that error but forward any other error. | |
| 220 | − */ | |
| 221 | − if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV)) | |
| 222 | − return PTR_ERR(tzd); | |
| 217 | + if (IS_ERR(tzd)) { | |
| 218 | + if (PTR_ERR(tzd) != -ENODEV) | |
| 219 | + return PTR_ERR(tzd); | |
| 220 | + dev_info(dev, "temp%d_input not attached to any thermal zone\n", | |
| 221 | + index + 1); | |
| 222 | + devm_kfree(dev, tdata); | |
| 223 | + return 0; | |
| 224 | + } | |
| 223 | 225 | |
| 224 | 226 | err = devm_add_action(dev, hwmon_thermal_remove_sensor, &tdata->node); |
| 225 | 227 | if (err) |
| @@ -59,7 +59,7 @@ static const struct platform_device_id ntc_thermistor_id[] = { · 58 unmodified lines | ||
| 59 | 59 | [NTC_NCP15XH103] = { "ncp15xh103", TYPE_NCPXXXH103 }, |
| 60 | 60 | [NTC_NCP18WB473] = { "ncp18wb473", TYPE_NCPXXWB473 }, |
| 61 | 61 | [NTC_NCP21WB473] = { "ncp21wb473", TYPE_NCPXXWB473 }, |
| 62 | − [NTC_SSG1404001221] = { "ssg1404-001221", TYPE_NCPXXWB473 }, | |
| 62 | + [NTC_SSG1404001221] = { "ssg1404_001221", TYPE_NCPXXWB473 }, | |
| 63 | 63 | [NTC_LAST] = { }, |
| 64 | 64 | }; |
| 65 | 65 | |
| @@ -911,6 +911,11 @@ static int pmbus_get_boolean(struct i2c_client *client, struct pmbus_boolean *b, · 910 unmodified lines | ||
| 911 | 911 | pmbus_update_sensor_data(client, s2); |
| 912 | 912 | |
| 913 | 913 | regval = status & mask; |
| 914 | + if (regval) { | |
| 915 | + ret = pmbus_write_byte_data(client, page, reg, regval); | |
| 916 | + if (ret) | |
| 917 | + goto unlock; | |
| 918 | + } | |
| 914 | 919 | if (s1 && s2) { |
| 915 | 920 | s64 v1, v2; |
| 916 | 921 | |
| @@ -488,7 +488,7 @@ config I2C_BRCMSTB · 487 unmodified lines | ||
| 488 | 488 | |
| 489 | 489 | config I2C_CADENCE |
| 490 | 490 | tristate "Cadence I2C Controller" |
| 491 | − depends on ARCH_ZYNQ || ARM64 || XTENSA | |
| 491 | + depends on ARCH_ZYNQ || ARM64 || XTENSA || COMPILE_TEST | |
| 492 | 492 | help |
| 493 | 493 | Say yes here to select Cadence I2C Host Controller. This controller is |
| 494 | 494 | e.g. used by Xilinx Zynq. |
| @@ -680,7 +680,7 @@ config I2C_IMG · 185 unmodified lines | ||
| 680 | 680 | |
| 681 | 681 | config I2C_IMX |
| 682 | 682 | tristate "IMX I2C interface" |
| 683 | − depends on ARCH_MXC || ARCH_LAYERSCAPE || COLDFIRE | |
| 683 | + depends on ARCH_MXC || ARCH_LAYERSCAPE || COLDFIRE || COMPILE_TEST | |
| 684 | 684 | select I2C_SLAVE |
| 685 | 685 | help |
| 686 | 686 | Say Y here if you want to use the IIC bus controller on |
| @@ -935,7 +935,7 @@ config I2C_QCOM_GENI · 248 unmodified lines | ||
| 935 | 935 | |
| 936 | 936 | config I2C_QUP |
| 937 | 937 | tristate "Qualcomm QUP based I2C controller" |
| 938 | − depends on ARCH_QCOM | |
| 938 | + depends on ARCH_QCOM || COMPILE_TEST | |
| 939 | 939 | help |
| 940 | 940 | If you say yes to this option, support will be included for the |
| 941 | 941 | built-in I2C interface on the Qualcomm SoCs. |
| @@ -23,6 +23,11 @@ · 22 unmodified lines | ||
| 23 | 23 | #define BCM2835_I2C_FIFO 0x10 |
| 24 | 24 | #define BCM2835_I2C_DIV 0x14 |
| 25 | 25 | #define BCM2835_I2C_DEL 0x18 |
| 26 | +/* | |
| 27 | + * 16-bit field for the number of SCL cycles to wait after rising SCL | |
| 28 | + * before deciding the slave is not responding. 0 disables the | |
| 29 | + * timeout detection. | |
| 30 | + */ | |
| 26 | 31 | #define BCM2835_I2C_CLKT 0x1c |
| 27 | 32 | |
| 28 | 33 | #define BCM2835_I2C_C_READ BIT(0) |
| @@ -474,6 +479,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) · 445 unmodified lines | ||
| 474 | 479 | adap->dev.of_node = pdev->dev.of_node; |
| 475 | 480 | adap->quirks = of_device_get_match_data(&pdev->dev); |
| 476 | 481 | |
| 482 | + /* | |
| 483 | + * Disable the hardware clock stretching timeout. SMBUS | |
| 484 | + * specifies a limit for how long the device can stretch the | |
| 485 | + * clock, but core I2C doesn't. | |
| 486 | + */ | |
| 487 | + bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_CLKT, 0); | |
| 477 | 488 | bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0); |
| 478 | 489 | |
| 479 | 490 | ret = i2c_add_adapter(adap); |
| @@ -673,7 +673,7 @@ static int brcmstb_i2c_probe(struct platform_device *pdev) · 672 unmodified lines | ||
| 673 | 673 | |
| 674 | 674 | /* set the data in/out register size for compatible SoCs */ |
| 675 | 675 | if (of_device_is_compatible(dev->device->of_node, |
| 676 | − "brcmstb,brcmper-i2c")) | |
| 676 | + "brcm,brcmper-i2c")) | |
| 677 | 677 | dev->data_regsz = sizeof(u8); |
| 678 | 678 | else |
| 679 | 679 | dev->data_regsz = sizeof(u32); |
| @@ -558,7 +558,7 @@ static int cci_probe(struct platform_device *pdev) · 557 unmodified lines | ||
| 558 | 558 | cci->master[idx].adap.quirks = &cci->data->quirks; |
| 559 | 559 | cci->master[idx].adap.algo = &cci_algo; |
| 560 | 560 | cci->master[idx].adap.dev.parent = dev; |
| 561 | − cci->master[idx].adap.dev.of_node = child; | |
| 561 | + cci->master[idx].adap.dev.of_node = of_node_get(child); | |
| 562 | 562 | cci->master[idx].master = idx; |
| 563 | 563 | cci->master[idx].cci = cci; |
| 564 | 564 | |
| @@ -643,8 +643,10 @@ static int cci_probe(struct platform_device *pdev) · 78 unmodified lines | ||
| 643 | 643 | continue; |
| 644 | 644 | |
| 645 | 645 | ret = i2c_add_adapter(&cci->master[i].adap); |
| 646 | − if (ret < 0) | |
| 646 | + if (ret < 0) { | |
| 647 | + of_node_put(cci->master[i].adap.dev.of_node); | |
| 647 | 648 | goto error_i2c; |
| 649 | + } | |
| 648 | 650 | } |
| 649 | 651 | |
| 650 | 652 | pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); |
| @@ -655,9 +657,11 @@ static int cci_probe(struct platform_device *pdev) · 4 unmodified lines | ||
| 655 | 657 | return 0; |
| 656 | 658 | |
| 657 | 659 | error_i2c: |
| 658 | − for (; i >= 0; i--) { | |
| 659 | − if (cci->master[i].cci) | |
| 660 | + for (--i ; i >= 0; i--) { | |
| 661 | + if (cci->master[i].cci) { | |
| 660 | 662 | i2c_del_adapter(&cci->master[i].adap); |
| 663 | + of_node_put(cci->master[i].adap.dev.of_node); | |
| 664 | + } | |
| 661 | 665 | } |
| 662 | 666 | error: |
| 663 | 667 | disable_irq(cci->irq); |
| @@ -673,8 +677,10 @@ static int cci_remove(struct platform_device *pdev) · 9 unmodified lines | ||
| 673 | 677 | int i; |
| 674 | 678 | |
| 675 | 679 | for (i = 0; i < cci->data->num_masters; i++) { |
| 676 | − if (cci->master[i].cci) | |
| 680 | + if (cci->master[i].cci) { | |
| 677 | 681 | i2c_del_adapter(&cci->master[i].adap); |
| 682 | + of_node_put(cci->master[i].adap.dev.of_node); | |
| 683 | + } | |
| 678 | 684 | cci_halt(cci, i); |
| 679 | 685 | } |
| 680 | 686 | |
| @@ -2285,6 +2285,12 @@ int input_register_device(struct input_dev *dev) · 2284 unmodified lines | ||
| 2285 | 2285 | /* KEY_RESERVED is not supposed to be transmitted to userspace. */ |
| 2286 | 2286 | __clear_bit(KEY_RESERVED, dev->keybit); |
| 2287 | 2287 | |
| 2288 | + /* Buttonpads should not map BTN_RIGHT and/or BTN_MIDDLE. */ | |
| 2289 | + if (test_bit(INPUT_PROP_BUTTONPAD, dev->propbit)) { | |
| 2290 | + __clear_bit(BTN_RIGHT, dev->keybit); | |
| 2291 | + __clear_bit(BTN_MIDDLE, dev->keybit); | |
| 2292 | + } | |
| 2293 | + | |
| 2288 | 2294 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ |
| 2289 | 2295 | input_cleanse_bitmasks(dev); |
| 2290 | 2296 | |
| @@ -75,6 +75,8 @@ static void psmouse_smbus_detach_i2c_client(struct i2c_client *client) · 74 unmodified lines | ||
| 75 | 75 | "Marking SMBus companion %s as gone\n", |
| 76 | 76 | dev_name(&smbdev->client->dev)); |
| 77 | 77 | smbdev->dead = true; |
| 78 | + device_link_remove(&smbdev->client->dev, | |
| 79 | + &smbdev->psmouse->ps2dev.serio->dev); | |
| 78 | 80 | serio_rescan(smbdev->psmouse->ps2dev.serio); |
| 79 | 81 | } else { |
| 80 | 82 | list_del(&smbdev->node); |
| @@ -174,6 +176,8 @@ static void psmouse_smbus_disconnect(struct psmouse *psmouse) · 93 unmodified lines | ||
| 174 | 176 | kfree(smbdev); |
| 175 | 177 | } else { |
| 176 | 178 | smbdev->dead = true; |
| 179 | + device_link_remove(&smbdev->client->dev, | |
| 180 | + &psmouse->ps2dev.serio->dev); | |
| 177 | 181 | psmouse_dbg(smbdev->psmouse, |
| 178 | 182 | "posting removal request for SMBus companion %s\n", |
| 179 | 183 | dev_name(&smbdev->client->dev)); |
| @@ -270,6 +274,12 @@ int psmouse_smbus_init(struct psmouse *psmouse, · 90 unmodified lines | ||
| 270 | 274 | |
| 271 | 275 | if (smbdev->client) { |
| 272 | 276 | /* We have our companion device */ |
| 277 | + if (!device_link_add(&smbdev->client->dev, | |
| 278 | + &psmouse->ps2dev.serio->dev, | |
| 279 | + DL_FLAG_STATELESS)) | |
| 280 | + psmouse_warn(psmouse, | |
| 281 | + "failed to set up link with iSMBus companion %s\n", | |
| 282 | + dev_name(&smbdev->client->dev)); | |
| 273 | 283 | return 0; |
| 274 | 284 | } |
| 275 | 285 | |
| @@ -571,8 +571,20 @@ static SIMPLE_DEV_PM_OPS(zinitix_pm_ops, zinitix_suspend, zinitix_resume); · 570 unmodified lines | ||
| 571 | 571 | |
| 572 | 572 | #ifdef CONFIG_OF |
| 573 | 573 | static const struct of_device_id zinitix_of_match[] = { |
| 574 | + { .compatible = "zinitix,bt402" }, | |
| 575 | + { .compatible = "zinitix,bt403" }, | |
| 576 | + { .compatible = "zinitix,bt404" }, | |
| 577 | + { .compatible = "zinitix,bt412" }, | |
| 578 | + { .compatible = "zinitix,bt413" }, | |
| 579 | + { .compatible = "zinitix,bt431" }, | |
| 580 | + { .compatible = "zinitix,bt432" }, | |
| 581 | + { .compatible = "zinitix,bt531" }, | |
| 574 | 582 | { .compatible = "zinitix,bt532" }, |
| 583 | + { .compatible = "zinitix,bt538" }, | |
| 575 | 584 | { .compatible = "zinitix,bt541" }, |
| 585 | + { .compatible = "zinitix,bt548" }, | |
| 586 | + { .compatible = "zinitix,bt554" }, | |
| 587 | + { .compatible = "zinitix,at100" }, | |
| 576 | 588 | { } |
| 577 | 589 | }; |
| 578 | 590 | MODULE_DEVICE_TABLE(of, zinitix_of_match); |
| @@ -2077,7 +2077,7 @@ static void __dm_destroy(struct mapped_device *md, bool wait) · 2076 unmodified lines | ||
| 2077 | 2077 | set_bit(DMF_FREEING, &md->flags); |
| 2078 | 2078 | spin_unlock(&_minor_lock); |
| 2079 | 2079 | |
| 2080 | − blk_set_queue_dying(md->queue); | |
| 2080 | + blk_mark_disk_dead(md->disk); | |
| 2081 | 2081 | |
| 2082 | 2082 | /* |
| 2083 | 2083 | * Take suspend_lock so that presuspend and postsuspend methods |
| @@ -264,16 +264,20 @@ static int phram_setup(const char *val) · 263 unmodified lines | ||
| 264 | 264 | } |
| 265 | 265 | } |
| 266 | 266 | |
| 267 | − if (erasesize) | |
| 268 | − div_u64_rem(len, (uint32_t)erasesize, &rem); | |
| 269 | − | |
| 270 | 267 | if (len == 0 || erasesize == 0 || erasesize > len |
| 271 | − || erasesize > UINT_MAX || rem) { | |
| 268 | + || erasesize > UINT_MAX) { | |
| 272 | 269 | parse_err("illegal erasesize or len\n"); |
| 273 | 270 | ret = -EINVAL; |
| 274 | 271 | goto error; |
| 275 | 272 | } |
| 276 | 273 | |
| 274 | + div_u64_rem(len, (uint32_t)erasesize, &rem); | |
| 275 | + if (rem) { | |
| 276 | + parse_err("len is not multiple of erasesize\n"); | |
| 277 | + ret = -EINVAL; | |
| 278 | + goto error; | |
| 279 | + } | |
| 280 | + | |
| 277 | 281 | ret = register_device(name, start, len, (uint32_t)erasesize); |
| 278 | 282 | if (ret) |
| 279 | 283 | goto error; |
| @@ -42,7 +42,8 @@ config MTD_NAND_OMAP2 · 41 unmodified lines | ||
| 42 | 42 | tristate "OMAP2, OMAP3, OMAP4 and Keystone NAND controller" |
| 43 | 43 | depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST |
| 44 | 44 | depends on HAS_IOMEM |
| 45 | − select OMAP_GPMC if ARCH_K3 | |
| 45 | + select MEMORY | |
| 46 | + select OMAP_GPMC | |
| 46 | 47 | help |
| 47 | 48 | Support for NAND flash on Texas Instruments OMAP2, OMAP3, OMAP4 |
| 48 | 49 | and Keystone platforms. |
| @@ -2106,7 +2106,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, · 2105 unmodified lines | ||
| 2106 | 2106 | mtd->oobsize / trans, |
| 2107 | 2107 | host->hwcfg.sector_size_1k); |
| 2108 | 2108 | |
| 2109 | − if (!ret) { | |
| 2109 | + if (ret != -EBADMSG) { | |
| 2110 | 2110 | *err_addr = brcmnand_get_uncorrecc_addr(ctrl); |
| 2111 | 2111 | |
| 2112 | 2112 | if (*err_addr) |
| @@ -2285,7 +2285,7 @@ static int gpmi_nfc_exec_op(struct nand_chip *chip, · 2284 unmodified lines | ||
| 2285 | 2285 | this->hw.must_apply_timings = false; |
| 2286 | 2286 | ret = gpmi_nfc_apply_timings(this); |
| 2287 | 2287 | if (ret) |
| 2288 | − return ret; | |
| 2288 | + goto out_pm; | |
| 2289 | 2289 | } |
| 2290 | 2290 | |
| 2291 | 2291 | dev_dbg(this->dev, "%s: %d instructions\n", __func__, op->ninstrs); |
| @@ -2414,6 +2414,7 @@ unmap: · 122 unmodified lines | ||
| 2414 | 2414 | |
| 2415 | 2415 | this->bch = false; |
| 2416 | 2416 | |
| 2417 | +out_pm: | |
| 2417 | 2418 | pm_runtime_mark_last_busy(this->dev); |
| 2418 | 2419 | pm_runtime_put_autosuspend(this->dev); |
| 2419 | 2420 | |
| @@ -68,9 +68,14 @@ static struct ingenic_ecc *ingenic_ecc_get(struct device_node *np) · 67 unmodified lines | ||
| 68 | 68 | struct ingenic_ecc *ecc; |
| 69 | 69 | |
| 70 | 70 | pdev = of_find_device_by_node(np); |
| 71 | − if (!pdev || !platform_get_drvdata(pdev)) | |
| 71 | + if (!pdev) | |
| 72 | 72 | return ERR_PTR(-EPROBE_DEFER); |
| 73 | 73 | |
| 74 | + if (!platform_get_drvdata(pdev)) { | |
| 75 | + put_device(&pdev->dev); | |
| 76 | + return ERR_PTR(-EPROBE_DEFER); | |
| 77 | + } | |
| 78 | + | |
| 74 | 79 | ecc = platform_get_drvdata(pdev); |
| 75 | 80 | clk_prepare_enable(ecc->clk); |
| 76 | 81 | |
| @@ -2,7 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | /* |
| 3 | 3 | * Copyright (c) 2016, The Linux Foundation. All rights reserved. |
| 4 | 4 | */ |
| 5 | − | |
| 6 | 5 | #include <linux/clk.h> |
| 7 | 6 | #include <linux/slab.h> |
| 8 | 7 | #include <linux/bitops.h> |
| @@ -3073,10 +3072,6 @@ static int qcom_nandc_probe(struct platform_device *pdev) · 3064 unmodified lines | ||
| 3073 | 3072 | if (dma_mapping_error(dev, nandc->base_dma)) |
| 3074 | 3073 | return -ENXIO; |
| 3075 | 3074 | |
| 3076 | − ret = qcom_nandc_alloc(nandc); | |
| 3077 | − if (ret) | |
| 3078 | − goto err_nandc_alloc; | |
| 3079 | − | |
| 3080 | 3075 | ret = clk_prepare_enable(nandc->core_clk); |
| 3081 | 3076 | if (ret) |
| 3082 | 3077 | goto err_core_clk; |
| @@ -3085,6 +3080,10 @@ static int qcom_nandc_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 3085 | 3080 | if (ret) |
| 3086 | 3081 | goto err_aon_clk; |
| 3087 | 3082 | |
| 3083 | + ret = qcom_nandc_alloc(nandc); | |
| 3084 | + if (ret) | |
| 3085 | + goto err_nandc_alloc; | |
| 3086 | + | |
| 3088 | 3087 | ret = qcom_nandc_setup(nandc); |
| 3089 | 3088 | if (ret) |
| 3090 | 3089 | goto err_setup; |
| @@ -3096,15 +3095,14 @@ static int qcom_nandc_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 3096 | 3095 | return 0; |
| 3097 | 3096 | |
| 3098 | 3097 | err_setup: |
| 3098 | + qcom_nandc_unalloc(nandc); | |
| 3099 | +err_nandc_alloc: | |
| 3099 | 3100 | clk_disable_unprepare(nandc->aon_clk); |
| 3100 | 3101 | err_aon_clk: |
| 3101 | 3102 | clk_disable_unprepare(nandc->core_clk); |
| 3102 | 3103 | err_core_clk: |
| 3103 | − qcom_nandc_unalloc(nandc); | |
| 3104 | −err_nandc_alloc: | |
| 3105 | 3104 | dma_unmap_resource(dev, res->start, resource_size(res), |
| 3106 | 3105 | DMA_BIDIRECTIONAL, 0); |
| 3107 | − | |
| 3108 | 3106 | return ret; |
| 3109 | 3107 | } |
| 3110 | 3108 | |
| @@ -58,11 +58,11 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, · 57 unmodified lines | ||
| 58 | 58 | const struct mtd_partition **pparts, |
| 59 | 59 | struct mtd_part_parser_data *data) |
| 60 | 60 | { |
| 61 | + size_t len = SMEM_FLASH_PTABLE_HDR_LEN; | |
| 62 | + int ret, i, j, tmpparts, numparts = 0; | |
| 61 | 63 | struct smem_flash_pentry *pentry; |
| 62 | 64 | struct smem_flash_ptable *ptable; |
| 63 | − size_t len = SMEM_FLASH_PTABLE_HDR_LEN; | |
| 64 | 65 | struct mtd_partition *parts; |
| 65 | − int ret, i, numparts; | |
| 66 | 66 | char *name, *c; |
| 67 | 67 | |
| 68 | 68 | if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_4K_SECTORS) |
| @@ -75,7 +75,8 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, · 6 unmodified lines | ||
| 75 | 75 | pr_debug("Parsing partition table info from SMEM\n"); |
| 76 | 76 | ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len); |
| 77 | 77 | if (IS_ERR(ptable)) { |
| 78 | − pr_err("Error reading partition table header\n"); | |
| 78 | + if (PTR_ERR(ptable) != -EPROBE_DEFER) | |
| 79 | + pr_err("Error reading partition table header\n"); | |
| 79 | 80 | return PTR_ERR(ptable); |
| 80 | 81 | } |
| 81 | 82 | |
| @@ -87,8 +88,8 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, · 5 unmodified lines | ||
| 87 | 88 | } |
| 88 | 89 | |
| 89 | 90 | /* Ensure that # of partitions is less than the max we have allocated */ |
| 90 | − numparts = le32_to_cpu(ptable->numparts); | |
| 91 | − if (numparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) { | |
| 91 | + tmpparts = le32_to_cpu(ptable->numparts); | |
| 92 | + if (tmpparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) { | |
| 92 | 93 | pr_err("Partition numbers exceed the max limit\n"); |
| 93 | 94 | return -EINVAL; |
| 94 | 95 | } |
| @@ -116,11 +117,17 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, · 21 unmodified lines | ||
| 116 | 117 | return PTR_ERR(ptable); |
| 117 | 118 | } |
| 118 | 119 | |
| 120 | + for (i = 0; i < tmpparts; i++) { | |
| 121 | + pentry = &ptable->pentry[i]; | |
| 122 | + if (pentry->name[0] != '\0') | |
| 123 | + numparts++; | |
| 124 | + } | |
| 125 | + | |
| 119 | 126 | parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL); |
| 120 | 127 | if (!parts) |
| 121 | 128 | return -ENOMEM; |
| 122 | 129 | |
| 123 | − for (i = 0; i < numparts; i++) { | |
| 130 | + for (i = 0, j = 0; i < tmpparts; i++) { | |
| 124 | 131 | pentry = &ptable->pentry[i]; |
| 125 | 132 | if (pentry->name[0] == '\0') |
| 126 | 133 | continue; |
| @@ -135,24 +142,25 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, · 8 unmodified lines | ||
| 135 | 142 | for (c = name; *c != '\0'; c++) |
| 136 | 143 | *c = tolower(*c); |
| 137 | 144 | |
| 138 | − parts[i].name = name; | |
| 139 | − parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize; | |
| 140 | − parts[i].mask_flags = pentry->attr; | |
| 141 | − parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize; | |
| 145 | + parts[j].name = name; | |
| 146 | + parts[j].offset = le32_to_cpu(pentry->offset) * mtd->erasesize; | |
| 147 | + parts[j].mask_flags = pentry->attr; | |
| 148 | + parts[j].size = le32_to_cpu(pentry->length) * mtd->erasesize; | |
| 142 | 149 | pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n", |
| 143 | 150 | i, pentry->name, le32_to_cpu(pentry->offset), |
| 144 | 151 | le32_to_cpu(pentry->length), pentry->attr); |
| 152 | + j++; | |
| 145 | 153 | } |
| 146 | 154 | |
| 147 | 155 | pr_debug("SMEM partition table found: ver: %d len: %d\n", |
| 148 | − le32_to_cpu(ptable->version), numparts); | |
| 156 | + le32_to_cpu(ptable->version), tmpparts); | |
| 149 | 157 | *pparts = parts; |
| 150 | 158 | |
| 151 | 159 | return numparts; |
| 152 | 160 | |
| 153 | 161 | out_free_parts: |
| 154 | − while (--i >= 0) | |
| 155 | − kfree(parts[i].name); | |
| 162 | + while (--j >= 0) | |
| 163 | + kfree(parts[j].name); | |
| 156 | 164 | kfree(parts); |
| 157 | 165 | *pparts = NULL; |
| 158 | 166 | |
| @@ -166,6 +174,8 @@ static void parse_qcomsmem_cleanup(const struct mtd_partition *pparts, · 7 unmodified lines | ||
| 166 | 174 | |
| 167 | 175 | for (i = 0; i < nr_parts; i++) |
| 168 | 176 | kfree(pparts[i].name); |
| 177 | + | |
| 178 | + kfree(pparts); | |
| 169 | 179 | } |
| 170 | 180 | |
| 171 | 181 | static const struct of_device_id qcomsmem_of_match_table[] = { |
| @@ -26,7 +26,7 @@ void ksz_update_port_member(struct ksz_device *dev, int port) · 25 unmodified lines | ||
| 26 | 26 | struct dsa_switch *ds = dev->ds; |
| 27 | 27 | u8 port_member = 0, cpu_port; |
| 28 | 28 | const struct dsa_port *dp; |
| 29 | − int i; | |
| 29 | + int i, j; | |
| 30 | 30 | |
| 31 | 31 | if (!dsa_is_user_port(ds, port)) |
| 32 | 32 | return; |
| @@ -45,13 +45,33 @@ void ksz_update_port_member(struct ksz_device *dev, int port) · 12 unmodified lines | ||
| 45 | 45 | continue; |
| 46 | 46 | if (!dsa_port_bridge_same(dp, other_dp)) |
| 47 | 47 | continue; |
| 48 | + if (other_p->stp_state != BR_STATE_FORWARDING) | |
| 49 | + continue; | |
| 48 | 50 | |
| 49 | − if (other_p->stp_state == BR_STATE_FORWARDING && | |
| 50 | − p->stp_state == BR_STATE_FORWARDING) { | |
| 51 | + if (p->stp_state == BR_STATE_FORWARDING) { | |
| 51 | 52 | val |= BIT(port); |
| 52 | 53 | port_member |= BIT(i); |
| 53 | 54 | } |
| 54 | 55 | |
| 56 | + /* Retain port [i]'s relationship to other ports than [port] */ | |
| 57 | + for (j = 0; j < ds->num_ports; j++) { | |
| 58 | + const struct dsa_port *third_dp; | |
| 59 | + struct ksz_port *third_p; | |
| 60 | + | |
| 61 | + if (j == i) | |
| 62 | + continue; | |
| 63 | + if (j == port) | |
| 64 | + continue; | |
| 65 | + if (!dsa_is_user_port(ds, j)) | |
| 66 | + continue; | |
| 67 | + third_p = &dev->ports[j]; | |
| 68 | + if (third_p->stp_state != BR_STATE_FORWARDING) | |
| 69 | + continue; | |
| 70 | + third_dp = dsa_to_port(ds, j); | |
| 71 | + if (dsa_port_bridge_same(other_dp, third_dp)) | |
| 72 | + val |= BIT(j); | |
| 73 | + } | |
| 74 | + | |
| 55 | 75 | dev->dev_ops->cfg_port_member(dev, i, val | cpu_port); |
| 56 | 76 | } |
| 57 | 77 | |
| @@ -100,6 +100,9 @@ MODULE_LICENSE("GPL"); · 99 unmodified lines | ||
| 100 | 100 | MODULE_FIRMWARE(FW_FILE_NAME_E1); |
| 101 | 101 | MODULE_FIRMWARE(FW_FILE_NAME_E1H); |
| 102 | 102 | MODULE_FIRMWARE(FW_FILE_NAME_E2); |
| 103 | +MODULE_FIRMWARE(FW_FILE_NAME_E1_V15); | |
| 104 | +MODULE_FIRMWARE(FW_FILE_NAME_E1H_V15); | |
| 105 | +MODULE_FIRMWARE(FW_FILE_NAME_E2_V15); | |
| 103 | 106 | |
| 104 | 107 | int bnx2x_num_queues; |
| 105 | 108 | module_param_named(num_queues, bnx2x_num_queues, int, 0444); |
| @@ -4776,8 +4776,10 @@ static int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, u16 vnic_id) · 4775 unmodified lines | ||
| 4776 | 4776 | return rc; |
| 4777 | 4777 | |
| 4778 | 4778 | req->vnic_id = cpu_to_le32(vnic->fw_vnic_id); |
| 4779 | − req->num_mc_entries = cpu_to_le32(vnic->mc_list_count); | |
| 4780 | − req->mc_tbl_addr = cpu_to_le64(vnic->mc_list_mapping); | |
| 4779 | + if (vnic->rx_mask & CFA_L2_SET_RX_MASK_REQ_MASK_MCAST) { | |
| 4780 | + req->num_mc_entries = cpu_to_le32(vnic->mc_list_count); | |
| 4781 | + req->mc_tbl_addr = cpu_to_le64(vnic->mc_list_mapping); | |
| 4782 | + } | |
| 4781 | 4783 | req->mask = cpu_to_le32(vnic->rx_mask); |
| 4782 | 4784 | return hwrm_req_send_silent(bp, req); |
| 4783 | 4785 | } |
| @@ -7820,6 +7822,19 @@ static int bnxt_map_fw_health_regs(struct bnxt *bp) · 3036 unmodified lines | ||
| 7820 | 7822 | return 0; |
| 7821 | 7823 | } |
| 7822 | 7824 | |
| 7825 | +static void bnxt_remap_fw_health_regs(struct bnxt *bp) | |
| 7826 | +{ | |
| 7827 | + if (!bp->fw_health) | |
| 7828 | + return; | |
| 7829 | + | |
| 7830 | + if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) { | |
| 7831 | + bp->fw_health->status_reliable = true; | |
| 7832 | + bp->fw_health->resets_reliable = true; | |
| 7833 | + } else { | |
| 7834 | + bnxt_try_map_fw_health_reg(bp); | |
| 7835 | + } | |
| 7836 | +} | |
| 7837 | + | |
| 7823 | 7838 | static int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp) |
| 7824 | 7839 | { |
| 7825 | 7840 | struct bnxt_fw_health *fw_health = bp->fw_health; |
| @@ -8672,6 +8687,9 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init) · 846 unmodified lines | ||
| 8672 | 8687 | vnic->uc_filter_count = 1; |
| 8673 | 8688 | |
| 8674 | 8689 | vnic->rx_mask = 0; |
| 8690 | + if (test_bit(BNXT_STATE_HALF_OPEN, &bp->state)) | |
| 8691 | + goto skip_rx_mask; | |
| 8692 | + | |
| 8675 | 8693 | if (bp->dev->flags & IFF_BROADCAST) |
| 8676 | 8694 | vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_BCAST; |
| 8677 | 8695 | |
| @@ -8681,7 +8699,7 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init) · 3 unmodified lines | ||
| 8681 | 8699 | if (bp->dev->flags & IFF_ALLMULTI) { |
| 8682 | 8700 | vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; |
| 8683 | 8701 | vnic->mc_list_count = 0; |
| 8684 | − } else { | |
| 8702 | + } else if (bp->dev->flags & IFF_MULTICAST) { | |
| 8685 | 8703 | u32 mask = 0; |
| 8686 | 8704 | |
| 8687 | 8705 | bnxt_mc_list_updated(bp, &mask); |
| @@ -8692,6 +8710,7 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init) · 4 unmodified lines | ||
| 8692 | 8710 | if (rc) |
| 8693 | 8711 | goto err_out; |
| 8694 | 8712 | |
| 8713 | +skip_rx_mask: | |
| 8695 | 8714 | rc = bnxt_hwrm_set_coal(bp); |
| 8696 | 8715 | if (rc) |
| 8697 | 8716 | netdev_warn(bp->dev, "HWRM set coalescing failure rc: %x\n", |
| @@ -9883,8 +9902,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up) · 1185 unmodified lines | ||
| 9883 | 9902 | resc_reinit = true; |
| 9884 | 9903 | if (flags & FUNC_DRV_IF_CHANGE_RESP_FLAGS_HOT_FW_RESET_DONE) |
| 9885 | 9904 | fw_reset = true; |
| 9886 | − else if (bp->fw_health && !bp->fw_health->status_reliable) | |
| 9887 | − bnxt_try_map_fw_health_reg(bp); | |
| 9905 | + else | |
| 9906 | + bnxt_remap_fw_health_regs(bp); | |
| 9888 | 9907 | |
| 9889 | 9908 | if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) && !fw_reset) { |
| 9890 | 9909 | netdev_err(bp->dev, "RESET_DONE not set during FW reset.\n"); |
| @@ -10364,13 +10383,15 @@ int bnxt_half_open_nic(struct bnxt *bp) · 473 unmodified lines | ||
| 10364 | 10383 | goto half_open_err; |
| 10365 | 10384 | } |
| 10366 | 10385 | |
| 10367 | − rc = bnxt_alloc_mem(bp, false); | |
| 10386 | + rc = bnxt_alloc_mem(bp, true); | |
| 10368 | 10387 | if (rc) { |
| 10369 | 10388 | netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); |
| 10370 | 10389 | goto half_open_err; |
| 10371 | 10390 | } |
| 10372 | − rc = bnxt_init_nic(bp, false); | |
| 10391 | + set_bit(BNXT_STATE_HALF_OPEN, &bp->state); | |
| 10392 | + rc = bnxt_init_nic(bp, true); | |
| 10373 | 10393 | if (rc) { |
| 10394 | + clear_bit(BNXT_STATE_HALF_OPEN, &bp->state); | |
| 10374 | 10395 | netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc); |
| 10375 | 10396 | goto half_open_err; |
| 10376 | 10397 | } |
| @@ -10378,7 +10399,7 @@ int bnxt_half_open_nic(struct bnxt *bp) · 1 unmodified line | ||
| 10378 | 10399 | |
| 10379 | 10400 | half_open_err: |
| 10380 | 10401 | bnxt_free_skbs(bp); |
| 10381 | − bnxt_free_mem(bp, false); | |
| 10402 | + bnxt_free_mem(bp, true); | |
| 10382 | 10403 | dev_close(bp->dev); |
| 10383 | 10404 | return rc; |
| 10384 | 10405 | } |
| @@ -10388,9 +10409,10 @@ half_open_err: · 3 unmodified lines | ||
| 10388 | 10409 | */ |
| 10389 | 10410 | void bnxt_half_close_nic(struct bnxt *bp) |
| 10390 | 10411 | { |
| 10391 | − bnxt_hwrm_resource_free(bp, false, false); | |
| 10412 | + bnxt_hwrm_resource_free(bp, false, true); | |
| 10392 | 10413 | bnxt_free_skbs(bp); |
| 10393 | − bnxt_free_mem(bp, false); | |
| 10414 | + bnxt_free_mem(bp, true); | |
| 10415 | + clear_bit(BNXT_STATE_HALF_OPEN, &bp->state); | |
| 10394 | 10416 | } |
| 10395 | 10417 | |
| 10396 | 10418 | void bnxt_reenable_sriov(struct bnxt *bp) |
| @@ -10806,7 +10828,7 @@ static void bnxt_set_rx_mode(struct net_device *dev) · 409 unmodified lines | ||
| 10806 | 10828 | if (dev->flags & IFF_ALLMULTI) { |
| 10807 | 10829 | mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; |
| 10808 | 10830 | vnic->mc_list_count = 0; |
| 10809 | − } else { | |
| 10831 | + } else if (dev->flags & IFF_MULTICAST) { | |
| 10810 | 10832 | mc_update = bnxt_mc_list_updated(bp, &mask); |
| 10811 | 10833 | } |
| 10812 | 10834 | |
| @@ -10883,9 +10905,10 @@ skip_uc: · 70 unmodified lines | ||
| 10883 | 10905 | !bnxt_promisc_ok(bp)) |
| 10884 | 10906 | vnic->rx_mask &= ~CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS; |
| 10885 | 10907 | rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0); |
| 10886 | − if (rc && vnic->mc_list_count) { | |
| 10908 | + if (rc && (vnic->rx_mask & CFA_L2_SET_RX_MASK_REQ_MASK_MCAST)) { | |
| 10887 | 10909 | netdev_info(bp->dev, "Failed setting MC filters rc: %d, turning on ALL_MCAST mode\n", |
| 10888 | 10910 | rc); |
| 10911 | + vnic->rx_mask &= ~CFA_L2_SET_RX_MASK_REQ_MASK_MCAST; | |
| 10889 | 10912 | vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; |
| 10890 | 10913 | vnic->mc_list_count = 0; |
| 10891 | 10914 | rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0); |
| @@ -1921,6 +1921,7 @@ struct bnxt { · 1920 unmodified lines | ||
| 1921 | 1921 | #define BNXT_STATE_RECOVER 12 |
| 1922 | 1922 | #define BNXT_STATE_FW_NON_FATAL_COND 13 |
| 1923 | 1923 | #define BNXT_STATE_FW_ACTIVATE_RESET 14 |
| 1924 | +#define BNXT_STATE_HALF_OPEN 15 /* For offline ethtool tests */ | |
| 1924 | 1925 | |
| 1925 | 1926 | #define BNXT_NO_FW_ACCESS(bp) \ |
| 1926 | 1927 | (test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state) || \ |
| @@ -367,6 +367,16 @@ bnxt_dl_livepatch_report_err(struct bnxt *bp, struct netlink_ext_ack *extack, · 366 unmodified lines | ||
| 367 | 367 | } |
| 368 | 368 | } |
| 369 | 369 | |
| 370 | +/* Live patch status in NVM */ | |
| 371 | +#define BNXT_LIVEPATCH_NOT_INSTALLED 0 | |
| 372 | +#define BNXT_LIVEPATCH_INSTALLED FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL | |
| 373 | +#define BNXT_LIVEPATCH_REMOVED FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE | |
| 374 | +#define BNXT_LIVEPATCH_MASK (FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL | \ | |
| 375 | + FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE) | |
| 376 | +#define BNXT_LIVEPATCH_ACTIVATED BNXT_LIVEPATCH_MASK | |
| 377 | + | |
| 378 | +#define BNXT_LIVEPATCH_STATE(flags) ((flags) & BNXT_LIVEPATCH_MASK) | |
| 379 | + | |
| 370 | 380 | static int |
| 371 | 381 | bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack) |
| 372 | 382 | { |
| @@ -374,8 +384,9 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack) · 1 unmodified line | ||
| 374 | 384 | struct hwrm_fw_livepatch_query_input *query_req; |
| 375 | 385 | struct hwrm_fw_livepatch_output *patch_resp; |
| 376 | 386 | struct hwrm_fw_livepatch_input *patch_req; |
| 387 | + u16 flags, live_patch_state; | |
| 388 | + bool activated = false; | |
| 377 | 389 | u32 installed = 0; |
| 378 | − u16 flags; | |
| 379 | 390 | u8 target; |
| 380 | 391 | int rc; |
| 381 | 392 | |
| @@ -394,7 +405,6 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack) · 12 unmodified lines | ||
| 394 | 405 | hwrm_req_drop(bp, query_req); |
| 395 | 406 | return rc; |
| 396 | 407 | } |
| 397 | − patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_ACTIVATE; | |
| 398 | 408 | patch_req->loadtype = FW_LIVEPATCH_REQ_LOADTYPE_NVM_INSTALL; |
| 399 | 409 | patch_resp = hwrm_req_hold(bp, patch_req); |
| 400 | 410 | |
| @@ -407,12 +417,20 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack) · 6 unmodified lines | ||
| 407 | 417 | } |
| 408 | 418 | |
| 409 | 419 | flags = le16_to_cpu(query_resp->status_flags); |
| 410 | − if (~flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL) | |
| 420 | + live_patch_state = BNXT_LIVEPATCH_STATE(flags); | |
| 421 | + | |
| 422 | + if (live_patch_state == BNXT_LIVEPATCH_NOT_INSTALLED) | |
| 411 | 423 | continue; |
| 412 | − if ((flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE) && | |
| 413 | − !strncmp(query_resp->active_ver, query_resp->install_ver, | |
| 414 | − sizeof(query_resp->active_ver))) | |
| 424 | + | |
| 425 | + if (live_patch_state == BNXT_LIVEPATCH_ACTIVATED) { | |
| 426 | + activated = true; | |
| 415 | 427 | continue; |
| 428 | + } | |
| 429 | + | |
| 430 | + if (live_patch_state == BNXT_LIVEPATCH_INSTALLED) | |
| 431 | + patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_ACTIVATE; | |
| 432 | + else if (live_patch_state == BNXT_LIVEPATCH_REMOVED) | |
| 433 | + patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_DEACTIVATE; | |
| 416 | 434 | |
| 417 | 435 | patch_req->fw_target = target; |
| 418 | 436 | rc = hwrm_req_send(bp, patch_req); |
| @@ -424,8 +442,13 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack) · 5 unmodified lines | ||
| 424 | 442 | } |
| 425 | 443 | |
| 426 | 444 | if (!rc && !installed) { |
| 427 | − NL_SET_ERR_MSG_MOD(extack, "No live patches found"); | |
| 428 | − rc = -ENOENT; | |
| 445 | + if (activated) { | |
| 446 | + NL_SET_ERR_MSG_MOD(extack, "Live patch already activated"); | |
| 447 | + rc = -EEXIST; | |
| 448 | + } else { | |
| 449 | + NL_SET_ERR_MSG_MOD(extack, "No live patches found"); | |
| 450 | + rc = -ENOENT; | |
| 451 | + } | |
| 429 | 452 | } |
| 430 | 453 | hwrm_req_drop(bp, query_req); |
| 431 | 454 | hwrm_req_drop(bp, patch_req); |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include "bnxt_hsi.h" |
| 27 | 27 | #include "bnxt.h" |
| 28 | 28 | #include "bnxt_hwrm.h" |
| 29 | +#include "bnxt_ulp.h" | |
| 29 | 30 | #include "bnxt_xdp.h" |
| 30 | 31 | #include "bnxt_ptp.h" |
| 31 | 32 | #include "bnxt_ethtool.h" |
| @@ -1972,6 +1973,9 @@ static int bnxt_get_fecparam(struct net_device *dev, · 1940 unmodified lines | ||
| 1972 | 1973 | case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE: |
| 1973 | 1974 | fec->active_fec |= ETHTOOL_FEC_LLRS; |
| 1974 | 1975 | break; |
| 1976 | + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_NONE_ACTIVE: | |
| 1977 | + fec->active_fec |= ETHTOOL_FEC_OFF; | |
| 1978 | + break; | |
| 1975 | 1979 | } |
| 1976 | 1980 | return 0; |
| 1977 | 1981 | } |
| @@ -3457,7 +3461,7 @@ static int bnxt_run_loopback(struct bnxt *bp) · 1479 unmodified lines | ||
| 3457 | 3461 | if (!skb) |
| 3458 | 3462 | return -ENOMEM; |
| 3459 | 3463 | data = skb_put(skb, pkt_size); |
| 3460 | − eth_broadcast_addr(data); | |
| 3464 | + ether_addr_copy(&data[i], bp->dev->dev_addr); | |
| 3461 | 3465 | i += ETH_ALEN; |
| 3462 | 3466 | ether_addr_copy(&data[i], bp->dev->dev_addr); |
| 3463 | 3467 | i += ETH_ALEN; |
| @@ -3551,9 +3555,12 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, · 87 unmodified lines | ||
| 3551 | 3555 | if (!offline) { |
| 3552 | 3556 | bnxt_run_fw_tests(bp, test_mask, &test_results); |
| 3553 | 3557 | } else { |
| 3554 | − rc = bnxt_close_nic(bp, false, false); | |
| 3555 | − if (rc) | |
| 3558 | + bnxt_ulp_stop(bp); | |
| 3559 | + rc = bnxt_close_nic(bp, true, false); | |
| 3560 | + if (rc) { | |
| 3561 | + bnxt_ulp_start(bp, rc); | |
| 3556 | 3562 | return; |
| 3563 | + } | |
| 3557 | 3564 | bnxt_run_fw_tests(bp, test_mask, &test_results); |
| 3558 | 3565 | |
| 3559 | 3566 | buf[BNXT_MACLPBK_TEST_IDX] = 1; |
| @@ -3563,6 +3570,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, · 3 unmodified lines | ||
| 3563 | 3570 | if (rc) { |
| 3564 | 3571 | bnxt_hwrm_mac_loopback(bp, false); |
| 3565 | 3572 | etest->flags |= ETH_TEST_FL_FAILED; |
| 3573 | + bnxt_ulp_start(bp, rc); | |
| 3566 | 3574 | return; |
| 3567 | 3575 | } |
| 3568 | 3576 | if (bnxt_run_loopback(bp)) |
| @@ -3588,7 +3596,8 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, · 19 unmodified lines | ||
| 3588 | 3596 | } |
| 3589 | 3597 | bnxt_hwrm_phy_loopback(bp, false, false); |
| 3590 | 3598 | bnxt_half_close_nic(bp); |
| 3591 | − rc = bnxt_open_nic(bp, false, true); | |
| 3599 | + rc = bnxt_open_nic(bp, true, true); | |
| 3600 | + bnxt_ulp_start(bp, rc); | |
| 3592 | 3601 | } |
| 3593 | 3602 | if (rc || bnxt_test_irq(bp)) { |
| 3594 | 3603 | buf[BNXT_IRQ_TEST_IDX] = 1; |
| @@ -644,17 +644,23 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx) · 643 unmodified lines | ||
| 644 | 644 | |
| 645 | 645 | /* Last byte of resp contains valid bit */ |
| 646 | 646 | valid = ((u8 *)ctx->resp) + len - 1; |
| 647 | − for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; j++) { | |
| 647 | + for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; ) { | |
| 648 | 648 | /* make sure we read from updated DMA memory */ |
| 649 | 649 | dma_rmb(); |
| 650 | 650 | if (*valid) |
| 651 | 651 | break; |
| 652 | − usleep_range(1, 5); | |
| 652 | + if (j < 10) { | |
| 653 | + udelay(1); | |
| 654 | + j++; | |
| 655 | + } else { | |
| 656 | + usleep_range(20, 30); | |
| 657 | + j += 20; | |
| 658 | + } | |
| 653 | 659 | } |
| 654 | 660 | |
| 655 | 661 | if (j >= HWRM_VALID_BIT_DELAY_USEC) { |
| 656 | 662 | hwrm_err(bp, ctx, "Error (timeout: %u) msg {0x%x 0x%x} len:%d v:%d\n", |
| 657 | − hwrm_total_timeout(i), req_type, | |
| 663 | + hwrm_total_timeout(i) + j, req_type, | |
| 658 | 664 | le16_to_cpu(ctx->req->seq_id), len, *valid); |
| 659 | 665 | goto exit; |
| 660 | 666 | } |
| @@ -90,7 +90,7 @@ static inline unsigned int hwrm_total_timeout(unsigned int n) · 89 unmodified lines | ||
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | |
| 93 | −#define HWRM_VALID_BIT_DELAY_USEC 150 | |
| 93 | +#define HWRM_VALID_BIT_DELAY_USEC 50000 | |
| 94 | 94 | |
| 95 | 95 | static inline bool bnxt_cfa_hwrm_message(u16 req_type) |
| 96 | 96 | { |
| @@ -989,117 +989,6 @@ static int ftgmac100_alloc_rx_buffers(struct ftgmac100 *priv) · 988 unmodified lines | ||
| 989 | 989 | return 0; |
| 990 | 990 | } |
| 991 | 991 | |
| 992 | −static void ftgmac100_adjust_link(struct net_device *netdev) | |
| 993 | −{ | |
| 994 | − struct ftgmac100 *priv = netdev_priv(netdev); | |
| 995 | − struct phy_device *phydev = netdev->phydev; | |
| 996 | − bool tx_pause, rx_pause; | |
| 997 | − int new_speed; | |
| 998 | − | |
| 999 | − /* We store "no link" as speed 0 */ | |
| 1000 | − if (!phydev->link) | |
| 1001 | − new_speed = 0; | |
| 1002 | − else | |
| 1003 | − new_speed = phydev->speed; | |
| 1004 | − | |
| 1005 | − /* Grab pause settings from PHY if configured to do so */ | |
| 1006 | − if (priv->aneg_pause) { | |
| 1007 | − rx_pause = tx_pause = phydev->pause; | |
| 1008 | − if (phydev->asym_pause) | |
| 1009 | − tx_pause = !rx_pause; | |
| 1010 | − } else { | |
| 1011 | − rx_pause = priv->rx_pause; | |
| 1012 | − tx_pause = priv->tx_pause; | |
| 1013 | − } | |
| 1014 | − | |
| 1015 | − /* Link hasn't changed, do nothing */ | |
| 1016 | − if (phydev->speed == priv->cur_speed && | |
| 1017 | − phydev->duplex == priv->cur_duplex && | |
| 1018 | − rx_pause == priv->rx_pause && | |
| 1019 | − tx_pause == priv->tx_pause) | |
| 1020 | − return; | |
| 1021 | − | |
| 1022 | − /* Print status if we have a link or we had one and just lost it, | |
| 1023 | − * don't print otherwise. | |
| 1024 | − */ | |
| 1025 | − if (new_speed || priv->cur_speed) | |
| 1026 | − phy_print_status(phydev); | |
| 1027 | − | |
| 1028 | − priv->cur_speed = new_speed; | |
| 1029 | − priv->cur_duplex = phydev->duplex; | |
| 1030 | − priv->rx_pause = rx_pause; | |
| 1031 | − priv->tx_pause = tx_pause; | |
| 1032 | − | |
| 1033 | − /* Link is down, do nothing else */ | |
| 1034 | − if (!new_speed) | |
| 1035 | − return; | |
| 1036 | − | |
| 1037 | − /* Disable all interrupts */ | |
| 1038 | − iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); | |
| 1039 | − | |
| 1040 | − /* Reset the adapter asynchronously */ | |
| 1041 | − schedule_work(&priv->reset_task); | |
| 1042 | −} | |
| 1043 | − | |
| 1044 | −static int ftgmac100_mii_probe(struct net_device *netdev) | |
| 1045 | −{ | |
| 1046 | − struct ftgmac100 *priv = netdev_priv(netdev); | |
| 1047 | − struct platform_device *pdev = to_platform_device(priv->dev); | |
| 1048 | − struct device_node *np = pdev->dev.of_node; | |
| 1049 | − struct phy_device *phydev; | |
| 1050 | − phy_interface_t phy_intf; | |
| 1051 | − int err; | |
| 1052 | − | |
| 1053 | − /* Default to RGMII. It's a gigabit part after all */ | |
| 1054 | − err = of_get_phy_mode(np, &phy_intf); | |
| 1055 | − if (err) | |
| 1056 | − phy_intf = PHY_INTERFACE_MODE_RGMII; | |
| 1057 | − | |
| 1058 | − /* Aspeed only supports these. I don't know about other IP | |
| 1059 | − * block vendors so I'm going to just let them through for | |
| 1060 | − * now. Note that this is only a warning if for some obscure | |
| 1061 | − * reason the DT really means to lie about it or it's a newer | |
| 1062 | − * part we don't know about. | |
| 1063 | − * | |
| 1064 | − * On the Aspeed SoC there are additionally straps and SCU | |
| 1065 | − * control bits that could tell us what the interface is | |
| 1066 | − * (or allow us to configure it while the IP block is held | |
| 1067 | − * in reset). For now I chose to keep this driver away from | |
| 1068 | − * those SoC specific bits and assume the device-tree is | |
| 1069 | − * right and the SCU has been configured properly by pinmux | |
| 1070 | − * or the firmware. | |
| 1071 | − */ | |
| 1072 | − if (priv->is_aspeed && !(phy_interface_mode_is_rgmii(phy_intf))) { | |
| 1073 | − netdev_warn(netdev, | |
| 1074 | − "Unsupported PHY mode %s !\n", | |
| 1075 | − phy_modes(phy_intf)); | |
| 1076 | − } | |
| 1077 | − | |
| 1078 | − phydev = phy_find_first(priv->mii_bus); | |
| 1079 | − if (!phydev) { | |
| 1080 | − netdev_info(netdev, "%s: no PHY found\n", netdev->name); | |
| 1081 | − return -ENODEV; | |
| 1082 | − } | |
| 1083 | − | |
| 1084 | − phydev = phy_connect(netdev, phydev_name(phydev), | |
| 1085 | − &ftgmac100_adjust_link, phy_intf); | |
| 1086 | − | |
| 1087 | − if (IS_ERR(phydev)) { | |
| 1088 | − netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name); | |
| 1089 | − return PTR_ERR(phydev); | |
| 1090 | − } | |
| 1091 | − | |
| 1092 | − /* Indicate that we support PAUSE frames (see comment in | |
| 1093 | − * Documentation/networking/phy.rst) | |
| 1094 | − */ | |
| 1095 | − phy_support_asym_pause(phydev); | |
| 1096 | − | |
| 1097 | − /* Display what we found */ | |
| 1098 | − phy_attached_info(phydev); | |
| 1099 | − | |
| 1100 | − return 0; | |
| 1101 | −} | |
| 1102 | − | |
| 1103 | 992 | static int ftgmac100_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) |
| 1104 | 993 | { |
| 1105 | 994 | struct net_device *netdev = bus->priv; |
| @@ -1410,10 +1299,8 @@ static int ftgmac100_init_all(struct ftgmac100 *priv, bool ignore_alloc_err) · 304 unmodified lines | ||
| 1410 | 1299 | return err; |
| 1411 | 1300 | } |
| 1412 | 1301 | |
| 1413 | −static void ftgmac100_reset_task(struct work_struct *work) | |
| 1302 | +static void ftgmac100_reset(struct ftgmac100 *priv) | |
| 1414 | 1303 | { |
| 1415 | − struct ftgmac100 *priv = container_of(work, struct ftgmac100, | |
| 1416 | − reset_task); | |
| 1417 | 1304 | struct net_device *netdev = priv->netdev; |
| 1418 | 1305 | int err; |
| 1419 | 1306 | |
| @@ -1459,6 +1346,134 @@ static void ftgmac100_reset_task(struct work_struct *work) · 39 unmodified lines | ||
| 1459 | 1346 | rtnl_unlock(); |
| 1460 | 1347 | } |
| 1461 | 1348 | |
| 1349 | +static void ftgmac100_reset_task(struct work_struct *work) | |
| 1350 | +{ | |
| 1351 | + struct ftgmac100 *priv = container_of(work, struct ftgmac100, | |
| 1352 | + reset_task); | |
| 1353 | + | |
| 1354 | + ftgmac100_reset(priv); | |
| 1355 | +} | |
| 1356 | + | |
| 1357 | +static void ftgmac100_adjust_link(struct net_device *netdev) | |
| 1358 | +{ | |
| 1359 | + struct ftgmac100 *priv = netdev_priv(netdev); | |
| 1360 | + struct phy_device *phydev = netdev->phydev; | |
| 1361 | + bool tx_pause, rx_pause; | |
| 1362 | + int new_speed; | |
| 1363 | + | |
| 1364 | + /* We store "no link" as speed 0 */ | |
| 1365 | + if (!phydev->link) | |
| 1366 | + new_speed = 0; | |
| 1367 | + else | |
| 1368 | + new_speed = phydev->speed; | |
| 1369 | + | |
| 1370 | + /* Grab pause settings from PHY if configured to do so */ | |
| 1371 | + if (priv->aneg_pause) { | |
| 1372 | + rx_pause = tx_pause = phydev->pause; | |
| 1373 | + if (phydev->asym_pause) | |
| 1374 | + tx_pause = !rx_pause; | |
| 1375 | + } else { | |
| 1376 | + rx_pause = priv->rx_pause; | |
| 1377 | + tx_pause = priv->tx_pause; | |
| 1378 | + } | |
| 1379 | + | |
| 1380 | + /* Link hasn't changed, do nothing */ | |
| 1381 | + if (phydev->speed == priv->cur_speed && | |
| 1382 | + phydev->duplex == priv->cur_duplex && | |
| 1383 | + rx_pause == priv->rx_pause && | |
| 1384 | + tx_pause == priv->tx_pause) | |
| 1385 | + return; | |
| 1386 | + | |
| 1387 | + /* Print status if we have a link or we had one and just lost it, | |
| 1388 | + * don't print otherwise. | |
| 1389 | + */ | |
| 1390 | + if (new_speed || priv->cur_speed) | |
| 1391 | + phy_print_status(phydev); | |
| 1392 | + | |
| 1393 | + priv->cur_speed = new_speed; | |
| 1394 | + priv->cur_duplex = phydev->duplex; | |
| 1395 | + priv->rx_pause = rx_pause; | |
| 1396 | + priv->tx_pause = tx_pause; | |
| 1397 | + | |
| 1398 | + /* Link is down, do nothing else */ | |
| 1399 | + if (!new_speed) | |
| 1400 | + return; | |
| 1401 | + | |
| 1402 | + /* Disable all interrupts */ | |
| 1403 | + iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); | |
| 1404 | + | |
| 1405 | + /* Release phy lock to allow ftgmac100_reset to aquire it, keeping lock | |
| 1406 | + * order consistent to prevent dead lock. | |
| 1407 | + */ | |
| 1408 | + if (netdev->phydev) | |
| 1409 | + mutex_unlock(&netdev->phydev->lock); | |
| 1410 | + | |
| 1411 | + ftgmac100_reset(priv); | |
| 1412 | + | |
| 1413 | + if (netdev->phydev) | |
| 1414 | + mutex_lock(&netdev->phydev->lock); | |
| 1415 | + | |
| 1416 | +} | |
| 1417 | + | |
| 1418 | +static int ftgmac100_mii_probe(struct net_device *netdev) | |
| 1419 | +{ | |
| 1420 | + struct ftgmac100 *priv = netdev_priv(netdev); | |
| 1421 | + struct platform_device *pdev = to_platform_device(priv->dev); | |
| 1422 | + struct device_node *np = pdev->dev.of_node; | |
| 1423 | + struct phy_device *phydev; | |
| 1424 | + phy_interface_t phy_intf; | |
| 1425 | + int err; | |
| 1426 | + | |
| 1427 | + /* Default to RGMII. It's a gigabit part after all */ | |
| 1428 | + err = of_get_phy_mode(np, &phy_intf); | |
| 1429 | + if (err) | |
| 1430 | + phy_intf = PHY_INTERFACE_MODE_RGMII; | |
| 1431 | + | |
| 1432 | + /* Aspeed only supports these. I don't know about other IP | |
| 1433 | + * block vendors so I'm going to just let them through for | |
| 1434 | + * now. Note that this is only a warning if for some obscure | |
| 1435 | + * reason the DT really means to lie about it or it's a newer | |
| 1436 | + * part we don't know about. | |
| 1437 | + * | |
| 1438 | + * On the Aspeed SoC there are additionally straps and SCU | |
| 1439 | + * control bits that could tell us what the interface is | |
| 1440 | + * (or allow us to configure it while the IP block is held | |
| 1441 | + * in reset). For now I chose to keep this driver away from | |
| 1442 | + * those SoC specific bits and assume the device-tree is | |
| 1443 | + * right and the SCU has been configured properly by pinmux | |
| 1444 | + * or the firmware. | |
| 1445 | + */ | |
| 1446 | + if (priv->is_aspeed && !(phy_interface_mode_is_rgmii(phy_intf))) { | |
| 1447 | + netdev_warn(netdev, | |
| 1448 | + "Unsupported PHY mode %s !\n", | |
| 1449 | + phy_modes(phy_intf)); | |
| 1450 | + } | |
| 1451 | + | |
| 1452 | + phydev = phy_find_first(priv->mii_bus); | |
| 1453 | + if (!phydev) { | |
| 1454 | + netdev_info(netdev, "%s: no PHY found\n", netdev->name); | |
| 1455 | + return -ENODEV; | |
| 1456 | + } | |
| 1457 | + | |
| 1458 | + phydev = phy_connect(netdev, phydev_name(phydev), | |
| 1459 | + &ftgmac100_adjust_link, phy_intf); | |
| 1460 | + | |
| 1461 | + if (IS_ERR(phydev)) { | |
| 1462 | + netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name); | |
| 1463 | + return PTR_ERR(phydev); | |
| 1464 | + } | |
| 1465 | + | |
| 1466 | + /* Indicate that we support PAUSE frames (see comment in | |
| 1467 | + * Documentation/networking/phy.rst) | |
| 1468 | + */ | |
| 1469 | + phy_support_asym_pause(phydev); | |
| 1470 | + | |
| 1471 | + /* Display what we found */ | |
| 1472 | + phy_attached_info(phydev); | |
| 1473 | + | |
| 1474 | + return 0; | |
| 1475 | +} | |
| 1476 | + | |
| 1462 | 1477 | static int ftgmac100_open(struct net_device *netdev) |
| 1463 | 1478 | { |
| 1464 | 1479 | struct ftgmac100 *priv = netdev_priv(netdev); |
| @@ -5934,10 +5934,14 @@ static ssize_t failover_store(struct device *dev, struct device_attribute *attr, · 5933 unmodified lines | ||
| 5934 | 5934 | be64_to_cpu(session_token)); |
| 5935 | 5935 | rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address, |
| 5936 | 5936 | H_SESSION_ERR_DETECTED, session_token, 0, 0); |
| 5937 | − if (rc) | |
| 5937 | + if (rc) { | |
| 5938 | 5938 | netdev_err(netdev, |
| 5939 | 5939 | "H_VIOCTL initiated failover failed, rc %ld\n", |
| 5940 | 5940 | rc); |
| 5941 | + goto last_resort; | |
| 5942 | + } | |
| 5943 | + | |
| 5944 | + return count; | |
| 5941 | 5945 | |
| 5942 | 5946 | last_resort: |
| 5943 | 5947 | netdev_dbg(netdev, "Trying to send CRQ_CMD, the last resort\n"); |
| @@ -5386,15 +5386,7 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc, · 5385 unmodified lines | ||
| 5386 | 5386 | /* There is no need to reset BW when mqprio mode is on. */ |
| 5387 | 5387 | if (pf->flags & I40E_FLAG_TC_MQPRIO) |
| 5388 | 5388 | return 0; |
| 5389 | − | |
| 5390 | − if (!vsi->mqprio_qopt.qopt.hw) { | |
| 5391 | − if (pf->flags & I40E_FLAG_DCB_ENABLED) | |
| 5392 | − goto skip_reset; | |
| 5393 | − | |
| 5394 | − if (IS_ENABLED(CONFIG_I40E_DCB) && | |
| 5395 | − i40e_dcb_hw_get_num_tc(&pf->hw) == 1) | |
| 5396 | − goto skip_reset; | |
| 5397 | − | |
| 5389 | + if (!vsi->mqprio_qopt.qopt.hw && !(pf->flags & I40E_FLAG_DCB_ENABLED)) { | |
| 5398 | 5390 | ret = i40e_set_bw_limit(vsi, vsi->seid, 0); |
| 5399 | 5391 | if (ret) |
| 5400 | 5392 | dev_info(&pf->pdev->dev, |
| @@ -5402,8 +5394,6 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc, · 1 unmodified line | ||
| 5402 | 5394 | vsi->seid); |
| 5403 | 5395 | return ret; |
| 5404 | 5396 | } |
| 5405 | − | |
| 5406 | −skip_reset: | |
| 5407 | 5397 | memset(&bw_data, 0, sizeof(bw_data)); |
| 5408 | 5398 | bw_data.tc_valid_bits = enabled_tc; |
| 5409 | 5399 | for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) |
| @@ -281,7 +281,6 @@ enum ice_pf_state { · 280 unmodified lines | ||
| 281 | 281 | ICE_VFLR_EVENT_PENDING, |
| 282 | 282 | ICE_FLTR_OVERFLOW_PROMISC, |
| 283 | 283 | ICE_VF_DIS, |
| 284 | − ICE_VF_DEINIT_IN_PROGRESS, | |
| 285 | 284 | ICE_CFG_BUSY, |
| 286 | 285 | ICE_SERVICE_SCHED, |
| 287 | 286 | ICE_SERVICE_DIS, |
| @@ -3379,7 +3379,7 @@ ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg, · 3378 unmodified lines | ||
| 3379 | 3379 | |
| 3380 | 3380 | if (fec == ICE_FEC_AUTO && ice_fw_supports_link_override(hw) && |
| 3381 | 3381 | !ice_fw_supports_report_dflt_cfg(hw)) { |
| 3382 | − struct ice_link_default_override_tlv tlv; | |
| 3382 | + struct ice_link_default_override_tlv tlv = { 0 }; | |
| 3383 | 3383 | |
| 3384 | 3384 | status = ice_get_link_default_override(&tlv, pi); |
| 3385 | 3385 | if (status) |
| @@ -44,6 +44,7 @@ ice_eswitch_add_vf_mac_rule(struct ice_pf *pf, struct ice_vf *vf, const u8 *mac) · 43 unmodified lines | ||
| 44 | 44 | ctrl_vsi->rxq_map[vf->vf_id]; |
| 45 | 45 | rule_info.flags_info.act |= ICE_SINGLE_ACT_LB_ENABLE; |
| 46 | 46 | rule_info.flags_info.act_valid = true; |
| 47 | + rule_info.tun_type = ICE_SW_TUN_AND_NON_TUN; | |
| 47 | 48 | |
| 48 | 49 | err = ice_add_adv_rule(hw, list, lkups_cnt, &rule_info, |
| 49 | 50 | vf->repr->mac_rule); |
| @@ -1802,7 +1802,9 @@ static void ice_handle_mdd_event(struct ice_pf *pf) · 1801 unmodified lines | ||
| 1802 | 1802 | * reset, so print the event prior to reset. |
| 1803 | 1803 | */ |
| 1804 | 1804 | ice_print_vf_rx_mdd_event(vf); |
| 1805 | + mutex_lock(&pf->vf[i].cfg_lock); | |
| 1805 | 1806 | ice_reset_vf(&pf->vf[i], false); |
| 1807 | + mutex_unlock(&pf->vf[i].cfg_lock); | |
| 1806 | 1808 | } |
| 1807 | 1809 | } |
| 1808 | 1810 | } |
| @@ -47,6 +47,7 @@ enum ice_protocol_type { · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | enum ice_sw_tunnel_type { |
| 49 | 49 | ICE_NON_TUN = 0, |
| 50 | + ICE_SW_TUN_AND_NON_TUN, | |
| 50 | 51 | ICE_SW_TUN_VXLAN, |
| 51 | 52 | ICE_SW_TUN_GENEVE, |
| 52 | 53 | ICE_SW_TUN_NVGRE, |
| @@ -1533,9 +1533,12 @@ exit: · 1532 unmodified lines | ||
| 1533 | 1533 | static int ice_ptp_adjtime_nonatomic(struct ptp_clock_info *info, s64 delta) |
| 1534 | 1534 | { |
| 1535 | 1535 | struct timespec64 now, then; |
| 1536 | + int ret; | |
| 1536 | 1537 | |
| 1537 | 1538 | then = ns_to_timespec64(delta); |
| 1538 | − ice_ptp_gettimex64(info, &now, NULL); | |
| 1539 | + ret = ice_ptp_gettimex64(info, &now, NULL); | |
| 1540 | + if (ret) | |
| 1541 | + return ret; | |
| 1539 | 1542 | now = timespec64_add(now, then); |
| 1540 | 1543 | |
| 1541 | 1544 | return ice_ptp_settime64(info, (const struct timespec64 *)&now); |
| @@ -4617,6 +4617,7 @@ ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, · 4616 unmodified lines | ||
| 4617 | 4617 | case ICE_SW_TUN_NVGRE: |
| 4618 | 4618 | prof_type = ICE_PROF_TUN_GRE; |
| 4619 | 4619 | break; |
| 4620 | + case ICE_SW_TUN_AND_NON_TUN: | |
| 4620 | 4621 | default: |
| 4621 | 4622 | prof_type = ICE_PROF_ALL; |
| 4622 | 4623 | break; |
| @@ -5385,7 +5386,8 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, · 762 unmodified lines | ||
| 5385 | 5386 | if (status) |
| 5386 | 5387 | goto err_ice_add_adv_rule; |
| 5387 | 5388 | |
| 5388 | − if (rinfo->tun_type != ICE_NON_TUN) { | |
| 5389 | + if (rinfo->tun_type != ICE_NON_TUN && | |
| 5390 | + rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) { | |
| 5389 | 5391 | status = ice_fill_adv_packet_tun(hw, rinfo->tun_type, |
| 5390 | 5392 | s_rule->pdata.lkup_tx_rx.hdr, |
| 5391 | 5393 | pkt_offsets); |
| @@ -709,7 +709,7 @@ ice_tc_set_port(struct flow_match_ports match, · 708 unmodified lines | ||
| 709 | 709 | fltr->flags |= ICE_TC_FLWR_FIELD_ENC_DEST_L4_PORT; |
| 710 | 710 | else |
| 711 | 711 | fltr->flags |= ICE_TC_FLWR_FIELD_DEST_L4_PORT; |
| 712 | − fltr->flags |= ICE_TC_FLWR_FIELD_DEST_L4_PORT; | |
| 712 | + | |
| 713 | 713 | headers->l4_key.dst_port = match.key->dst; |
| 714 | 714 | headers->l4_mask.dst_port = match.mask->dst; |
| 715 | 715 | } |
| @@ -718,7 +718,7 @@ ice_tc_set_port(struct flow_match_ports match, · 2 unmodified lines | ||
| 718 | 718 | fltr->flags |= ICE_TC_FLWR_FIELD_ENC_SRC_L4_PORT; |
| 719 | 719 | else |
| 720 | 720 | fltr->flags |= ICE_TC_FLWR_FIELD_SRC_L4_PORT; |
| 721 | − fltr->flags |= ICE_TC_FLWR_FIELD_SRC_L4_PORT; | |
| 721 | + | |
| 722 | 722 | headers->l4_key.src_port = match.key->src; |
| 723 | 723 | headers->l4_mask.src_port = match.mask->src; |
| 724 | 724 | } |
| @@ -502,8 +502,6 @@ void ice_free_vfs(struct ice_pf *pf) · 501 unmodified lines | ||
| 502 | 502 | struct ice_hw *hw = &pf->hw; |
| 503 | 503 | unsigned int tmp, i; |
| 504 | 504 | |
| 505 | − set_bit(ICE_VF_DEINIT_IN_PROGRESS, pf->state); | |
| 506 | − | |
| 507 | 505 | if (!pf->vf) |
| 508 | 506 | return; |
| 509 | 507 | |
| @@ -521,22 +519,26 @@ void ice_free_vfs(struct ice_pf *pf) · 11 unmodified lines | ||
| 521 | 519 | else |
| 522 | 520 | dev_warn(dev, "VFs are assigned - not disabling SR-IOV\n"); |
| 523 | 521 | |
| 524 | − /* Avoid wait time by stopping all VFs at the same time */ | |
| 525 | − ice_for_each_vf(pf, i) | |
| 526 | − ice_dis_vf_qs(&pf->vf[i]); | |
| 527 | − | |
| 528 | 522 | tmp = pf->num_alloc_vfs; |
| 529 | 523 | pf->num_qps_per_vf = 0; |
| 530 | 524 | pf->num_alloc_vfs = 0; |
| 531 | 525 | for (i = 0; i < tmp; i++) { |
| 532 | − if (test_bit(ICE_VF_STATE_INIT, pf->vf[i].vf_states)) { | |
| 526 | + struct ice_vf *vf = &pf->vf[i]; | |
| 527 | + | |
| 528 | + mutex_lock(&vf->cfg_lock); | |
| 529 | + | |
| 530 | + ice_dis_vf_qs(vf); | |
| 531 | + | |
| 532 | + if (test_bit(ICE_VF_STATE_INIT, vf->vf_states)) { | |
| 533 | 533 | /* disable VF qp mappings and set VF disable state */ |
| 534 | − ice_dis_vf_mappings(&pf->vf[i]); | |
| 535 | − set_bit(ICE_VF_STATE_DIS, pf->vf[i].vf_states); | |
| 536 | − ice_free_vf_res(&pf->vf[i]); | |
| 534 | + ice_dis_vf_mappings(vf); | |
| 535 | + set_bit(ICE_VF_STATE_DIS, vf->vf_states); | |
| 536 | + ice_free_vf_res(vf); | |
| 537 | 537 | } |
| 538 | 538 | |
| 539 | − mutex_destroy(&pf->vf[i].cfg_lock); | |
| 539 | + mutex_unlock(&vf->cfg_lock); | |
| 540 | + | |
| 541 | + mutex_destroy(&vf->cfg_lock); | |
| 540 | 542 | } |
| 541 | 543 | |
| 542 | 544 | if (ice_sriov_free_msix_res(pf)) |
| @@ -572,7 +574,6 @@ void ice_free_vfs(struct ice_pf *pf) · 29 unmodified lines | ||
| 572 | 574 | i); |
| 573 | 575 | |
| 574 | 576 | clear_bit(ICE_VF_DIS, pf->state); |
| 575 | − clear_bit(ICE_VF_DEINIT_IN_PROGRESS, pf->state); | |
| 576 | 577 | clear_bit(ICE_FLAG_SRIOV_ENA, pf->flags); |
| 577 | 578 | } |
| 578 | 579 | |
| @@ -1564,6 +1565,8 @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr) · 985 unmodified lines | ||
| 1564 | 1565 | ice_for_each_vf(pf, v) { |
| 1565 | 1566 | vf = &pf->vf[v]; |
| 1566 | 1567 | |
| 1568 | + mutex_lock(&vf->cfg_lock); | |
| 1569 | + | |
| 1567 | 1570 | vf->driver_caps = 0; |
| 1568 | 1571 | ice_vc_set_default_allowlist(vf); |
| 1569 | 1572 | |
| @@ -1578,6 +1581,8 @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr) · 8 unmodified lines | ||
| 1578 | 1581 | ice_vf_pre_vsi_rebuild(vf); |
| 1579 | 1582 | ice_vf_rebuild_vsi(vf); |
| 1580 | 1583 | ice_vf_post_vsi_rebuild(vf); |
| 1584 | + | |
| 1585 | + mutex_unlock(&vf->cfg_lock); | |
| 1581 | 1586 | } |
| 1582 | 1587 | |
| 1583 | 1588 | if (ice_is_eswitch_mode_switchdev(pf)) |
| @@ -1628,6 +1633,8 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr) · 44 unmodified lines | ||
| 1628 | 1633 | u32 reg; |
| 1629 | 1634 | int i; |
| 1630 | 1635 | |
| 1636 | + lockdep_assert_held(&vf->cfg_lock); | |
| 1637 | + | |
| 1631 | 1638 | dev = ice_pf_to_dev(pf); |
| 1632 | 1639 | |
| 1633 | 1640 | if (test_bit(ICE_VF_RESETS_DISABLED, pf->state)) { |
| @@ -2143,9 +2150,12 @@ void ice_process_vflr_event(struct ice_pf *pf) · 509 unmodified lines | ||
| 2143 | 2150 | bit_idx = (hw->func_caps.vf_base_id + vf_id) % 32; |
| 2144 | 2151 | /* read GLGEN_VFLRSTAT register to find out the flr VFs */ |
| 2145 | 2152 | reg = rd32(hw, GLGEN_VFLRSTAT(reg_idx)); |
| 2146 | − if (reg & BIT(bit_idx)) | |
| 2153 | + if (reg & BIT(bit_idx)) { | |
| 2147 | 2154 | /* GLGEN_VFLRSTAT bit will be cleared in ice_reset_vf */ |
| 2155 | + mutex_lock(&vf->cfg_lock); | |
| 2148 | 2156 | ice_reset_vf(vf, true); |
| 2157 | + mutex_unlock(&vf->cfg_lock); | |
| 2158 | + } | |
| 2149 | 2159 | } |
| 2150 | 2160 | } |
| 2151 | 2161 | |
| @@ -2222,7 +2232,9 @@ ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event) · 70 unmodified lines | ||
| 2222 | 2232 | if (!vf) |
| 2223 | 2233 | return; |
| 2224 | 2234 | |
| 2235 | + mutex_lock(&vf->cfg_lock); | |
| 2225 | 2236 | ice_vc_reset_vf(vf); |
| 2237 | + mutex_unlock(&vf->cfg_lock); | |
| 2226 | 2238 | } |
| 2227 | 2239 | |
| 2228 | 2240 | /** |
| @@ -5759,10 +5771,6 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event) · 3530 unmodified lines | ||
| 5759 | 5771 | struct device *dev; |
| 5760 | 5772 | int err = 0; |
| 5761 | 5773 | |
| 5762 | − /* if de-init is underway, don't process messages from VF */ | |
| 5763 | − if (test_bit(ICE_VF_DEINIT_IN_PROGRESS, pf->state)) | |
| 5764 | − return; | |
| 5765 | − | |
| 5766 | 5774 | dev = ice_pf_to_dev(pf); |
| 5767 | 5775 | if (ice_validate_vf_id(pf, vf_id)) { |
| 5768 | 5776 | err = -EINVAL; |
| @@ -2704,6 +2704,16 @@ MODULE_DEVICE_TABLE(of, mv643xx_eth_shared_ids); · 2703 unmodified lines | ||
| 2704 | 2704 | |
| 2705 | 2705 | static struct platform_device *port_platdev[3]; |
| 2706 | 2706 | |
| 2707 | +static void mv643xx_eth_shared_of_remove(void) | |
| 2708 | +{ | |
| 2709 | + int n; | |
| 2710 | + | |
| 2711 | + for (n = 0; n < 3; n++) { | |
| 2712 | + platform_device_del(port_platdev[n]); | |
| 2713 | + port_platdev[n] = NULL; | |
| 2714 | + } | |
| 2715 | +} | |
| 2716 | + | |
| 2707 | 2717 | static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev, |
| 2708 | 2718 | struct device_node *pnp) |
| 2709 | 2719 | { |
| @@ -2740,7 +2750,9 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev, · 30 unmodified lines | ||
| 2740 | 2750 | return -EINVAL; |
| 2741 | 2751 | } |
| 2742 | 2752 | |
| 2743 | − of_get_mac_address(pnp, ppd.mac_addr); | |
| 2753 | + ret = of_get_mac_address(pnp, ppd.mac_addr); | |
| 2754 | + if (ret) | |
| 2755 | + return ret; | |
| 2744 | 2756 | |
| 2745 | 2757 | mv643xx_eth_property(pnp, "tx-queue-size", ppd.tx_queue_size); |
| 2746 | 2758 | mv643xx_eth_property(pnp, "tx-sram-addr", ppd.tx_sram_addr); |
| @@ -2804,21 +2816,13 @@ static int mv643xx_eth_shared_of_probe(struct platform_device *pdev) · 57 unmodified lines | ||
| 2804 | 2816 | ret = mv643xx_eth_shared_of_add_port(pdev, pnp); |
| 2805 | 2817 | if (ret) { |
| 2806 | 2818 | of_node_put(pnp); |
| 2819 | + mv643xx_eth_shared_of_remove(); | |
| 2807 | 2820 | return ret; |
| 2808 | 2821 | } |
| 2809 | 2822 | } |
| 2810 | 2823 | return 0; |
| 2811 | 2824 | } |
| 2812 | 2825 | |
| 2813 | −static void mv643xx_eth_shared_of_remove(void) | |
| 2814 | −{ | |
| 2815 | − int n; | |
| 2816 | − | |
| 2817 | − for (n = 0; n < 3; n++) { | |
| 2818 | − platform_device_del(port_platdev[n]); | |
| 2819 | − port_platdev[n] = NULL; | |
| 2820 | − } | |
| 2821 | −} | |
| 2822 | 2826 | #else |
| 2823 | 2827 | static inline int mv643xx_eth_shared_of_probe(struct platform_device *pdev) |
| 2824 | 2828 | { |
| @@ -6870,6 +6870,9 @@ static int mvpp2_port_probe(struct platform_device *pdev, · 6869 unmodified lines | ||
| 6870 | 6870 | dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE; |
| 6871 | 6871 | dev->dev.of_node = port_node; |
| 6872 | 6872 | |
| 6873 | + port->pcs_gmac.ops = &mvpp2_phylink_gmac_pcs_ops; | |
| 6874 | + port->pcs_xlg.ops = &mvpp2_phylink_xlg_pcs_ops; | |
| 6875 | + | |
| 6873 | 6876 | if (!mvpp2_use_acpi_compat_mode(port_fwnode)) { |
| 6874 | 6877 | port->phylink_config.dev = &dev->dev; |
| 6875 | 6878 | port->phylink_config.type = PHYLINK_NETDEV; |
| @@ -6940,9 +6943,6 @@ static int mvpp2_port_probe(struct platform_device *pdev, · 64 unmodified lines | ||
| 6940 | 6943 | port->phylink_config.supported_interfaces); |
| 6941 | 6944 | } |
| 6942 | 6945 | |
| 6943 | − port->pcs_gmac.ops = &mvpp2_phylink_gmac_pcs_ops; | |
| 6944 | − port->pcs_xlg.ops = &mvpp2_phylink_xlg_pcs_ops; | |
| 6945 | − | |
| 6946 | 6946 | phylink = phylink_create(&port->phylink_config, port_fwnode, |
| 6947 | 6947 | phy_mode, &mvpp2_phylink_ops); |
| 6948 | 6948 | if (IS_ERR(phylink)) { |
| @@ -18,11 +18,13 @@ struct mlx5e_tc_act_parse_state { · 17 unmodified lines | ||
| 18 | 18 | struct netlink_ext_ack *extack; |
| 19 | 19 | u32 actions; |
| 20 | 20 | bool ct; |
| 21 | + bool ct_clear; | |
| 21 | 22 | bool encap; |
| 22 | 23 | bool decap; |
| 23 | 24 | bool mpls_push; |
| 24 | 25 | bool ptype_host; |
| 25 | 26 | const struct ip_tunnel_info *tun_info; |
| 27 | + struct mlx5e_mpls_info mpls_info; | |
| 26 | 28 | int ifindexes[MLX5_MAX_FLOW_FWD_VPORTS]; |
| 27 | 29 | int if_count; |
| 28 | 30 | struct mlx5_tc_ct_priv *ct_priv; |
| @@ -31,6 +31,10 @@ tc_act_parse_ct(struct mlx5e_tc_act_parse_state *parse_state, · 30 unmodified lines | ||
| 31 | 31 | bool clear_action = act->ct.action & TCA_CT_ACT_CLEAR; |
| 32 | 32 | int err; |
| 33 | 33 | |
| 34 | + /* It's redundant to do ct clear more than once. */ | |
| 35 | + if (clear_action && parse_state->ct_clear) | |
| 36 | + return 0; | |
| 37 | + | |
| 34 | 38 | err = mlx5_tc_ct_parse_action(parse_state->ct_priv, attr, |
| 35 | 39 | &attr->parse_attr->mod_hdr_acts, |
| 36 | 40 | act, parse_state->extack); |
| @@ -46,6 +50,7 @@ tc_act_parse_ct(struct mlx5e_tc_act_parse_state *parse_state, · 9 unmodified lines | ||
| 46 | 50 | flow_flag_set(parse_state->flow, CT); |
| 47 | 51 | parse_state->ct = true; |
| 48 | 52 | } |
| 53 | + parse_state->ct_clear = clear_action; | |
| 49 | 54 | |
| 50 | 55 | return 0; |
| 51 | 56 | } |
| @@ -178,6 +178,12 @@ parse_mirred_encap(struct mlx5e_tc_act_parse_state *parse_state, · 177 unmodified lines | ||
| 178 | 178 | return -ENOMEM; |
| 179 | 179 | |
| 180 | 180 | parse_state->encap = false; |
| 181 | + | |
| 182 | + if (parse_state->mpls_push) { | |
| 183 | + memcpy(&parse_attr->mpls_info[esw_attr->out_count], | |
| 184 | + &parse_state->mpls_info, sizeof(parse_state->mpls_info)); | |
| 185 | + parse_state->mpls_push = false; | |
| 186 | + } | |
| 181 | 187 | esw_attr->dests[esw_attr->out_count].flags |= MLX5_ESW_DEST_ENCAP; |
| 182 | 188 | esw_attr->out_count++; |
| 183 | 189 | /* attr->dests[].rep is resolved when we handle encap */ |
| @@ -23,6 +23,16 @@ tc_act_can_offload_mpls_push(struct mlx5e_tc_act_parse_state *parse_state, · 22 unmodified lines | ||
| 23 | 23 | return true; |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | +static void | |
| 27 | +copy_mpls_info(struct mlx5e_mpls_info *mpls_info, | |
| 28 | + const struct flow_action_entry *act) | |
| 29 | +{ | |
| 30 | + mpls_info->label = act->mpls_push.label; | |
| 31 | + mpls_info->tc = act->mpls_push.tc; | |
| 32 | + mpls_info->bos = act->mpls_push.bos; | |
| 33 | + mpls_info->ttl = act->mpls_push.ttl; | |
| 34 | +} | |
| 35 | + | |
| 26 | 36 | static int |
| 27 | 37 | tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state, |
| 28 | 38 | const struct flow_action_entry *act, |
| @@ -30,6 +40,7 @@ tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state, · 1 unmodified line | ||
| 30 | 40 | struct mlx5_flow_attr *attr) |
| 31 | 41 | { |
| 32 | 42 | parse_state->mpls_push = true; |
| 43 | + copy_mpls_info(&parse_state->mpls_info, act); | |
| 33 | 44 | |
| 34 | 45 | return 0; |
| 35 | 46 | } |
| @@ -35,6 +35,7 @@ enum { · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | struct mlx5e_tc_flow_parse_attr { |
| 37 | 37 | const struct ip_tunnel_info *tun_info[MLX5_MAX_FLOW_FWD_VPORTS]; |
| 38 | + struct mlx5e_mpls_info mpls_info[MLX5_MAX_FLOW_FWD_VPORTS]; | |
| 38 | 39 | struct net_device *filter_dev; |
| 39 | 40 | struct mlx5_flow_spec spec; |
| 40 | 41 | struct pedit_headers_action hdrs[__PEDIT_CMD_MAX]; |
| @@ -768,6 +768,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv, · 767 unmodified lines | ||
| 768 | 768 | struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; |
| 769 | 769 | struct mlx5e_tc_flow_parse_attr *parse_attr; |
| 770 | 770 | const struct ip_tunnel_info *tun_info; |
| 771 | + const struct mlx5e_mpls_info *mpls_info; | |
| 771 | 772 | unsigned long tbl_time_before = 0; |
| 772 | 773 | struct mlx5e_encap_entry *e; |
| 773 | 774 | struct mlx5e_encap_key key; |
| @@ -778,6 +779,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv, · 4 unmodified lines | ||
| 778 | 779 | |
| 779 | 780 | parse_attr = attr->parse_attr; |
| 780 | 781 | tun_info = parse_attr->tun_info[out_index]; |
| 782 | + mpls_info = &parse_attr->mpls_info[out_index]; | |
| 781 | 783 | family = ip_tunnel_info_af(tun_info); |
| 782 | 784 | key.ip_tun_key = &tun_info->key; |
| 783 | 785 | key.tc_tunnel = mlx5e_get_tc_tun(mirred_dev); |
| @@ -828,6 +830,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv, · 44 unmodified lines | ||
| 828 | 830 | goto out_err_init; |
| 829 | 831 | } |
| 830 | 832 | e->tun_info = tun_info; |
| 833 | + memcpy(&e->mpls_info, mpls_info, sizeof(*mpls_info)); | |
| 831 | 834 | err = mlx5e_tc_tun_init_encap_attr(mirred_dev, priv, e, extack); |
| 832 | 835 | if (err) |
| 833 | 836 | goto out_err_init; |
| @@ -30,16 +30,15 @@ static int generate_ip_tun_hdr(char buf[], · 29 unmodified lines | ||
| 30 | 30 | struct mlx5e_encap_entry *r) |
| 31 | 31 | { |
| 32 | 32 | const struct ip_tunnel_key *tun_key = &r->tun_info->key; |
| 33 | + const struct mlx5e_mpls_info *mpls_info = &r->mpls_info; | |
| 33 | 34 | struct udphdr *udp = (struct udphdr *)(buf); |
| 34 | 35 | struct mpls_shim_hdr *mpls; |
| 35 | − u32 tun_id; | |
| 36 | 36 | |
| 37 | − tun_id = be32_to_cpu(tunnel_id_to_key32(tun_key->tun_id)); | |
| 38 | 37 | mpls = (struct mpls_shim_hdr *)(udp + 1); |
| 39 | 38 | *ip_proto = IPPROTO_UDP; |
| 40 | 39 | |
| 41 | 40 | udp->dest = tun_key->tp_dst; |
| 42 | − *mpls = mpls_entry_encode(tun_id, tun_key->ttl, tun_key->tos, true); | |
| 41 | + *mpls = mpls_entry_encode(mpls_info->label, mpls_info->ttl, mpls_info->tc, mpls_info->bos); | |
| 43 | 42 | |
| 44 | 43 | return 0; |
| 45 | 44 | } |
| @@ -60,37 +59,31 @@ static int parse_tunnel(struct mlx5e_priv *priv, · 14 unmodified lines | ||
| 60 | 59 | void *headers_v) |
| 61 | 60 | { |
| 62 | 61 | struct flow_rule *rule = flow_cls_offload_flow_rule(f); |
| 63 | − struct flow_match_enc_keyid enc_keyid; | |
| 64 | 62 | struct flow_match_mpls match; |
| 65 | 63 | void *misc2_c; |
| 66 | 64 | void *misc2_v; |
| 67 | 65 | |
| 68 | − misc2_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, | |
| 69 | − misc_parameters_2); | |
| 70 | − misc2_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, | |
| 71 | − misc_parameters_2); | |
| 72 | − | |
| 73 | − if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS)) | |
| 74 | − return 0; | |
| 75 | − | |
| 76 | − if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID)) | |
| 77 | − return 0; | |
| 78 | − | |
| 79 | − flow_rule_match_enc_keyid(rule, &enc_keyid); | |
| 80 | − | |
| 81 | − if (!enc_keyid.mask->keyid) | |
| 82 | − return 0; | |
| 83 | − | |
| 84 | 66 | if (!MLX5_CAP_ETH(priv->mdev, tunnel_stateless_mpls_over_udp) && |
| 85 | 67 | !(MLX5_CAP_GEN(priv->mdev, flex_parser_protocols) & MLX5_FLEX_PROTO_CW_MPLS_UDP)) |
| 86 | 68 | return -EOPNOTSUPP; |
| 87 | 69 | |
| 70 | + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID)) | |
| 71 | + return -EOPNOTSUPP; | |
| 72 | + | |
| 73 | + if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS)) | |
| 74 | + return 0; | |
| 75 | + | |
| 88 | 76 | flow_rule_match_mpls(rule, &match); |
| 89 | 77 | |
| 90 | 78 | /* Only support matching the first LSE */ |
| 91 | 79 | if (match.mask->used_lses != 1) |
| 92 | 80 | return -EOPNOTSUPP; |
| 93 | 81 | |
| 82 | + misc2_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, | |
| 83 | + misc_parameters_2); | |
| 84 | + misc2_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, | |
| 85 | + misc_parameters_2); | |
| 86 | + | |
| 94 | 87 | MLX5_SET(fte_match_set_misc2, misc2_c, |
| 95 | 88 | outer_first_mpls_over_udp.mpls_label, |
| 96 | 89 | match.mask->ls[0].mpls_label); |
| @@ -1792,7 +1792,7 @@ static int mlx5e_get_module_eeprom(struct net_device *netdev, · 1791 unmodified lines | ||
| 1792 | 1792 | if (size_read < 0) { |
| 1793 | 1793 | netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n", |
| 1794 | 1794 | __func__, size_read); |
| 1795 | − return 0; | |
| 1795 | + return size_read; | |
| 1796 | 1796 | } |
| 1797 | 1797 | |
| 1798 | 1798 | i += size_read; |
| @@ -179,6 +179,13 @@ struct mlx5e_decap_entry { · 178 unmodified lines | ||
| 179 | 179 | struct rcu_head rcu; |
| 180 | 180 | }; |
| 181 | 181 | |
| 182 | +struct mlx5e_mpls_info { | |
| 183 | + u32 label; | |
| 184 | + u8 tc; | |
| 185 | + u8 bos; | |
| 186 | + u8 ttl; | |
| 187 | +}; | |
| 188 | + | |
| 182 | 189 | struct mlx5e_encap_entry { |
| 183 | 190 | /* attached neigh hash entry */ |
| 184 | 191 | struct mlx5e_neigh_hash_entry *nhe; |
| @@ -192,6 +199,7 @@ struct mlx5e_encap_entry { · 7 unmodified lines | ||
| 192 | 199 | struct list_head route_list; |
| 193 | 200 | struct mlx5_pkt_reformat *pkt_reformat; |
| 194 | 201 | const struct ip_tunnel_info *tun_info; |
| 202 | + struct mlx5e_mpls_info mpls_info; | |
| 195 | 203 | unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ |
| 196 | 204 | |
| 197 | 205 | struct net_device *out_dev; |
| @@ -1348,7 +1348,8 @@ static inline void mlx5e_handle_csum(struct net_device *netdev, · 1347 unmodified lines | ||
| 1348 | 1348 | } |
| 1349 | 1349 | |
| 1350 | 1350 | /* True when explicitly set via priv flag, or XDP prog is loaded */ |
| 1351 | − if (test_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &rq->state)) | |
| 1351 | + if (test_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &rq->state) || | |
| 1352 | + get_cqe_tls_offload(cqe)) | |
| 1352 | 1353 | goto csum_unnecessary; |
| 1353 | 1354 | |
| 1354 | 1355 | /* CQE csum doesn't cover padding octets in short ethernet |
| @@ -334,6 +334,7 @@ void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest, · 333 unmodified lines | ||
| 334 | 334 | netdev_info(ndev, "\t[%d] %s start..\n", i, st.name); |
| 335 | 335 | buf[count] = st.st_func(priv); |
| 336 | 336 | netdev_info(ndev, "\t[%d] %s end: result(%lld)\n", i, st.name, buf[count]); |
| 337 | + count++; | |
| 337 | 338 | } |
| 338 | 339 | |
| 339 | 340 | mutex_unlock(&priv->state_lock); |
| @@ -1254,9 +1254,6 @@ static void fec_set_corrected_bits_total(struct mlx5e_priv *priv, · 1253 unmodified lines | ||
| 1254 | 1254 | u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {}; |
| 1255 | 1255 | int sz = MLX5_ST_SZ_BYTES(ppcnt_reg); |
| 1256 | 1256 | |
| 1257 | − if (!MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group)) | |
| 1258 | − return; | |
| 1259 | − | |
| 1260 | 1257 | MLX5_SET(ppcnt_reg, in, local_port, 1); |
| 1261 | 1258 | MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_STATISTICAL_GROUP); |
| 1262 | 1259 | if (mlx5_core_access_reg(mdev, in, sz, ppcnt_phy_statistical, |
| @@ -1272,6 +1269,9 @@ static void fec_set_corrected_bits_total(struct mlx5e_priv *priv, · 9 unmodified lines | ||
| 1272 | 1269 | void mlx5e_stats_fec_get(struct mlx5e_priv *priv, |
| 1273 | 1270 | struct ethtool_fec_stats *fec_stats) |
| 1274 | 1271 | { |
| 1272 | + if (!MLX5_CAP_PCAM_FEATURE(priv->mdev, ppcnt_statistical_group)) | |
| 1273 | + return; | |
| 1274 | + | |
| 1275 | 1275 | fec_set_corrected_bits_total(priv, fec_stats); |
| 1276 | 1276 | fec_set_block_stats(priv, fec_stats); |
| 1277 | 1277 | } |
| @@ -3316,6 +3316,18 @@ actions_match_supported(struct mlx5e_priv *priv, · 3315 unmodified lines | ||
| 3316 | 3316 | return false; |
| 3317 | 3317 | } |
| 3318 | 3318 | |
| 3319 | + if (!(~actions & | |
| 3320 | + (MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP))) { | |
| 3321 | + NL_SET_ERR_MSG_MOD(extack, "Rule cannot support forward+drop action"); | |
| 3322 | + return false; | |
| 3323 | + } | |
| 3324 | + | |
| 3325 | + if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR && | |
| 3326 | + actions & MLX5_FLOW_CONTEXT_ACTION_DROP) { | |
| 3327 | + NL_SET_ERR_MSG_MOD(extack, "Drop with modify header action is not supported"); | |
| 3328 | + return false; | |
| 3329 | + } | |
| 3330 | + | |
| 3319 | 3331 | if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR && |
| 3320 | 3332 | !modify_header_match_supported(priv, &parse_attr->spec, flow_action, |
| 3321 | 3333 | actions, ct_flow, ct_clear, extack)) |
| @@ -697,7 +697,7 @@ void mlx5_esw_qos_vport_disable(struct mlx5_eswitch *esw, struct mlx5_vport *vpo · 696 unmodified lines | ||
| 697 | 697 | } |
| 698 | 698 | |
| 699 | 699 | int mlx5_esw_qos_set_vport_rate(struct mlx5_eswitch *esw, struct mlx5_vport *vport, |
| 700 | − u32 min_rate, u32 max_rate) | |
| 700 | + u32 max_rate, u32 min_rate) | |
| 701 | 701 | { |
| 702 | 702 | int err; |
| 703 | 703 | |
| @@ -2839,10 +2839,6 @@ bool mlx5_esw_vport_match_metadata_supported(const struct mlx5_eswitch *esw) · 2838 unmodified lines | ||
| 2839 | 2839 | if (!MLX5_CAP_ESW_FLOWTABLE(esw->dev, flow_source)) |
| 2840 | 2840 | return false; |
| 2841 | 2841 | |
| 2842 | − if (mlx5_core_is_ecpf_esw_manager(esw->dev) || | |
| 2843 | − mlx5_ecpf_vport_exists(esw->dev)) | |
| 2844 | − return false; | |
| 2845 | − | |
| 2846 | 2842 | return true; |
| 2847 | 2843 | } |
| 2848 | 2844 | |
| @@ -2074,6 +2074,8 @@ void mlx5_del_flow_rules(struct mlx5_flow_handle *handle) · 2073 unmodified lines | ||
| 2074 | 2074 | fte->node.del_hw_func = NULL; |
| 2075 | 2075 | up_write_ref_node(&fte->node, false); |
| 2076 | 2076 | tree_put_node(&fte->node, false); |
| 2077 | + } else { | |
| 2078 | + up_write_ref_node(&fte->node, false); | |
| 2077 | 2079 | } |
| 2078 | 2080 | kfree(handle); |
| 2079 | 2081 | } |
| @@ -121,6 +121,9 @@ u32 mlx5_chains_get_nf_ft_chain(struct mlx5_fs_chains *chains) · 120 unmodified lines | ||
| 121 | 121 | |
| 122 | 122 | u32 mlx5_chains_get_prio_range(struct mlx5_fs_chains *chains) |
| 123 | 123 | { |
| 124 | + if (!mlx5_chains_prios_supported(chains)) | |
| 125 | + return 1; | |
| 126 | + | |
| 124 | 127 | if (mlx5_chains_ignore_flow_level_supported(chains)) |
| 125 | 128 | return UINT_MAX; |
| 126 | 129 | |
| @@ -526,7 +526,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx) · 525 unmodified lines | ||
| 526 | 526 | |
| 527 | 527 | /* Check log_max_qp from HCA caps to set in current profile */ |
| 528 | 528 | if (prof->log_max_qp == LOG_MAX_SUPPORTED_QPS) { |
| 529 | − prof->log_max_qp = MLX5_CAP_GEN_MAX(dev, log_max_qp); | |
| 529 | + prof->log_max_qp = min_t(u8, 17, MLX5_CAP_GEN_MAX(dev, log_max_qp)); | |
| 530 | 530 | } else if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < prof->log_max_qp) { |
| 531 | 531 | mlx5_core_warn(dev, "log_max_qp value in current profile is %d, changing it to HCA capability limit (%d)\n", |
| 532 | 532 | prof->log_max_qp, |
| @@ -1840,10 +1840,12 @@ static const struct pci_device_id mlx5_core_pci_table[] = { · 1307 unmodified lines | ||
| 1840 | 1840 | { PCI_VDEVICE(MELLANOX, 0x101e), MLX5_PCI_DEV_IS_VF}, /* ConnectX Family mlx5Gen Virtual Function */ |
| 1841 | 1841 | { PCI_VDEVICE(MELLANOX, 0x101f) }, /* ConnectX-6 LX */ |
| 1842 | 1842 | { PCI_VDEVICE(MELLANOX, 0x1021) }, /* ConnectX-7 */ |
| 1843 | + { PCI_VDEVICE(MELLANOX, 0x1023) }, /* ConnectX-8 */ | |
| 1843 | 1844 | { PCI_VDEVICE(MELLANOX, 0xa2d2) }, /* BlueField integrated ConnectX-5 network controller */ |
| 1844 | 1845 | { PCI_VDEVICE(MELLANOX, 0xa2d3), MLX5_PCI_DEV_IS_VF}, /* BlueField integrated ConnectX-5 network controller VF */ |
| 1845 | 1846 | { PCI_VDEVICE(MELLANOX, 0xa2d6) }, /* BlueField-2 integrated ConnectX-6 Dx network controller */ |
| 1846 | 1847 | { PCI_VDEVICE(MELLANOX, 0xa2dc) }, /* BlueField-3 integrated ConnectX-7 network controller */ |
| 1848 | + { PCI_VDEVICE(MELLANOX, 0xa2df) }, /* BlueField-4 integrated ConnectX-8 network controller */ | |
| 1847 | 1849 | { 0, } |
| 1848 | 1850 | }; |
| 1849 | 1851 | |
| @@ -4,7 +4,6 @@ · 3 unmodified lines | ||
| 4 | 4 | #include "dr_types.h" |
| 5 | 5 | |
| 6 | 6 | #define DR_ICM_MODIFY_HDR_ALIGN_BASE 64 |
| 7 | −#define DR_ICM_SYNC_THRESHOLD_POOL (64 * 1024 * 1024) | |
| 8 | 7 | |
| 9 | 8 | struct mlx5dr_icm_pool { |
| 10 | 9 | enum mlx5dr_icm_type icm_type; |
| @@ -136,37 +135,35 @@ static void dr_icm_pool_mr_destroy(struct mlx5dr_icm_mr *icm_mr) · 125 unmodified lines | ||
| 136 | 135 | kvfree(icm_mr); |
| 137 | 136 | } |
| 138 | 137 | |
| 139 | −static int dr_icm_chunk_ste_init(struct mlx5dr_icm_chunk *chunk) | |
| 138 | +static int dr_icm_buddy_get_ste_size(struct mlx5dr_icm_buddy_mem *buddy) | |
| 140 | 139 | { |
| 141 | − chunk->ste_arr = kvzalloc(chunk->num_of_entries * | |
| 142 | − sizeof(chunk->ste_arr[0]), GFP_KERNEL); | |
| 143 | − if (!chunk->ste_arr) | |
| 144 | − return -ENOMEM; | |
| 145 | − | |
| 146 | − chunk->hw_ste_arr = kvzalloc(chunk->num_of_entries * | |
| 147 | − DR_STE_SIZE_REDUCED, GFP_KERNEL); | |
| 148 | − if (!chunk->hw_ste_arr) | |
| 149 | − goto out_free_ste_arr; | |
| 150 | − | |
| 151 | − chunk->miss_list = kvmalloc(chunk->num_of_entries * | |
| 152 | − sizeof(chunk->miss_list[0]), GFP_KERNEL); | |
| 153 | − if (!chunk->miss_list) | |
| 154 | − goto out_free_hw_ste_arr; | |
| 140 | + /* We support only one type of STE size, both for ConnectX-5 and later | |
| 141 | + * devices. Once the support for match STE which has a larger tag is | |
| 142 | + * added (32B instead of 16B), the STE size for devices later than | |
| 143 | + * ConnectX-5 needs to account for that. | |
| 144 | + */ | |
| 145 | + return DR_STE_SIZE_REDUCED; | |
| 146 | +} | |
| 155 | 147 | |
| 156 | − return 0; | |
| 148 | +static void dr_icm_chunk_ste_init(struct mlx5dr_icm_chunk *chunk, int offset) | |
| 149 | +{ | |
| 150 | + struct mlx5dr_icm_buddy_mem *buddy = chunk->buddy_mem; | |
| 151 | + int index = offset / DR_STE_SIZE; | |
| 157 | 152 | |
| 158 | −out_free_hw_ste_arr: | |
| 159 | − kvfree(chunk->hw_ste_arr); | |
| 160 | −out_free_ste_arr: | |
| 161 | − kvfree(chunk->ste_arr); | |
| 162 | − return -ENOMEM; | |
| 153 | + chunk->ste_arr = &buddy->ste_arr[index]; | |
| 154 | + chunk->miss_list = &buddy->miss_list[index]; | |
| 155 | + chunk->hw_ste_arr = buddy->hw_ste_arr + | |
| 156 | + index * dr_icm_buddy_get_ste_size(buddy); | |
| 163 | 157 | } |
| 164 | 158 | |
| 165 | 159 | static void dr_icm_chunk_ste_cleanup(struct mlx5dr_icm_chunk *chunk) |
| 166 | 160 | { |
| 167 | − kvfree(chunk->miss_list); | |
| 168 | − kvfree(chunk->hw_ste_arr); | |
| 169 | − kvfree(chunk->ste_arr); | |
| 161 | + struct mlx5dr_icm_buddy_mem *buddy = chunk->buddy_mem; | |
| 162 | + | |
| 163 | + memset(chunk->hw_ste_arr, 0, | |
| 164 | + chunk->num_of_entries * dr_icm_buddy_get_ste_size(buddy)); | |
| 165 | + memset(chunk->ste_arr, 0, | |
| 166 | + chunk->num_of_entries * sizeof(chunk->ste_arr[0])); | |
| 170 | 167 | } |
| 171 | 168 | |
| 172 | 169 | static enum mlx5dr_icm_type |
| @@ -189,6 +186,44 @@ static void dr_icm_chunk_destroy(struct mlx5dr_icm_chunk *chunk, · 16 unmodified lines | ||
| 189 | 186 | kvfree(chunk); |
| 190 | 187 | } |
| 191 | 188 | |
| 189 | +static int dr_icm_buddy_init_ste_cache(struct mlx5dr_icm_buddy_mem *buddy) | |
| 190 | +{ | |
| 191 | + int num_of_entries = | |
| 192 | + mlx5dr_icm_pool_chunk_size_to_entries(buddy->pool->max_log_chunk_sz); | |
| 193 | + | |
| 194 | + buddy->ste_arr = kvcalloc(num_of_entries, | |
| 195 | + sizeof(struct mlx5dr_ste), GFP_KERNEL); | |
| 196 | + if (!buddy->ste_arr) | |
| 197 | + return -ENOMEM; | |
| 198 | + | |
| 199 | + /* Preallocate full STE size on non-ConnectX-5 devices since | |
| 200 | + * we need to support both full and reduced with the same cache. | |
| 201 | + */ | |
| 202 | + buddy->hw_ste_arr = kvcalloc(num_of_entries, | |
| 203 | + dr_icm_buddy_get_ste_size(buddy), GFP_KERNEL); | |
| 204 | + if (!buddy->hw_ste_arr) | |
| 205 | + goto free_ste_arr; | |
| 206 | + | |
| 207 | + buddy->miss_list = kvmalloc(num_of_entries * sizeof(struct list_head), GFP_KERNEL); | |
| 208 | + if (!buddy->miss_list) | |
| 209 | + goto free_hw_ste_arr; | |
| 210 | + | |
| 211 | + return 0; | |
| 212 | + | |
| 213 | +free_hw_ste_arr: | |
| 214 | + kvfree(buddy->hw_ste_arr); | |
| 215 | +free_ste_arr: | |
| 216 | + kvfree(buddy->ste_arr); | |
| 217 | + return -ENOMEM; | |
| 218 | +} | |
| 219 | + | |
| 220 | +static void dr_icm_buddy_cleanup_ste_cache(struct mlx5dr_icm_buddy_mem *buddy) | |
| 221 | +{ | |
| 222 | + kvfree(buddy->ste_arr); | |
| 223 | + kvfree(buddy->hw_ste_arr); | |
| 224 | + kvfree(buddy->miss_list); | |
| 225 | +} | |
| 226 | + | |
| 192 | 227 | static int dr_icm_buddy_create(struct mlx5dr_icm_pool *pool) |
| 193 | 228 | { |
| 194 | 229 | struct mlx5dr_icm_buddy_mem *buddy; |
| @@ -208,11 +243,19 @@ static int dr_icm_buddy_create(struct mlx5dr_icm_pool *pool) · 13 unmodified lines | ||
| 208 | 243 | buddy->icm_mr = icm_mr; |
| 209 | 244 | buddy->pool = pool; |
| 210 | 245 | |
| 246 | + if (pool->icm_type == DR_ICM_TYPE_STE) { | |
| 247 | + /* Reduce allocations by preallocating and reusing the STE structures */ | |
| 248 | + if (dr_icm_buddy_init_ste_cache(buddy)) | |
| 249 | + goto err_cleanup_buddy; | |
| 250 | + } | |
| 251 | + | |
| 211 | 252 | /* add it to the -start- of the list in order to search in it first */ |
| 212 | 253 | list_add(&buddy->list_node, &pool->buddy_mem_list); |
| 213 | 254 | |
| 214 | 255 | return 0; |
| 215 | 256 | |
| 257 | +err_cleanup_buddy: | |
| 258 | + mlx5dr_buddy_cleanup(buddy); | |
| 216 | 259 | err_free_buddy: |
| 217 | 260 | kvfree(buddy); |
| 218 | 261 | free_mr: |
| @@ -234,6 +277,9 @@ static void dr_icm_buddy_destroy(struct mlx5dr_icm_buddy_mem *buddy) · 15 unmodified lines | ||
| 234 | 277 | |
| 235 | 278 | mlx5dr_buddy_cleanup(buddy); |
| 236 | 279 | |
| 280 | + if (buddy->pool->icm_type == DR_ICM_TYPE_STE) | |
| 281 | + dr_icm_buddy_cleanup_ste_cache(buddy); | |
| 282 | + | |
| 237 | 283 | kvfree(buddy); |
| 238 | 284 | } |
| 239 | 285 | |
| @@ -261,34 +307,30 @@ dr_icm_chunk_create(struct mlx5dr_icm_pool *pool, · 21 unmodified lines | ||
| 261 | 307 | chunk->byte_size = |
| 262 | 308 | mlx5dr_icm_pool_chunk_size_to_byte(chunk_size, pool->icm_type); |
| 263 | 309 | chunk->seg = seg; |
| 310 | + chunk->buddy_mem = buddy_mem_pool; | |
| 264 | 311 | |
| 265 | − if (pool->icm_type == DR_ICM_TYPE_STE && dr_icm_chunk_ste_init(chunk)) { | |
| 266 | − mlx5dr_err(pool->dmn, | |
| 267 | − "Failed to init ste arrays (order: %d)\n", | |
| 268 | − chunk_size); | |
| 269 | − goto out_free_chunk; | |
| 270 | − } | |
| 312 | + if (pool->icm_type == DR_ICM_TYPE_STE) | |
| 313 | + dr_icm_chunk_ste_init(chunk, offset); | |
| 271 | 314 | |
| 272 | 315 | buddy_mem_pool->used_memory += chunk->byte_size; |
| 273 | − chunk->buddy_mem = buddy_mem_pool; | |
| 274 | 316 | INIT_LIST_HEAD(&chunk->chunk_list); |
| 275 | 317 | |
| 276 | 318 | /* chunk now is part of the used_list */ |
| 277 | 319 | list_add_tail(&chunk->chunk_list, &buddy_mem_pool->used_list); |
| 278 | 320 | |
| 279 | 321 | return chunk; |
| 280 | − | |
| 281 | −out_free_chunk: | |
| 282 | − kvfree(chunk); | |
| 283 | − return NULL; | |
| 284 | 322 | } |
| 285 | 323 | |
| 286 | 324 | static bool dr_icm_pool_is_sync_required(struct mlx5dr_icm_pool *pool) |
| 287 | 325 | { |
| 288 | − if (pool->hot_memory_size > DR_ICM_SYNC_THRESHOLD_POOL) | |
| 289 | − return true; | |
| 326 | + int allow_hot_size; | |
| 327 | + | |
| 328 | + /* sync when hot memory reaches half of the pool size */ | |
| 329 | + allow_hot_size = | |
| 330 | + mlx5dr_icm_pool_chunk_size_to_byte(pool->max_log_chunk_sz, | |
| 331 | + pool->icm_type) / 2; | |
| 290 | 332 | |
| 291 | − return false; | |
| 333 | + return pool->hot_memory_size > allow_hot_size; | |
| 292 | 334 | } |
| 293 | 335 | |
| 294 | 336 | static int dr_icm_pool_sync_all_buddy_pools(struct mlx5dr_icm_pool *pool) |
| @@ -13,18 +13,6 @@ static bool dr_mask_is_dmac_set(struct mlx5dr_match_spec *spec) · 12 unmodified lines | ||
| 13 | 13 | return (spec->dmac_47_16 || spec->dmac_15_0); |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | −static bool dr_mask_is_src_addr_set(struct mlx5dr_match_spec *spec) | |
| 17 | −{ | |
| 18 | − return (spec->src_ip_127_96 || spec->src_ip_95_64 || | |
| 19 | − spec->src_ip_63_32 || spec->src_ip_31_0); | |
| 20 | −} | |
| 21 | − | |
| 22 | −static bool dr_mask_is_dst_addr_set(struct mlx5dr_match_spec *spec) | |
| 23 | −{ | |
| 24 | − return (spec->dst_ip_127_96 || spec->dst_ip_95_64 || | |
| 25 | − spec->dst_ip_63_32 || spec->dst_ip_31_0); | |
| 26 | −} | |
| 27 | − | |
| 28 | 16 | static bool dr_mask_is_l3_base_set(struct mlx5dr_match_spec *spec) |
| 29 | 17 | { |
| 30 | 18 | return (spec->ip_protocol || spec->frag || spec->tcp_flags || |
| @@ -503,11 +491,11 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher, · 472 unmodified lines | ||
| 503 | 491 | &mask, inner, rx); |
| 504 | 492 | |
| 505 | 493 | if (outer_ipv == DR_RULE_IPV6) { |
| 506 | − if (dr_mask_is_dst_addr_set(&mask.outer)) | |
| 494 | + if (DR_MASK_IS_DST_IP_SET(&mask.outer)) | |
| 507 | 495 | mlx5dr_ste_build_eth_l3_ipv6_dst(ste_ctx, &sb[idx++], |
| 508 | 496 | &mask, inner, rx); |
| 509 | 497 | |
| 510 | − if (dr_mask_is_src_addr_set(&mask.outer)) | |
| 498 | + if (DR_MASK_IS_SRC_IP_SET(&mask.outer)) | |
| 511 | 499 | mlx5dr_ste_build_eth_l3_ipv6_src(ste_ctx, &sb[idx++], |
| 512 | 500 | &mask, inner, rx); |
| 513 | 501 | |
| @@ -610,11 +598,11 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher, · 96 unmodified lines | ||
| 610 | 598 | &mask, inner, rx); |
| 611 | 599 | |
| 612 | 600 | if (inner_ipv == DR_RULE_IPV6) { |
| 613 | − if (dr_mask_is_dst_addr_set(&mask.inner)) | |
| 601 | + if (DR_MASK_IS_DST_IP_SET(&mask.inner)) | |
| 614 | 602 | mlx5dr_ste_build_eth_l3_ipv6_dst(ste_ctx, &sb[idx++], |
| 615 | 603 | &mask, inner, rx); |
| 616 | 604 | |
| 617 | − if (dr_mask_is_src_addr_set(&mask.inner)) | |
| 605 | + if (DR_MASK_IS_SRC_IP_SET(&mask.inner)) | |
| 618 | 606 | mlx5dr_ste_build_eth_l3_ipv6_src(ste_ctx, &sb[idx++], |
| 619 | 607 | &mask, inner, rx); |
| 620 | 608 | |
| @@ -602,12 +602,34 @@ int mlx5dr_ste_set_action_decap_l3_list(struct mlx5dr_ste_ctx *ste_ctx, · 601 unmodified lines | ||
| 602 | 602 | used_hw_action_num); |
| 603 | 603 | } |
| 604 | 604 | |
| 605 | +static int dr_ste_build_pre_check_spec(struct mlx5dr_domain *dmn, | |
| 606 | + struct mlx5dr_match_spec *spec) | |
| 607 | +{ | |
| 608 | + if (spec->ip_version) { | |
| 609 | + if (spec->ip_version != 0xf) { | |
| 610 | + mlx5dr_err(dmn, | |
| 611 | + "Partial ip_version mask with src/dst IP is not supported\n"); | |
| 612 | + return -EINVAL; | |
| 613 | + } | |
| 614 | + } else if (spec->ethertype != 0xffff && | |
| 615 | + (DR_MASK_IS_SRC_IP_SET(spec) || DR_MASK_IS_DST_IP_SET(spec))) { | |
| 616 | + mlx5dr_err(dmn, | |
| 617 | + "Partial/no ethertype mask with src/dst IP is not supported\n"); | |
| 618 | + return -EINVAL; | |
| 619 | + } | |
| 620 | + | |
| 621 | + return 0; | |
| 622 | +} | |
| 623 | + | |
| 605 | 624 | int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn, |
| 606 | 625 | u8 match_criteria, |
| 607 | 626 | struct mlx5dr_match_param *mask, |
| 608 | 627 | struct mlx5dr_match_param *value) |
| 609 | 628 | { |
| 610 | − if (!value && (match_criteria & DR_MATCHER_CRITERIA_MISC)) { | |
| 629 | + if (value) | |
| 630 | + return 0; | |
| 631 | + | |
| 632 | + if (match_criteria & DR_MATCHER_CRITERIA_MISC) { | |
| 611 | 633 | if (mask->misc.source_port && mask->misc.source_port != 0xffff) { |
| 612 | 634 | mlx5dr_err(dmn, |
| 613 | 635 | "Partial mask source_port is not supported\n"); |
| @@ -621,6 +643,14 @@ int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn, · 7 unmodified lines | ||
| 621 | 643 | } |
| 622 | 644 | } |
| 623 | 645 | |
| 646 | + if ((match_criteria & DR_MATCHER_CRITERIA_OUTER) && | |
| 647 | + dr_ste_build_pre_check_spec(dmn, &mask->outer)) | |
| 648 | + return -EINVAL; | |
| 649 | + | |
| 650 | + if ((match_criteria & DR_MATCHER_CRITERIA_INNER) && | |
| 651 | + dr_ste_build_pre_check_spec(dmn, &mask->inner)) | |
| 652 | + return -EINVAL; | |
| 653 | + | |
| 624 | 654 | return 0; |
| 625 | 655 | } |
| 626 | 656 | |
| @@ -798,6 +798,16 @@ struct mlx5dr_match_param { · 797 unmodified lines | ||
| 798 | 798 | (_misc3)->icmpv4_code || \ |
| 799 | 799 | (_misc3)->icmpv4_header_data) |
| 800 | 800 | |
| 801 | +#define DR_MASK_IS_SRC_IP_SET(_spec) ((_spec)->src_ip_127_96 || \ | |
| 802 | + (_spec)->src_ip_95_64 || \ | |
| 803 | + (_spec)->src_ip_63_32 || \ | |
| 804 | + (_spec)->src_ip_31_0) | |
| 805 | + | |
| 806 | +#define DR_MASK_IS_DST_IP_SET(_spec) ((_spec)->dst_ip_127_96 || \ | |
| 807 | + (_spec)->dst_ip_95_64 || \ | |
| 808 | + (_spec)->dst_ip_63_32 || \ | |
| 809 | + (_spec)->dst_ip_31_0) | |
| 810 | + | |
| 801 | 811 | struct mlx5dr_esw_caps { |
| 802 | 812 | u64 drop_icm_address_rx; |
| 803 | 813 | u64 drop_icm_address_tx; |
| @@ -233,7 +233,11 @@ static bool contain_vport_reformat_action(struct mlx5_flow_rule *dst) · 232 unmodified lines | ||
| 233 | 233 | dst->dest_attr.vport.flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID; |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | −#define MLX5_FLOW_CONTEXT_ACTION_MAX 32 | |
| 236 | +/* We want to support a rule with 32 destinations, which means we need to | |
| 237 | + * account for 32 destinations plus usually a counter plus one more action | |
| 238 | + * for a multi-destination flow table. | |
| 239 | + */ | |
| 240 | +#define MLX5_FLOW_CONTEXT_ACTION_MAX 34 | |
| 237 | 241 | static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns, |
| 238 | 242 | struct mlx5_flow_table *ft, |
| 239 | 243 | struct mlx5_flow_group *group, |
| @@ -403,9 +407,9 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns, · 163 unmodified lines | ||
| 403 | 407 | enum mlx5_flow_destination_type type = dst->dest_attr.type; |
| 404 | 408 | u32 id; |
| 405 | 409 | |
| 406 | − if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX || | |
| 407 | − num_term_actions >= MLX5_FLOW_CONTEXT_ACTION_MAX) { | |
| 408 | − err = -ENOSPC; | |
| 410 | + if (fs_dr_num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX || | |
| 411 | + num_term_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) { | |
| 412 | + err = -EOPNOTSUPP; | |
| 409 | 413 | goto free_actions; |
| 410 | 414 | } |
| 411 | 415 | |
| @@ -478,8 +482,9 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns, · 66 unmodified lines | ||
| 478 | 482 | MLX5_FLOW_DESTINATION_TYPE_COUNTER) |
| 479 | 483 | continue; |
| 480 | 484 | |
| 481 | − if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) { | |
| 482 | − err = -ENOSPC; | |
| 485 | + if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX || | |
| 486 | + fs_dr_num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) { | |
| 487 | + err = -EOPNOTSUPP; | |
| 483 | 488 | goto free_actions; |
| 484 | 489 | } |
| 485 | 490 | |
| @@ -499,14 +504,28 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns, · 13 unmodified lines | ||
| 499 | 504 | params.match_sz = match_sz; |
| 500 | 505 | params.match_buf = (u64 *)fte->val; |
| 501 | 506 | if (num_term_actions == 1) { |
| 502 | − if (term_actions->reformat) | |
| 507 | + if (term_actions->reformat) { | |
| 508 | + if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) { | |
| 509 | + err = -EOPNOTSUPP; | |
| 510 | + goto free_actions; | |
| 511 | + } | |
| 503 | 512 | actions[num_actions++] = term_actions->reformat; |
| 513 | + } | |
| 504 | 514 | |
| 515 | + if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) { | |
| 516 | + err = -EOPNOTSUPP; | |
| 517 | + goto free_actions; | |
| 518 | + } | |
| 505 | 519 | actions[num_actions++] = term_actions->dest; |
| 506 | 520 | } else if (num_term_actions > 1) { |
| 507 | 521 | bool ignore_flow_level = |
| 508 | 522 | !!(fte->action.flags & FLOW_ACT_IGNORE_FLOW_LEVEL); |
| 509 | 523 | |
| 524 | + if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX || | |
| 525 | + fs_dr_num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) { | |
| 526 | + err = -EOPNOTSUPP; | |
| 527 | + goto free_actions; | |
| 528 | + } | |
| 510 | 529 | tmp_action = mlx5dr_action_create_mult_dest_tbl(domain, |
| 511 | 530 | term_actions, |
| 512 | 531 | num_term_actions, |
| @@ -160,6 +160,11 @@ struct mlx5dr_icm_buddy_mem { · 159 unmodified lines | ||
| 160 | 160 | * sync_ste command sets them free. |
| 161 | 161 | */ |
| 162 | 162 | struct list_head hot_list; |
| 163 | + | |
| 164 | + /* Memory optimisation */ | |
| 165 | + struct mlx5dr_ste *ste_arr; | |
| 166 | + struct list_head *miss_list; | |
| 167 | + u8 *hw_ste_arr; | |
| 163 | 168 | }; |
| 164 | 169 | |
| 165 | 170 | int mlx5dr_buddy_init(struct mlx5dr_icm_buddy_mem *buddy, |
| @@ -922,8 +922,8 @@ nfp_tunnel_add_shared_mac(struct nfp_app *app, struct net_device *netdev, · 921 unmodified lines | ||
| 922 | 922 | int port, bool mod) |
| 923 | 923 | { |
| 924 | 924 | struct nfp_flower_priv *priv = app->priv; |
| 925 | − int ida_idx = NFP_MAX_MAC_INDEX, err; | |
| 926 | 925 | struct nfp_tun_offloaded_mac *entry; |
| 926 | + int ida_idx = -1, err; | |
| 927 | 927 | u16 nfp_mac_idx = 0; |
| 928 | 928 | |
| 929 | 929 | entry = nfp_tunnel_lookup_offloaded_macs(app, netdev->dev_addr); |
| @@ -997,7 +997,7 @@ err_remove_hash: · 67 unmodified lines | ||
| 997 | 997 | err_free_entry: |
| 998 | 998 | kfree(entry); |
| 999 | 999 | err_free_ida: |
| 1000 | − if (ida_idx != NFP_MAX_MAC_INDEX) | |
| 1000 | + if (ida_idx != -1) | |
| 1001 | 1001 | ida_simple_remove(&priv->tun.mac_off_ids, ida_idx); |
| 1002 | 1002 | |
| 1003 | 1003 | return err; |
| @@ -1434,6 +1434,8 @@ static int temac_probe(struct platform_device *pdev) · 1433 unmodified lines | ||
| 1434 | 1434 | lp->indirect_lock = devm_kmalloc(&pdev->dev, |
| 1435 | 1435 | sizeof(*lp->indirect_lock), |
| 1436 | 1436 | GFP_KERNEL); |
| 1437 | + if (!lp->indirect_lock) | |
| 1438 | + return -ENOMEM; | |
| 1437 | 1439 | spin_lock_init(lp->indirect_lock); |
| 1438 | 1440 | } |
| 1439 | 1441 | |
| @@ -668,11 +668,11 @@ static void sixpack_close(struct tty_struct *tty) · 667 unmodified lines | ||
| 668 | 668 | */ |
| 669 | 669 | netif_stop_queue(sp->dev); |
| 670 | 670 | |
| 671 | + unregister_netdev(sp->dev); | |
| 672 | + | |
| 671 | 673 | del_timer_sync(&sp->tx_t); |
| 672 | 674 | del_timer_sync(&sp->resync_t); |
| 673 | 675 | |
| 674 | − unregister_netdev(sp->dev); | |
| 675 | − | |
| 676 | 676 | /* Free all 6pack frame buffers after unreg. */ |
| 677 | 677 | kfree(sp->rbuff); |
| 678 | 678 | kfree(sp->xbuff); |
| @@ -200,7 +200,11 @@ static int ipq_mdio_reset(struct mii_bus *bus) · 199 unmodified lines | ||
| 200 | 200 | if (ret) |
| 201 | 201 | return ret; |
| 202 | 202 | |
| 203 | − return clk_prepare_enable(priv->mdio_clk); | |
| 203 | + ret = clk_prepare_enable(priv->mdio_clk); | |
| 204 | + if (ret == 0) | |
| 205 | + mdelay(10); | |
| 206 | + | |
| 207 | + return ret; | |
| 204 | 208 | } |
| 205 | 209 | |
| 206 | 210 | static int ipq4019_mdio_probe(struct platform_device *pdev) |
| @@ -413,7 +413,7 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb) · 412 unmodified lines | ||
| 413 | 413 | /* ignore the CRC length */ |
| 414 | 414 | len = (skb->data[1] | (skb->data[2] << 8)) - 4; |
| 415 | 415 | |
| 416 | − if (len > ETH_FRAME_LEN) | |
| 416 | + if (len > ETH_FRAME_LEN || len > skb->len) | |
| 417 | 417 | return 0; |
| 418 | 418 | |
| 419 | 419 | /* the last packet of current skb */ |
| @@ -256,6 +256,7 @@ static void backend_disconnect(struct backend_info *be) · 255 unmodified lines | ||
| 256 | 256 | unsigned int queue_index; |
| 257 | 257 | |
| 258 | 258 | xen_unregister_watchers(vif); |
| 259 | + xenbus_rm(XBT_NIL, be->dev->nodename, "hotplug-status"); | |
| 259 | 260 | #ifdef CONFIG_DEBUG_FS |
| 260 | 261 | xenvif_debugfs_delif(vif); |
| 261 | 262 | #endif /* CONFIG_DEBUG_FS */ |
| @@ -675,7 +676,6 @@ static void hotplug_status_changed(struct xenbus_watch *watch, · 413 unmodified lines | ||
| 675 | 676 | |
| 676 | 677 | /* Not interested in this watch anymore. */ |
| 677 | 678 | unregister_hotplug_status_watch(be); |
| 678 | − xenbus_rm(XBT_NIL, be->dev->nodename, "hotplug-status"); | |
| 679 | 679 | } |
| 680 | 680 | kfree(str); |
| 681 | 681 | } |
| @@ -824,15 +824,11 @@ static void connect(struct backend_info *be) · 142 unmodified lines | ||
| 824 | 824 | xenvif_carrier_on(be->vif); |
| 825 | 825 | |
| 826 | 826 | unregister_hotplug_status_watch(be); |
| 827 | − if (xenbus_exists(XBT_NIL, dev->nodename, "hotplug-status")) { | |
| 828 | − err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, | |
| 829 | − NULL, hotplug_status_changed, | |
| 830 | − "%s/%s", dev->nodename, | |
| 831 | − "hotplug-status"); | |
| 832 | − if (err) | |
| 833 | − goto err; | |
| 827 | + err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, NULL, | |
| 828 | + hotplug_status_changed, | |
| 829 | + "%s/%s", dev->nodename, "hotplug-status"); | |
| 830 | + if (!err) | |
| 834 | 831 | be->have_hotplug_status_watch = 1; |
| 835 | − } | |
| 836 | 832 | |
| 837 | 833 | netif_tx_wake_all_queues(be->vif->dev); |
| 838 | 834 | |
| @@ -1723,7 +1723,7 @@ static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns, · 1722 unmodified lines | ||
| 1723 | 1723 | return 0; |
| 1724 | 1724 | } |
| 1725 | 1725 | |
| 1726 | −static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) | |
| 1726 | +static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) | |
| 1727 | 1727 | { |
| 1728 | 1728 | struct nvme_ctrl *ctrl = ns->ctrl; |
| 1729 | 1729 | |
| @@ -1739,7 +1739,8 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) · 9 unmodified lines | ||
| 1739 | 1739 | |
| 1740 | 1740 | ns->features &= ~(NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS); |
| 1741 | 1741 | if (!ns->ms || !(ctrl->ops->flags & NVME_F_METADATA_SUPPORTED)) |
| 1742 | − return 0; | |
| 1742 | + return; | |
| 1743 | + | |
| 1743 | 1744 | if (ctrl->ops->flags & NVME_F_FABRICS) { |
| 1744 | 1745 | /* |
| 1745 | 1746 | * The NVMe over Fabrics specification only supports metadata as |
| @@ -1747,7 +1748,7 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) · 1 unmodified line | ||
| 1747 | 1748 | * remap the separate metadata buffer from the block layer. |
| 1748 | 1749 | */ |
| 1749 | 1750 | if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT))) |
| 1750 | − return -EINVAL; | |
| 1751 | + return; | |
| 1751 | 1752 | |
| 1752 | 1753 | ns->features |= NVME_NS_EXT_LBAS; |
| 1753 | 1754 | |
| @@ -1774,8 +1775,6 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) · 20 unmodified lines | ||
| 1774 | 1775 | else |
| 1775 | 1776 | ns->features |= NVME_NS_METADATA_SUPPORTED; |
| 1776 | 1777 | } |
| 1777 | − | |
| 1778 | − return 0; | |
| 1779 | 1778 | } |
| 1780 | 1779 | |
| 1781 | 1780 | static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, |
| @@ -1916,9 +1915,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id) · 134 unmodified lines | ||
| 1916 | 1915 | ns->lba_shift = id->lbaf[lbaf].ds; |
| 1917 | 1916 | nvme_set_queue_limits(ns->ctrl, ns->queue); |
| 1918 | 1917 | |
| 1919 | − ret = nvme_configure_metadata(ns, id); | |
| 1920 | − if (ret) | |
| 1921 | − goto out_unfreeze; | |
| 1918 | + nvme_configure_metadata(ns, id); | |
| 1922 | 1919 | nvme_set_chunk_sectors(ns, id); |
| 1923 | 1920 | nvme_update_disk_info(ns->disk, ns, id); |
| 1924 | 1921 | |
| @@ -1934,7 +1931,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id) · 9 unmodified lines | ||
| 1934 | 1931 | if (blk_queue_is_zoned(ns->queue)) { |
| 1935 | 1932 | ret = nvme_revalidate_zones(ns); |
| 1936 | 1933 | if (ret && !nvme_first_scan(ns->disk)) |
| 1937 | − goto out; | |
| 1934 | + return ret; | |
| 1938 | 1935 | } |
| 1939 | 1936 | |
| 1940 | 1937 | if (nvme_ns_head_multipath(ns->head)) { |
| @@ -1949,16 +1946,16 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id) · 8 unmodified lines | ||
| 1949 | 1946 | return 0; |
| 1950 | 1947 | |
| 1951 | 1948 | out_unfreeze: |
| 1952 | − blk_mq_unfreeze_queue(ns->disk->queue); | |
| 1953 | −out: | |
| 1954 | 1949 | /* |
| 1955 | 1950 | * If probing fails due an unsupported feature, hide the block device, |
| 1956 | 1951 | * but still allow other access. |
| 1957 | 1952 | */ |
| 1958 | 1953 | if (ret == -ENODEV) { |
| 1959 | 1954 | ns->disk->flags |= GENHD_FL_HIDDEN; |
| 1955 | + set_bit(NVME_NS_READY, &ns->flags); | |
| 1960 | 1956 | ret = 0; |
| 1961 | 1957 | } |
| 1958 | + blk_mq_unfreeze_queue(ns->disk->queue); | |
| 1962 | 1959 | return ret; |
| 1963 | 1960 | } |
| 1964 | 1961 | |
| @@ -4574,7 +4571,7 @@ static void nvme_set_queue_dying(struct nvme_ns *ns) · 2609 unmodified lines | ||
| 4574 | 4571 | if (test_and_set_bit(NVME_NS_DEAD, &ns->flags)) |
| 4575 | 4572 | return; |
| 4576 | 4573 | |
| 4577 | − blk_set_queue_dying(ns->queue); | |
| 4574 | + blk_mark_disk_dead(ns->disk); | |
| 4578 | 4575 | nvme_start_ns_queue(ns); |
| 4579 | 4576 | |
| 4580 | 4577 | set_capacity_and_notify(ns->disk, 0); |
| @@ -848,7 +848,7 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) · 847 unmodified lines | ||
| 848 | 848 | { |
| 849 | 849 | if (!head->disk) |
| 850 | 850 | return; |
| 851 | − blk_set_queue_dying(head->disk->queue); | |
| 851 | + blk_mark_disk_dead(head->disk); | |
| 852 | 852 | /* make sure all pending bios are cleaned up */ |
| 853 | 853 | kblockd_schedule_work(&head->requeue_work); |
| 854 | 854 | flush_work(&head->requeue_work); |
| @@ -44,6 +44,8 @@ struct nvme_tcp_request { · 43 unmodified lines | ||
| 44 | 44 | u32 data_len; |
| 45 | 45 | u32 pdu_len; |
| 46 | 46 | u32 pdu_sent; |
| 47 | + u32 h2cdata_left; | |
| 48 | + u32 h2cdata_offset; | |
| 47 | 49 | u16 ttag; |
| 48 | 50 | __le16 status; |
| 49 | 51 | struct list_head entry; |
| @@ -95,6 +97,7 @@ struct nvme_tcp_queue { · 45 unmodified lines | ||
| 95 | 97 | struct nvme_tcp_request *request; |
| 96 | 98 | |
| 97 | 99 | int queue_size; |
| 100 | + u32 maxh2cdata; | |
| 98 | 101 | size_t cmnd_capsule_len; |
| 99 | 102 | struct nvme_tcp_ctrl *ctrl; |
| 100 | 103 | unsigned long flags; |
| @@ -572,23 +575,26 @@ static int nvme_tcp_handle_comp(struct nvme_tcp_queue *queue, · 471 unmodified lines | ||
| 572 | 575 | return ret; |
| 573 | 576 | } |
| 574 | 577 | |
| 575 | −static void nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req, | |
| 576 | − struct nvme_tcp_r2t_pdu *pdu) | |
| 578 | +static void nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req) | |
| 577 | 579 | { |
| 578 | 580 | struct nvme_tcp_data_pdu *data = req->pdu; |
| 579 | 581 | struct nvme_tcp_queue *queue = req->queue; |
| 580 | 582 | struct request *rq = blk_mq_rq_from_pdu(req); |
| 583 | + u32 h2cdata_sent = req->pdu_len; | |
| 581 | 584 | u8 hdgst = nvme_tcp_hdgst_len(queue); |
| 582 | 585 | u8 ddgst = nvme_tcp_ddgst_len(queue); |
| 583 | 586 | |
| 584 | 587 | req->state = NVME_TCP_SEND_H2C_PDU; |
| 585 | 588 | req->offset = 0; |
| 586 | − req->pdu_len = le32_to_cpu(pdu->r2t_length); | |
| 589 | + req->pdu_len = min(req->h2cdata_left, queue->maxh2cdata); | |
| 587 | 590 | req->pdu_sent = 0; |
| 591 | + req->h2cdata_left -= req->pdu_len; | |
| 592 | + req->h2cdata_offset += h2cdata_sent; | |
| 588 | 593 | |
| 589 | 594 | memset(data, 0, sizeof(*data)); |
| 590 | 595 | data->hdr.type = nvme_tcp_h2c_data; |
| 591 | − data->hdr.flags = NVME_TCP_F_DATA_LAST; | |
| 596 | + if (!req->h2cdata_left) | |
| 597 | + data->hdr.flags = NVME_TCP_F_DATA_LAST; | |
| 592 | 598 | if (queue->hdr_digest) |
| 593 | 599 | data->hdr.flags |= NVME_TCP_F_HDGST; |
| 594 | 600 | if (queue->data_digest) |
| @@ -597,9 +603,9 @@ static void nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req, · 2 unmodified lines | ||
| 597 | 603 | data->hdr.pdo = data->hdr.hlen + hdgst; |
| 598 | 604 | data->hdr.plen = |
| 599 | 605 | cpu_to_le32(data->hdr.hlen + hdgst + req->pdu_len + ddgst); |
| 600 | − data->ttag = pdu->ttag; | |
| 606 | + data->ttag = req->ttag; | |
| 601 | 607 | data->command_id = nvme_cid(rq); |
| 602 | − data->data_offset = pdu->r2t_offset; | |
| 608 | + data->data_offset = cpu_to_le32(req->h2cdata_offset); | |
| 603 | 609 | data->data_length = cpu_to_le32(req->pdu_len); |
| 604 | 610 | } |
| 605 | 611 | |
| @@ -609,6 +615,7 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue, · 3 unmodified lines | ||
| 609 | 615 | struct nvme_tcp_request *req; |
| 610 | 616 | struct request *rq; |
| 611 | 617 | u32 r2t_length = le32_to_cpu(pdu->r2t_length); |
| 618 | + u32 r2t_offset = le32_to_cpu(pdu->r2t_offset); | |
| 612 | 619 | |
| 613 | 620 | rq = nvme_find_rq(nvme_tcp_tagset(queue), pdu->command_id); |
| 614 | 621 | if (!rq) { |
| @@ -633,14 +640,19 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue, · 18 unmodified lines | ||
| 633 | 640 | return -EPROTO; |
| 634 | 641 | } |
| 635 | 642 | |
| 636 | − if (unlikely(le32_to_cpu(pdu->r2t_offset) < req->data_sent)) { | |
| 643 | + if (unlikely(r2t_offset < req->data_sent)) { | |
| 637 | 644 | dev_err(queue->ctrl->ctrl.device, |
| 638 | 645 | "req %d unexpected r2t offset %u (expected %zu)\n", |
| 639 | − rq->tag, le32_to_cpu(pdu->r2t_offset), req->data_sent); | |
| 646 | + rq->tag, r2t_offset, req->data_sent); | |
| 640 | 647 | return -EPROTO; |
| 641 | 648 | } |
| 642 | 649 | |
| 643 | − nvme_tcp_setup_h2c_data_pdu(req, pdu); | |
| 650 | + req->pdu_len = 0; | |
| 651 | + req->h2cdata_left = r2t_length; | |
| 652 | + req->h2cdata_offset = r2t_offset; | |
| 653 | + req->ttag = pdu->ttag; | |
| 654 | + | |
| 655 | + nvme_tcp_setup_h2c_data_pdu(req); | |
| 644 | 656 | nvme_tcp_queue_request(req, false, true); |
| 645 | 657 | |
| 646 | 658 | return 0; |
| @@ -928,6 +940,7 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req) · 281 unmodified lines | ||
| 928 | 940 | { |
| 929 | 941 | struct nvme_tcp_queue *queue = req->queue; |
| 930 | 942 | int req_data_len = req->data_len; |
| 943 | + u32 h2cdata_left = req->h2cdata_left; | |
| 931 | 944 | |
| 932 | 945 | while (true) { |
| 933 | 946 | struct page *page = nvme_tcp_req_cur_page(req); |
| @@ -972,7 +985,10 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req) · 38 unmodified lines | ||
| 972 | 985 | req->state = NVME_TCP_SEND_DDGST; |
| 973 | 986 | req->offset = 0; |
| 974 | 987 | } else { |
| 975 | − nvme_tcp_done_send_req(queue); | |
| 988 | + if (h2cdata_left) | |
| 989 | + nvme_tcp_setup_h2c_data_pdu(req); | |
| 990 | + else | |
| 991 | + nvme_tcp_done_send_req(queue); | |
| 976 | 992 | } |
| 977 | 993 | return 1; |
| 978 | 994 | } |
| @@ -1030,9 +1046,14 @@ static int nvme_tcp_try_send_data_pdu(struct nvme_tcp_request *req) · 51 unmodified lines | ||
| 1030 | 1046 | if (queue->hdr_digest && !req->offset) |
| 1031 | 1047 | nvme_tcp_hdgst(queue->snd_hash, pdu, sizeof(*pdu)); |
| 1032 | 1048 | |
| 1033 | − ret = kernel_sendpage(queue->sock, virt_to_page(pdu), | |
| 1034 | − offset_in_page(pdu) + req->offset, len, | |
| 1035 | − MSG_DONTWAIT | MSG_MORE | MSG_SENDPAGE_NOTLAST); | |
| 1049 | + if (!req->h2cdata_left) | |
| 1050 | + ret = kernel_sendpage(queue->sock, virt_to_page(pdu), | |
| 1051 | + offset_in_page(pdu) + req->offset, len, | |
| 1052 | + MSG_DONTWAIT | MSG_MORE | MSG_SENDPAGE_NOTLAST); | |
| 1053 | + else | |
| 1054 | + ret = sock_no_sendpage(queue->sock, virt_to_page(pdu), | |
| 1055 | + offset_in_page(pdu) + req->offset, len, | |
| 1056 | + MSG_DONTWAIT | MSG_MORE); | |
| 1036 | 1057 | if (unlikely(ret <= 0)) |
| 1037 | 1058 | return ret; |
| 1038 | 1059 | |
| @@ -1052,6 +1073,7 @@ static int nvme_tcp_try_send_ddgst(struct nvme_tcp_request *req) · 13 unmodified lines | ||
| 1052 | 1073 | { |
| 1053 | 1074 | struct nvme_tcp_queue *queue = req->queue; |
| 1054 | 1075 | size_t offset = req->offset; |
| 1076 | + u32 h2cdata_left = req->h2cdata_left; | |
| 1055 | 1077 | int ret; |
| 1056 | 1078 | struct msghdr msg = { .msg_flags = MSG_DONTWAIT }; |
| 1057 | 1079 | struct kvec iov = { |
| @@ -1069,7 +1091,10 @@ static int nvme_tcp_try_send_ddgst(struct nvme_tcp_request *req) · 11 unmodified lines | ||
| 1069 | 1091 | return ret; |
| 1070 | 1092 | |
| 1071 | 1093 | if (offset + ret == NVME_TCP_DIGEST_LENGTH) { |
| 1072 | − nvme_tcp_done_send_req(queue); | |
| 1094 | + if (h2cdata_left) | |
| 1095 | + nvme_tcp_setup_h2c_data_pdu(req); | |
| 1096 | + else | |
| 1097 | + nvme_tcp_done_send_req(queue); | |
| 1073 | 1098 | return 1; |
| 1074 | 1099 | } |
| 1075 | 1100 | |
| @@ -1261,6 +1286,7 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue) · 185 unmodified lines | ||
| 1261 | 1286 | struct msghdr msg = {}; |
| 1262 | 1287 | struct kvec iov; |
| 1263 | 1288 | bool ctrl_hdgst, ctrl_ddgst; |
| 1289 | + u32 maxh2cdata; | |
| 1264 | 1290 | int ret; |
| 1265 | 1291 | |
| 1266 | 1292 | icreq = kzalloc(sizeof(*icreq), GFP_KERNEL); |
| @@ -1344,6 +1370,14 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue) · 77 unmodified lines | ||
| 1344 | 1370 | goto free_icresp; |
| 1345 | 1371 | } |
| 1346 | 1372 | |
| 1373 | + maxh2cdata = le32_to_cpu(icresp->maxdata); | |
| 1374 | + if ((maxh2cdata % 4) || (maxh2cdata < NVME_TCP_MIN_MAXH2CDATA)) { | |
| 1375 | + pr_err("queue %d: invalid maxh2cdata returned %u\n", | |
| 1376 | + nvme_tcp_queue_id(queue), maxh2cdata); | |
| 1377 | + goto free_icresp; | |
| 1378 | + } | |
| 1379 | + queue->maxh2cdata = maxh2cdata; | |
| 1380 | + | |
| 1347 | 1381 | ret = 0; |
| 1348 | 1382 | free_icresp: |
| 1349 | 1383 | kfree(icresp); |
| @@ -2329,6 +2363,7 @@ static blk_status_t nvme_tcp_setup_cmd_pdu(struct nvme_ns *ns, · 979 unmodified lines | ||
| 2329 | 2363 | req->data_sent = 0; |
| 2330 | 2364 | req->pdu_len = 0; |
| 2331 | 2365 | req->pdu_sent = 0; |
| 2366 | + req->h2cdata_left = 0; | |
| 2332 | 2367 | req->data_len = blk_rq_nr_phys_segments(rq) ? |
| 2333 | 2368 | blk_rq_payload_bytes(rq) : 0; |
| 2334 | 2369 | req->curr_bio = rq->bio; |
| @@ -648,8 +648,8 @@ void __init early_init_fdt_scan_reserved_mem(void) · 647 unmodified lines | ||
| 648 | 648 | } |
| 649 | 649 | |
| 650 | 650 | fdt_scan_reserved_mem(); |
| 651 | − fdt_init_reserved_mem(); | |
| 652 | 651 | fdt_reserve_elfcorehdr(); |
| 652 | + fdt_init_reserved_mem(); | |
| 653 | 653 | } |
| 654 | 654 | |
| 655 | 655 | /** |
| @@ -513,24 +513,24 @@ static void __init of_unittest_parse_phandle_with_args(void) · 512 unmodified lines | ||
| 513 | 513 | memset(&args, 0, sizeof(args)); |
| 514 | 514 | |
| 515 | 515 | EXPECT_BEGIN(KERN_INFO, |
| 516 | − "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1"); | |
| 516 | + "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1"); | |
| 517 | 517 | |
| 518 | 518 | rc = of_parse_phandle_with_args(np, "phandle-list-bad-args", |
| 519 | 519 | "#phandle-cells", 1, &args); |
| 520 | 520 | |
| 521 | 521 | EXPECT_END(KERN_INFO, |
| 522 | − "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1"); | |
| 522 | + "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1"); | |
| 523 | 523 | |
| 524 | 524 | unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); |
| 525 | 525 | |
| 526 | 526 | EXPECT_BEGIN(KERN_INFO, |
| 527 | − "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1"); | |
| 527 | + "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1"); | |
| 528 | 528 | |
| 529 | 529 | rc = of_count_phandle_with_args(np, "phandle-list-bad-args", |
| 530 | 530 | "#phandle-cells"); |
| 531 | 531 | |
| 532 | 532 | EXPECT_END(KERN_INFO, |
| 533 | − "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1"); | |
| 533 | + "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1"); | |
| 534 | 534 | |
| 535 | 535 | unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); |
| 536 | 536 | } |
| @@ -670,12 +670,12 @@ static void __init of_unittest_parse_phandle_with_args_map(void) · 133 unmodified lines | ||
| 670 | 670 | memset(&args, 0, sizeof(args)); |
| 671 | 671 | |
| 672 | 672 | EXPECT_BEGIN(KERN_INFO, |
| 673 | − "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found -1"); | |
| 673 | + "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found 1"); | |
| 674 | 674 | |
| 675 | 675 | rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-args", |
| 676 | 676 | "phandle", 1, &args); |
| 677 | 677 | EXPECT_END(KERN_INFO, |
| 678 | − "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found -1"); | |
| 678 | + "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found 1"); | |
| 679 | 679 | |
| 680 | 680 | unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); |
| 681 | 681 | } |
| @@ -1257,12 +1257,12 @@ static void __init of_unittest_platform_populate(void) · 575 unmodified lines | ||
| 1257 | 1257 | unittest(pdev, "device 2 creation failed\n"); |
| 1258 | 1258 | |
| 1259 | 1259 | EXPECT_BEGIN(KERN_INFO, |
| 1260 | − "platform testcase-data:testcase-device2: IRQ index 0 not found"); | |
| 1260 | + "platform testcase-data:testcase-device2: error -ENXIO: IRQ index 0 not found"); | |
| 1261 | 1261 | |
| 1262 | 1262 | irq = platform_get_irq(pdev, 0); |
| 1263 | 1263 | |
| 1264 | 1264 | EXPECT_END(KERN_INFO, |
| 1265 | − "platform testcase-data:testcase-device2: IRQ index 0 not found"); | |
| 1265 | + "platform testcase-data:testcase-device2: error -ENXIO: IRQ index 0 not found"); | |
| 1266 | 1266 | |
| 1267 | 1267 | unittest(irq < 0 && irq != -EPROBE_DEFER, |
| 1268 | 1268 | "device parsing error failed - %d\n", irq); |
| @@ -1329,7 +1329,8 @@ static int mvebu_pcie_probe(struct platform_device *pdev) · 1328 unmodified lines | ||
| 1329 | 1329 | * indirectly via kernel emulated PCI bridge driver. |
| 1330 | 1330 | */ |
| 1331 | 1331 | mvebu_pcie_setup_hw(port); |
| 1332 | − mvebu_pcie_set_local_dev_nr(port, 0); | |
| 1332 | + mvebu_pcie_set_local_dev_nr(port, 1); | |
| 1333 | + mvebu_pcie_set_local_bus_nr(port, 0); | |
| 1333 | 1334 | } |
| 1334 | 1335 | |
| 1335 | 1336 | pcie->nports = i; |
| @@ -5344,11 +5344,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags); · 5343 unmodified lines | ||
| 5344 | 5344 | */ |
| 5345 | 5345 | static void quirk_amd_harvest_no_ats(struct pci_dev *pdev) |
| 5346 | 5346 | { |
| 5347 | − if ((pdev->device == 0x7312 && pdev->revision != 0x00) || | |
| 5348 | − (pdev->device == 0x7340 && pdev->revision != 0xc5) || | |
| 5349 | − (pdev->device == 0x7341 && pdev->revision != 0x00)) | |
| 5350 | − return; | |
| 5351 | − | |
| 5352 | 5347 | if (pdev->device == 0x15d8) { |
| 5353 | 5348 | if (pdev->revision == 0xcf && |
| 5354 | 5349 | pdev->subsystem_vendor == 0xea50 && |
| @@ -5370,10 +5365,19 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x98e4, quirk_amd_harvest_no_ats); · 15 unmodified lines | ||
| 5370 | 5365 | /* AMD Iceland dGPU */ |
| 5371 | 5366 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6900, quirk_amd_harvest_no_ats); |
| 5372 | 5367 | /* AMD Navi10 dGPU */ |
| 5368 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7310, quirk_amd_harvest_no_ats); | |
| 5373 | 5369 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7312, quirk_amd_harvest_no_ats); |
| 5370 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7318, quirk_amd_harvest_no_ats); | |
| 5371 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7319, quirk_amd_harvest_no_ats); | |
| 5372 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731a, quirk_amd_harvest_no_ats); | |
| 5373 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731b, quirk_amd_harvest_no_ats); | |
| 5374 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731e, quirk_amd_harvest_no_ats); | |
| 5375 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731f, quirk_amd_harvest_no_ats); | |
| 5374 | 5376 | /* AMD Navi14 dGPU */ |
| 5375 | 5377 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7340, quirk_amd_harvest_no_ats); |
| 5376 | 5378 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7341, quirk_amd_harvest_no_ats); |
| 5379 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_ats); | |
| 5380 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_ats); | |
| 5377 | 5381 | /* AMD Raven platform iGPU */ |
| 5378 | 5382 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_ats); |
| 5379 | 5383 | #endif /* CONFIG_PCI_ATS */ |
| @@ -232,14 +232,21 @@ static int mshw0011_bix(struct mshw0011_data *cdata, struct bix *bix) · 231 unmodified lines | ||
| 232 | 232 | } |
| 233 | 233 | bix->last_full_charg_capacity = ret; |
| 234 | 234 | |
| 235 | − /* get serial number */ | |
| 235 | + /* | |
| 236 | + * Get serial number, on some devices (with unofficial replacement | |
| 237 | + * battery?) reading any of the serial number range addresses gets | |
| 238 | + * nacked in this case just leave the serial number empty. | |
| 239 | + */ | |
| 236 | 240 | ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_SERIAL_NO, |
| 237 | 241 | sizeof(buf), buf); |
| 238 | − if (ret != sizeof(buf)) { | |
| 242 | + if (ret == -EREMOTEIO) { | |
| 243 | + /* no serial number available */ | |
| 244 | + } else if (ret != sizeof(buf)) { | |
| 239 | 245 | dev_err(&client->dev, "Error reading serial no: %d\n", ret); |
| 240 | 246 | return ret; |
| 247 | + } else { | |
| 248 | + snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf); | |
| 241 | 249 | } |
| 242 | − snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf); | |
| 243 | 250 | |
| 244 | 251 | /* get cycle count */ |
| 245 | 252 | ret = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CYCLE_CNT); |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/module.h> |
| 22 | 22 | #include <linux/pci.h> |
| 23 | 23 | #include <linux/platform_device.h> |
| 24 | +#include <linux/pm_qos.h> | |
| 24 | 25 | #include <linux/rtc.h> |
| 25 | 26 | #include <linux/suspend.h> |
| 26 | 27 | #include <linux/seq_file.h> |
| @@ -85,6 +86,9 @@ · 58 unmodified lines | ||
| 85 | 86 | #define PMC_MSG_DELAY_MIN_US 50 |
| 86 | 87 | #define RESPONSE_REGISTER_LOOP_MAX 20000 |
| 87 | 88 | |
| 89 | +/* QoS request for letting CPUs in idle states, but not the deepest */ | |
| 90 | +#define AMD_PMC_MAX_IDLE_STATE_LATENCY 3 | |
| 91 | + | |
| 88 | 92 | #define SOC_SUBSYSTEM_IP_MAX 12 |
| 89 | 93 | #define DELAY_MIN_US 2000 |
| 90 | 94 | #define DELAY_MAX_US 3000 |
| @@ -131,6 +135,7 @@ struct amd_pmc_dev { · 40 unmodified lines | ||
| 131 | 135 | struct device *dev; |
| 132 | 136 | struct pci_dev *rdev; |
| 133 | 137 | struct mutex lock; /* generic mutex lock */ |
| 138 | + struct pm_qos_request amd_pmc_pm_qos_req; | |
| 134 | 139 | #if IS_ENABLED(CONFIG_DEBUG_FS) |
| 135 | 140 | struct dentry *dbgfs_dir; |
| 136 | 141 | #endif /* CONFIG_DEBUG_FS */ |
| @@ -521,6 +526,14 @@ static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg) · 384 unmodified lines | ||
| 521 | 526 | rc = rtc_alarm_irq_enable(rtc_device, 0); |
| 522 | 527 | dev_dbg(pdev->dev, "wakeup timer programmed for %lld seconds\n", duration); |
| 523 | 528 | |
| 529 | + /* | |
| 530 | + * Prevent CPUs from getting into deep idle states while sending OS_HINT | |
| 531 | + * which is otherwise generally safe to send when at least one of the CPUs | |
| 532 | + * is not in deep idle states. | |
| 533 | + */ | |
| 534 | + cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req, AMD_PMC_MAX_IDLE_STATE_LATENCY); | |
| 535 | + wake_up_all_idle_cpus(); | |
| 536 | + | |
| 524 | 537 | return rc; |
| 525 | 538 | } |
| 526 | 539 | |
| @@ -538,24 +551,31 @@ static int __maybe_unused amd_pmc_suspend(struct device *dev) · 11 unmodified lines | ||
| 538 | 551 | /* Activate CZN specific RTC functionality */ |
| 539 | 552 | if (pdev->cpu_id == AMD_CPU_ID_CZN) { |
| 540 | 553 | rc = amd_pmc_verify_czn_rtc(pdev, &arg); |
| 541 | − if (rc < 0) | |
| 542 | − return rc; | |
| 554 | + if (rc) | |
| 555 | + goto fail; | |
| 543 | 556 | } |
| 544 | 557 | |
| 545 | 558 | /* Dump the IdleMask before we send hint to SMU */ |
| 546 | 559 | amd_pmc_idlemask_read(pdev, dev, NULL); |
| 547 | 560 | msg = amd_pmc_get_os_hint(pdev); |
| 548 | 561 | rc = amd_pmc_send_cmd(pdev, arg, NULL, msg, 0); |
| 549 | − if (rc) | |
| 562 | + if (rc) { | |
| 550 | 563 | dev_err(pdev->dev, "suspend failed\n"); |
| 564 | + goto fail; | |
| 565 | + } | |
| 551 | 566 | |
| 552 | 567 | if (enable_stb) |
| 553 | 568 | rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_PREDEF); |
| 554 | − if (rc) { | |
| 569 | + if (rc) { | |
| 555 | 570 | dev_err(pdev->dev, "error writing to STB\n"); |
| 556 | − return rc; | |
| 571 | + goto fail; | |
| 557 | 572 | } |
| 558 | 573 | |
| 574 | + return 0; | |
| 575 | +fail: | |
| 576 | + if (pdev->cpu_id == AMD_CPU_ID_CZN) | |
| 577 | + cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req, | |
| 578 | + PM_QOS_DEFAULT_VALUE); | |
| 559 | 579 | return rc; |
| 560 | 580 | } |
| 561 | 581 | |
| @@ -579,12 +599,15 @@ static int __maybe_unused amd_pmc_resume(struct device *dev) · 17 unmodified lines | ||
| 579 | 599 | /* Write data incremented by 1 to distinguish in stb_read */ |
| 580 | 600 | if (enable_stb) |
| 581 | 601 | rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_PREDEF + 1); |
| 582 | − if (rc) { | |
| 602 | + if (rc) | |
| 583 | 603 | dev_err(pdev->dev, "error writing to STB\n"); |
| 584 | − return rc; | |
| 585 | − } | |
| 586 | 604 | |
| 587 | − return 0; | |
| 605 | + /* Restore the QoS request back to defaults if it was set */ | |
| 606 | + if (pdev->cpu_id == AMD_CPU_ID_CZN) | |
| 607 | + cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req, | |
| 608 | + PM_QOS_DEFAULT_VALUE); | |
| 609 | + | |
| 610 | + return rc; | |
| 588 | 611 | } |
| 589 | 612 | |
| 590 | 613 | static const struct dev_pm_ops amd_pmc_pm_ops = { |
| @@ -722,6 +745,7 @@ static int amd_pmc_probe(struct platform_device *pdev) · 131 unmodified lines | ||
| 722 | 745 | amd_pmc_get_smu_version(dev); |
| 723 | 746 | platform_set_drvdata(pdev, dev); |
| 724 | 747 | amd_pmc_dbgfs_register(dev); |
| 748 | + cpu_latency_qos_add_request(&dev->amd_pmc_pm_qos_req, PM_QOS_DEFAULT_VALUE); | |
| 725 | 749 | return 0; |
| 726 | 750 | |
| 727 | 751 | err_pci_dev_put: |
| @@ -2223,7 +2223,7 @@ static int fan_curve_check_present(struct asus_wmi *asus, bool *available, · 2222 unmodified lines | ||
| 2223 | 2223 | |
| 2224 | 2224 | err = fan_curve_get_factory_default(asus, fan_dev); |
| 2225 | 2225 | if (err) { |
| 2226 | − if (err == -ENODEV) | |
| 2226 | + if (err == -ENODEV || err == -ENODATA) | |
| 2227 | 2227 | return 0; |
| 2228 | 2228 | return err; |
| 2229 | 2229 | } |
| @@ -100,7 +100,8 @@ static struct gpiod_lookup_table surface_go_tps68470_gpios = { · 99 unmodified lines | ||
| 100 | 100 | .dev_id = "i2c-INT347A:00", |
| 101 | 101 | .table = { |
| 102 | 102 | GPIO_LOOKUP("tps68470-gpio", 9, "reset", GPIO_ACTIVE_LOW), |
| 103 | − GPIO_LOOKUP("tps68470-gpio", 7, "powerdown", GPIO_ACTIVE_LOW) | |
| 103 | + GPIO_LOOKUP("tps68470-gpio", 7, "powerdown", GPIO_ACTIVE_LOW), | |
| 104 | + { } | |
| 104 | 105 | } |
| 105 | 106 | }; |
| 106 | 107 | |
| @@ -8703,6 +8703,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = { · 8702 unmodified lines | ||
| 8703 | 8703 | TPACPI_Q_LNV3('N', '4', '0', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (4nd gen) */ |
| 8704 | 8704 | TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL), /* P15 (1st gen) / P15v (1st gen) */ |
| 8705 | 8705 | TPACPI_Q_LNV3('N', '3', '2', TPACPI_FAN_2CTL), /* X1 Carbon (9th gen) */ |
| 8706 | + TPACPI_Q_LNV3('N', '3', '7', TPACPI_FAN_2CTL), /* T15g (2nd gen) */ | |
| 8706 | 8707 | TPACPI_Q_LNV3('N', '1', 'O', TPACPI_FAN_NOFAN), /* X1 Tablet (2nd gen) */ |
| 8707 | 8708 | }; |
| 8708 | 8709 | |
| @@ -1523,6 +1523,9 @@ static int bq256xx_hw_init(struct bq256xx_device *bq) · 1522 unmodified lines | ||
| 1523 | 1523 | BQ256XX_WDT_BIT_SHIFT); |
| 1524 | 1524 | |
| 1525 | 1525 | ret = power_supply_get_battery_info(bq->charger, &bat_info); |
| 1526 | + if (ret == -ENOMEM) | |
| 1527 | + return ret; | |
| 1528 | + | |
| 1526 | 1529 | if (ret) { |
| 1527 | 1530 | dev_warn(bq->dev, "battery info missing, default values will be applied\n"); |
| 1528 | 1531 | |
| @@ -689,7 +689,7 @@ static int cw_bat_probe(struct i2c_client *client) · 688 unmodified lines | ||
| 689 | 689 | if (ret) { |
| 690 | 690 | /* Allocate an empty battery */ |
| 691 | 691 | cw_bat->battery = devm_kzalloc(&client->dev, |
| 692 | − sizeof(cw_bat->battery), | |
| 692 | + sizeof(*cw_bat->battery), | |
| 693 | 693 | GFP_KERNEL); |
| 694 | 694 | if (!cw_bat->battery) |
| 695 | 695 | return -ENOMEM; |
| @@ -592,6 +592,7 @@ struct lpfc_vport { · 591 unmodified lines | ||
| 592 | 592 | #define FC_VPORT_LOGO_RCVD 0x200 /* LOGO received on vport */ |
| 593 | 593 | #define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */ |
| 594 | 594 | #define FC_LOGO_RCVD_DID_CHNG 0x800 /* FDISC on phys port detect DID chng*/ |
| 595 | +#define FC_PT2PT_NO_NVME 0x1000 /* Don't send NVME PRLI */ | |
| 595 | 596 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ |
| 596 | 597 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ |
| 597 | 598 | #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ |
| @@ -1315,6 +1315,9 @@ lpfc_issue_lip(struct Scsi_Host *shost) · 1314 unmodified lines | ||
| 1315 | 1315 | pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK; |
| 1316 | 1316 | pmboxq->u.mb.mbxOwner = OWN_HOST; |
| 1317 | 1317 | |
| 1318 | + if ((vport->fc_flag & FC_PT2PT) && (vport->fc_flag & FC_PT2PT_NO_NVME)) | |
| 1319 | + vport->fc_flag &= ~FC_PT2PT_NO_NVME; | |
| 1320 | + | |
| 1318 | 1321 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2); |
| 1319 | 1322 | |
| 1320 | 1323 | if ((mbxstatus == MBX_SUCCESS) && |
| @@ -1072,7 +1072,8 @@ stop_rr_fcf_flogi: · 1071 unmodified lines | ||
| 1072 | 1072 | |
| 1073 | 1073 | /* FLOGI failed, so there is no fabric */ |
| 1074 | 1074 | spin_lock_irq(shost->host_lock); |
| 1075 | − vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); | |
| 1075 | + vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP | | |
| 1076 | + FC_PT2PT_NO_NVME); | |
| 1076 | 1077 | spin_unlock_irq(shost->host_lock); |
| 1077 | 1078 | |
| 1078 | 1079 | /* If private loop, then allow max outstanding els to be |
| @@ -4607,6 +4608,23 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, · 3528 unmodified lines | ||
| 4607 | 4608 | /* Added for Vendor specifc support |
| 4608 | 4609 | * Just keep retrying for these Rsn / Exp codes |
| 4609 | 4610 | */ |
| 4611 | + if ((vport->fc_flag & FC_PT2PT) && | |
| 4612 | + cmd == ELS_CMD_NVMEPRLI) { | |
| 4613 | + switch (stat.un.b.lsRjtRsnCode) { | |
| 4614 | + case LSRJT_UNABLE_TPC: | |
| 4615 | + case LSRJT_INVALID_CMD: | |
| 4616 | + case LSRJT_LOGICAL_ERR: | |
| 4617 | + case LSRJT_CMD_UNSUPPORTED: | |
| 4618 | + lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS, | |
| 4619 | + "0168 NVME PRLI LS_RJT " | |
| 4620 | + "reason %x port doesn't " | |
| 4621 | + "support NVME, disabling NVME\n", | |
| 4622 | + stat.un.b.lsRjtRsnCode); | |
| 4623 | + retry = 0; | |
| 4624 | + vport->fc_flag |= FC_PT2PT_NO_NVME; | |
| 4625 | + goto out_retry; | |
| 4626 | + } | |
| 4627 | + } | |
| 4610 | 4628 | switch (stat.un.b.lsRjtRsnCode) { |
| 4611 | 4629 | case LSRJT_UNABLE_TPC: |
| 4612 | 4630 | /* The driver has a VALID PLOGI but the rport has |
| @@ -1961,8 +1961,9 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, · 1960 unmodified lines | ||
| 1961 | 1961 | * is configured try it. |
| 1962 | 1962 | */ |
| 1963 | 1963 | ndlp->nlp_fc4_type |= NLP_FC4_FCP; |
| 1964 | − if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || | |
| 1965 | − (vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) { | |
| 1964 | + if ((!(vport->fc_flag & FC_PT2PT_NO_NVME)) && | |
| 1965 | + (vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH || | |
| 1966 | + vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) { | |
| 1966 | 1967 | ndlp->nlp_fc4_type |= NLP_FC4_NVME; |
| 1967 | 1968 | /* We need to update the localport also */ |
| 1968 | 1969 | lpfc_nvme_update_localport(vport); |
| @@ -771,11 +771,10 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi, · 770 unmodified lines | ||
| 771 | 771 | qedi_cmd->list_tmf_work = NULL; |
| 772 | 772 | } |
| 773 | 773 | } |
| 774 | + spin_unlock_bh(&qedi_conn->tmf_work_lock); | |
| 774 | 775 | |
| 775 | − if (!found) { | |
| 776 | − spin_unlock_bh(&qedi_conn->tmf_work_lock); | |
| 776 | + if (!found) | |
| 777 | 777 | goto check_cleanup_reqs; |
| 778 | − } | |
| 779 | 778 | |
| 780 | 779 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_SCSI_TM, |
| 781 | 780 | "TMF work, cqe->tid=0x%x, tmf flags=0x%x, cid=0x%x\n", |
| @@ -806,7 +805,6 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi, · 24 unmodified lines | ||
| 806 | 805 | qedi_cmd->state = CLEANUP_RECV; |
| 807 | 806 | unlock: |
| 808 | 807 | spin_unlock_bh(&conn->session->back_lock); |
| 809 | − spin_unlock_bh(&qedi_conn->tmf_work_lock); | |
| 810 | 808 | wake_up_interruptible(&qedi_conn->wait_queue); |
| 811 | 809 | return; |
| 812 | 810 | |
| @@ -2681,7 +2681,7 @@ static int ufshcd_map_queues(struct Scsi_Host *shost) · 2680 unmodified lines | ||
| 2681 | 2681 | break; |
| 2682 | 2682 | case HCTX_TYPE_READ: |
| 2683 | 2683 | map->nr_queues = 0; |
| 2684 | − break; | |
| 2684 | + continue; | |
| 2685 | 2685 | default: |
| 2686 | 2686 | WARN_ON_ONCE(true); |
| 2687 | 2687 | } |
| @@ -411,17 +411,12 @@ out: · 410 unmodified lines | ||
| 411 | 411 | return ret; |
| 412 | 412 | } |
| 413 | 413 | |
| 414 | −static int init_clks(struct platform_device *pdev, struct clk **clk) | |
| 414 | +static void init_clks(struct platform_device *pdev, struct clk **clk) | |
| 415 | 415 | { |
| 416 | 416 | int i; |
| 417 | 417 | |
| 418 | − for (i = CLK_NONE + 1; i < CLK_MAX; i++) { | |
| 418 | + for (i = CLK_NONE + 1; i < CLK_MAX; i++) | |
| 419 | 419 | clk[i] = devm_clk_get(&pdev->dev, clk_names[i]); |
| 420 | − if (IS_ERR(clk[i])) | |
| 421 | − return PTR_ERR(clk[i]); | |
| 422 | − } | |
| 423 | − | |
| 424 | − return 0; | |
| 425 | 420 | } |
| 426 | 421 | |
| 427 | 422 | static struct scp *init_scp(struct platform_device *pdev, |
| @@ -431,7 +426,7 @@ static struct scp *init_scp(struct platform_device *pdev, · 3 unmodified lines | ||
| 431 | 426 | { |
| 432 | 427 | struct genpd_onecell_data *pd_data; |
| 433 | 428 | struct resource *res; |
| 434 | − int i, j, ret; | |
| 429 | + int i, j; | |
| 435 | 430 | struct scp *scp; |
| 436 | 431 | struct clk *clk[CLK_MAX]; |
| 437 | 432 | |
| @@ -486,9 +481,7 @@ static struct scp *init_scp(struct platform_device *pdev, · 48 unmodified lines | ||
| 486 | 481 | |
| 487 | 482 | pd_data->num_domains = num; |
| 488 | 483 | |
| 489 | − ret = init_clks(pdev, clk); | |
| 490 | − if (ret) | |
| 491 | − return ERR_PTR(ret); | |
| 484 | + init_clks(pdev, clk); | |
| 492 | 485 | |
| 493 | 486 | for (i = 0; i < num; i++) { |
| 494 | 487 | struct scp_domain *scpd = &scp->domains[i]; |
| @@ -629,16 +629,18 @@ err: · 628 unmodified lines | ||
| 629 | 629 | return ret; |
| 630 | 630 | } |
| 631 | 631 | |
| 632 | −static int vhost_vsock_stop(struct vhost_vsock *vsock) | |
| 632 | +static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner) | |
| 633 | 633 | { |
| 634 | 634 | size_t i; |
| 635 | − int ret; | |
| 635 | + int ret = 0; | |
| 636 | 636 | |
| 637 | 637 | mutex_lock(&vsock->dev.mutex); |
| 638 | 638 | |
| 639 | − ret = vhost_dev_check_owner(&vsock->dev); | |
| 640 | − if (ret) | |
| 641 | − goto err; | |
| 639 | + if (check_owner) { | |
| 640 | + ret = vhost_dev_check_owner(&vsock->dev); | |
| 641 | + if (ret) | |
| 642 | + goto err; | |
| 643 | + } | |
| 642 | 644 | |
| 643 | 645 | for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { |
| 644 | 646 | struct vhost_virtqueue *vq = &vsock->vqs[i]; |
| @@ -753,7 +755,12 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file) · 108 unmodified lines | ||
| 753 | 755 | * inefficient. Room for improvement here. */ |
| 754 | 756 | vsock_for_each_connected_socket(vhost_vsock_reset_orphans); |
| 755 | 757 | |
| 756 | − vhost_vsock_stop(vsock); | |
| 758 | + /* Don't check the owner, because we are in the release path, so we | |
| 759 | + * need to stop the vsock device in any case. | |
| 760 | + * vhost_vsock_stop() can not fail in this case, so we don't need to | |
| 761 | + * check the return code. | |
| 762 | + */ | |
| 763 | + vhost_vsock_stop(vsock, false); | |
| 757 | 764 | vhost_vsock_flush(vsock); |
| 758 | 765 | vhost_dev_stop(&vsock->dev); |
| 759 | 766 | |
| @@ -868,7 +875,7 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl, · 108 unmodified lines | ||
| 868 | 875 | if (start) |
| 869 | 876 | return vhost_vsock_start(vsock); |
| 870 | 877 | else |
| 871 | − return vhost_vsock_stop(vsock); | |
| 878 | + return vhost_vsock_stop(vsock, true); | |
| 872 | 879 | case VHOST_GET_FEATURES: |
| 873 | 880 | features = VHOST_VSOCK_FEATURES; |
| 874 | 881 | if (copy_to_user(argp, &features, sizeof(features))) |
| @@ -949,6 +949,9 @@ static void populate_new_aces(char *nacl_base, · 948 unmodified lines | ||
| 949 | 949 | pnntace = (struct cifs_ace *) (nacl_base + nsize); |
| 950 | 950 | nsize += setup_special_mode_ACE(pnntace, nmode); |
| 951 | 951 | num_aces++; |
| 952 | + pnntace = (struct cifs_ace *) (nacl_base + nsize); | |
| 953 | + nsize += setup_authusers_ACE(pnntace); | |
| 954 | + num_aces++; | |
| 952 | 955 | goto set_size; |
| 953 | 956 | } |
| 954 | 957 | |
| @@ -1297,7 +1300,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, · 342 unmodified lines | ||
| 1297 | 1300 | |
| 1298 | 1301 | if (uid_valid(uid)) { /* chown */ |
| 1299 | 1302 | uid_t id; |
| 1300 | − nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid), | |
| 1303 | + nowner_sid_ptr = kzalloc(sizeof(struct cifs_sid), | |
| 1301 | 1304 | GFP_KERNEL); |
| 1302 | 1305 | if (!nowner_sid_ptr) { |
| 1303 | 1306 | rc = -ENOMEM; |
| @@ -1326,7 +1329,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, · 22 unmodified lines | ||
| 1326 | 1329 | } |
| 1327 | 1330 | if (gid_valid(gid)) { /* chgrp */ |
| 1328 | 1331 | gid_t id; |
| 1329 | − ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid), | |
| 1332 | + ngroup_sid_ptr = kzalloc(sizeof(struct cifs_sid), | |
| 1330 | 1333 | GFP_KERNEL); |
| 1331 | 1334 | if (!ngroup_sid_ptr) { |
| 1332 | 1335 | rc = -ENOMEM; |
| @@ -1613,7 +1616,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, · 280 unmodified lines | ||
| 1613 | 1616 | nsecdesclen = secdesclen; |
| 1614 | 1617 | if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */ |
| 1615 | 1618 | if (mode_from_sid) |
| 1616 | − nsecdesclen += sizeof(struct cifs_ace); | |
| 1619 | + nsecdesclen += 2 * sizeof(struct cifs_ace); | |
| 1617 | 1620 | else /* cifsacl */ |
| 1618 | 1621 | nsecdesclen += 5 * sizeof(struct cifs_ace); |
| 1619 | 1622 | } else { /* chown */ |
| @@ -919,6 +919,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, · 918 unmodified lines | ||
| 919 | 919 | |
| 920 | 920 | out_super: |
| 921 | 921 | deactivate_locked_super(sb); |
| 922 | + return root; | |
| 922 | 923 | out: |
| 923 | 924 | if (cifs_sb) { |
| 924 | 925 | kfree(cifs_sb->prepath); |
| @@ -149,7 +149,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = { · 148 unmodified lines | ||
| 149 | 149 | fsparam_u32("echo_interval", Opt_echo_interval), |
| 150 | 150 | fsparam_u32("max_credits", Opt_max_credits), |
| 151 | 151 | fsparam_u32("handletimeout", Opt_handletimeout), |
| 152 | − fsparam_u32("snapshot", Opt_snapshot), | |
| 152 | + fsparam_u64("snapshot", Opt_snapshot), | |
| 153 | 153 | fsparam_u32("max_channels", Opt_max_channels), |
| 154 | 154 | |
| 155 | 155 | /* Mount options which take string value */ |
| @@ -1078,7 +1078,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, · 922 unmodified lines | ||
| 1078 | 1078 | ctx->echo_interval = result.uint_32; |
| 1079 | 1079 | break; |
| 1080 | 1080 | case Opt_snapshot: |
| 1081 | − ctx->snapshot_time = result.uint_32; | |
| 1081 | + ctx->snapshot_time = result.uint_64; | |
| 1082 | 1082 | break; |
| 1083 | 1083 | case Opt_max_credits: |
| 1084 | 1084 | if (result.uint_32 < 20 || result.uint_32 > 60000) { |
| @@ -127,11 +127,6 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) · 126 unmodified lines | ||
| 127 | 127 | struct cifs_server_iface *ifaces = NULL; |
| 128 | 128 | size_t iface_count; |
| 129 | 129 | |
| 130 | − if (ses->server->dialect < SMB30_PROT_ID) { | |
| 131 | − cifs_dbg(VFS, "multichannel is not supported on this protocol version, use 3.0 or above\n"); | |
| 132 | − return 0; | |
| 133 | − } | |
| 134 | − | |
| 135 | 130 | spin_lock(&ses->chan_lock); |
| 136 | 131 | |
| 137 | 132 | new_chan_count = old_chan_count = ses->chan_count; |
| @@ -145,6 +140,12 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) · 7 unmodified lines | ||
| 145 | 140 | return 0; |
| 146 | 141 | } |
| 147 | 142 | |
| 143 | + if (ses->server->dialect < SMB30_PROT_ID) { | |
| 144 | + spin_unlock(&ses->chan_lock); | |
| 145 | + cifs_dbg(VFS, "multichannel is not supported on this protocol version, use 3.0 or above\n"); | |
| 146 | + return 0; | |
| 147 | + } | |
| 148 | + | |
| 148 | 149 | if (!(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) { |
| 149 | 150 | ses->chan_max = 1; |
| 150 | 151 | spin_unlock(&ses->chan_lock); |
| @@ -175,11 +175,13 @@ static int cifs_xattr_set(const struct xattr_handler *handler, · 174 unmodified lines | ||
| 175 | 175 | switch (handler->flags) { |
| 176 | 176 | case XATTR_CIFS_NTSD_FULL: |
| 177 | 177 | aclflags = (CIFS_ACL_OWNER | |
| 178 | + CIFS_ACL_GROUP | | |
| 178 | 179 | CIFS_ACL_DACL | |
| 179 | 180 | CIFS_ACL_SACL); |
| 180 | 181 | break; |
| 181 | 182 | case XATTR_CIFS_NTSD: |
| 182 | 183 | aclflags = (CIFS_ACL_OWNER | |
| 184 | + CIFS_ACL_GROUP | | |
| 183 | 185 | CIFS_ACL_DACL); |
| 184 | 186 | break; |
| 185 | 187 | case XATTR_CIFS_ACL: |
| @@ -4567,6 +4567,7 @@ static int io_add_buffers(struct io_provide_buf *pbuf, struct io_buffer **head) · 4566 unmodified lines | ||
| 4567 | 4567 | } else { |
| 4568 | 4568 | list_add_tail(&buf->list, &(*head)->list); |
| 4569 | 4569 | } |
| 4570 | + cond_resched(); | |
| 4570 | 4571 | } |
| 4571 | 4572 | |
| 4572 | 4573 | return i ? i : -ENOMEM; |
| @@ -7693,7 +7694,7 @@ static int io_run_task_work_sig(void) · 3120 unmodified lines | ||
| 7693 | 7694 | /* when returns >0, the caller should retry */ |
| 7694 | 7695 | static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx, |
| 7695 | 7696 | struct io_wait_queue *iowq, |
| 7696 | − signed long *timeout) | |
| 7697 | + ktime_t timeout) | |
| 7697 | 7698 | { |
| 7698 | 7699 | int ret; |
| 7699 | 7700 | |
| @@ -7705,8 +7706,9 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx, · 5 unmodified lines | ||
| 7705 | 7706 | if (test_bit(0, &ctx->check_cq_overflow)) |
| 7706 | 7707 | return 1; |
| 7707 | 7708 | |
| 7708 | − *timeout = schedule_timeout(*timeout); | |
| 7709 | − return !*timeout ? -ETIME : 1; | |
| 7709 | + if (!schedule_hrtimeout(&timeout, HRTIMER_MODE_ABS)) | |
| 7710 | + return -ETIME; | |
| 7711 | + return 1; | |
| 7710 | 7712 | } |
| 7711 | 7713 | |
| 7712 | 7714 | /* |
| @@ -7719,7 +7721,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, · 6 unmodified lines | ||
| 7719 | 7721 | { |
| 7720 | 7722 | struct io_wait_queue iowq; |
| 7721 | 7723 | struct io_rings *rings = ctx->rings; |
| 7722 | − signed long timeout = MAX_SCHEDULE_TIMEOUT; | |
| 7724 | + ktime_t timeout = KTIME_MAX; | |
| 7723 | 7725 | int ret; |
| 7724 | 7726 | |
| 7725 | 7727 | do { |
| @@ -7735,7 +7737,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, · 9 unmodified lines | ||
| 7735 | 7737 | |
| 7736 | 7738 | if (get_timespec64(&ts, uts)) |
| 7737 | 7739 | return -EFAULT; |
| 7738 | − timeout = timespec64_to_jiffies(&ts); | |
| 7740 | + timeout = ktime_add_ns(timespec64_to_ktime(ts), ktime_get_ns()); | |
| 7739 | 7741 | } |
| 7740 | 7742 | |
| 7741 | 7743 | if (sig) { |
| @@ -7767,7 +7769,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, · 25 unmodified lines | ||
| 7767 | 7769 | } |
| 7768 | 7770 | prepare_to_wait_exclusive(&ctx->cq_wait, &iowq.wq, |
| 7769 | 7771 | TASK_INTERRUPTIBLE); |
| 7770 | − ret = io_cqring_wait_schedule(ctx, &iowq, &timeout); | |
| 7772 | + ret = io_cqring_wait_schedule(ctx, &iowq, timeout); | |
| 7771 | 7773 | finish_wait(&ctx->cq_wait, &iowq.wq); |
| 7772 | 7774 | cond_resched(); |
| 7773 | 7775 | } while (ret > 0); |
| @@ -7924,7 +7926,15 @@ static __cold int io_rsrc_ref_quiesce(struct io_rsrc_data *data, · 150 unmodified lines | ||
| 7924 | 7926 | ret = wait_for_completion_interruptible(&data->done); |
| 7925 | 7927 | if (!ret) { |
| 7926 | 7928 | mutex_lock(&ctx->uring_lock); |
| 7927 | − break; | |
| 7929 | + if (atomic_read(&data->refs) > 0) { | |
| 7930 | + /* | |
| 7931 | + * it has been revived by another thread while | |
| 7932 | + * we were unlocked | |
| 7933 | + */ | |
| 7934 | + mutex_unlock(&ctx->uring_lock); | |
| 7935 | + } else { | |
| 7936 | + break; | |
| 7937 | + } | |
| 7928 | 7938 | } |
| 7929 | 7939 | |
| 7930 | 7940 | atomic_inc(&data->refs); |
| @@ -469,6 +469,24 @@ void mnt_drop_write_file(struct file *file) · 468 unmodified lines | ||
| 469 | 469 | } |
| 470 | 470 | EXPORT_SYMBOL(mnt_drop_write_file); |
| 471 | 471 | |
| 472 | +/** | |
| 473 | + * mnt_hold_writers - prevent write access to the given mount | |
| 474 | + * @mnt: mnt to prevent write access to | |
| 475 | + * | |
| 476 | + * Prevents write access to @mnt if there are no active writers for @mnt. | |
| 477 | + * This function needs to be called and return successfully before changing | |
| 478 | + * properties of @mnt that need to remain stable for callers with write access | |
| 479 | + * to @mnt. | |
| 480 | + * | |
| 481 | + * After this functions has been called successfully callers must pair it with | |
| 482 | + * a call to mnt_unhold_writers() in order to stop preventing write access to | |
| 483 | + * @mnt. | |
| 484 | + * | |
| 485 | + * Context: This function expects lock_mount_hash() to be held serializing | |
| 486 | + * setting MNT_WRITE_HOLD. | |
| 487 | + * Return: On success 0 is returned. | |
| 488 | + * On error, -EBUSY is returned. | |
| 489 | + */ | |
| 472 | 490 | static inline int mnt_hold_writers(struct mount *mnt) |
| 473 | 491 | { |
| 474 | 492 | mnt->mnt.mnt_flags |= MNT_WRITE_HOLD; |
| @@ -500,6 +518,18 @@ static inline int mnt_hold_writers(struct mount *mnt) · 25 unmodified lines | ||
| 500 | 518 | return 0; |
| 501 | 519 | } |
| 502 | 520 | |
| 521 | +/** | |
| 522 | + * mnt_unhold_writers - stop preventing write access to the given mount | |
| 523 | + * @mnt: mnt to stop preventing write access to | |
| 524 | + * | |
| 525 | + * Stop preventing write access to @mnt allowing callers to gain write access | |
| 526 | + * to @mnt again. | |
| 527 | + * | |
| 528 | + * This function can only be called after a successful call to | |
| 529 | + * mnt_hold_writers(). | |
| 530 | + * | |
| 531 | + * Context: This function expects lock_mount_hash() to be held. | |
| 532 | + */ | |
| 503 | 533 | static inline void mnt_unhold_writers(struct mount *mnt) |
| 504 | 534 | { |
| 505 | 535 | /* |
| @@ -2010,14 +2010,14 @@ no_open: · 2009 unmodified lines | ||
| 2010 | 2010 | if (!res) { |
| 2011 | 2011 | inode = d_inode(dentry); |
| 2012 | 2012 | if ((lookup_flags & LOOKUP_DIRECTORY) && inode && |
| 2013 | − !S_ISDIR(inode->i_mode)) | |
| 2013 | + !(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) | |
| 2014 | 2014 | res = ERR_PTR(-ENOTDIR); |
| 2015 | 2015 | else if (inode && S_ISREG(inode->i_mode)) |
| 2016 | 2016 | res = ERR_PTR(-EOPENSTALE); |
| 2017 | 2017 | } else if (!IS_ERR(res)) { |
| 2018 | 2018 | inode = d_inode(res); |
| 2019 | 2019 | if ((lookup_flags & LOOKUP_DIRECTORY) && inode && |
| 2020 | − !S_ISDIR(inode->i_mode)) { | |
| 2020 | + !(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) { | |
| 2021 | 2021 | dput(res); |
| 2022 | 2022 | res = ERR_PTR(-ENOTDIR); |
| 2023 | 2023 | } else if (inode && S_ISREG(inode->i_mode)) { |
| @@ -853,12 +853,9 @@ int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path, · 852 unmodified lines | ||
| 853 | 853 | } |
| 854 | 854 | |
| 855 | 855 | /* Flush out writes to the server in order to update c/mtime. */ |
| 856 | − if ((request_mask & (STATX_CTIME|STATX_MTIME)) && | |
| 857 | − S_ISREG(inode->i_mode)) { | |
| 858 | − err = filemap_write_and_wait(inode->i_mapping); | |
| 859 | − if (err) | |
| 860 | − goto out; | |
| 861 | − } | |
| 856 | + if ((request_mask & (STATX_CTIME | STATX_MTIME)) && | |
| 857 | + S_ISREG(inode->i_mode)) | |
| 858 | + filemap_write_and_wait(inode->i_mapping); | |
| 862 | 859 | |
| 863 | 860 | /* |
| 864 | 861 | * We may force a getattr if the user cares about atime. |
| @@ -1229,8 +1229,7 @@ nfs4_update_changeattr_locked(struct inode *inode, · 1228 unmodified lines | ||
| 1229 | 1229 | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL | |
| 1230 | 1230 | NFS_INO_INVALID_SIZE | NFS_INO_INVALID_OTHER | |
| 1231 | 1231 | NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_NLINK | |
| 1232 | − NFS_INO_INVALID_MODE | NFS_INO_INVALID_XATTR | | |
| 1233 | − NFS_INO_REVAL_PAGECACHE; | |
| 1232 | + NFS_INO_INVALID_MODE | NFS_INO_INVALID_XATTR; | |
| 1234 | 1233 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
| 1235 | 1234 | } |
| 1236 | 1235 | nfsi->attrtimeo_timestamp = jiffies; |
| @@ -748,7 +748,8 @@ extern bool blk_queue_can_use_dma_map_merging(struct request_queue *q, · 747 unmodified lines | ||
| 748 | 748 | |
| 749 | 749 | bool __must_check blk_get_queue(struct request_queue *); |
| 750 | 750 | extern void blk_put_queue(struct request_queue *); |
| 751 | −extern void blk_set_queue_dying(struct request_queue *); | |
| 751 | + | |
| 752 | +void blk_mark_disk_dead(struct gendisk *disk); | |
| 752 | 753 | |
| 753 | 754 | #ifdef CONFIG_BLOCK |
| 754 | 755 | /* |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #define NVME_TCP_DISC_PORT 8009 |
| 13 | 13 | #define NVME_TCP_ADMIN_CCSZ SZ_8K |
| 14 | 14 | #define NVME_TCP_DIGEST_LENGTH 4 |
| 15 | +#define NVME_TCP_MIN_MAXH2CDATA 4096 | |
| 15 | 16 | |
| 16 | 17 | enum nvme_tcp_pfv { |
| 17 | 18 | NVME_TCP_PFV_1_0 = 0x0, |
| @@ -54,8 +54,8 @@ extern asmlinkage void schedule_tail(struct task_struct *prev); · 53 unmodified lines | ||
| 54 | 54 | extern void init_idle(struct task_struct *idle, int cpu); |
| 55 | 55 | |
| 56 | 56 | extern int sched_fork(unsigned long clone_flags, struct task_struct *p); |
| 57 | −extern void sched_post_fork(struct task_struct *p, | |
| 58 | − struct kernel_clone_args *kargs); | |
| 57 | +extern void sched_cgroup_fork(struct task_struct *p, struct kernel_clone_args *kargs); | |
| 58 | +extern void sched_post_fork(struct task_struct *p); | |
| 59 | 59 | extern void sched_dead(struct task_struct *p); |
| 60 | 60 | |
| 61 | 61 | void __noreturn do_task_dead(void); |
| @@ -660,8 +660,7 @@ static inline __alloc_size(1, 2) void *kcalloc(size_t n, size_t size, gfp_t flag · 659 unmodified lines | ||
| 660 | 660 | * allocator where we care about the real place the memory allocation |
| 661 | 661 | * request comes from. |
| 662 | 662 | */ |
| 663 | −extern void *__kmalloc_track_caller(size_t size, gfp_t flags, unsigned long caller) | |
| 664 | − __alloc_size(1); | |
| 663 | +extern void *__kmalloc_track_caller(size_t size, gfp_t flags, unsigned long caller); | |
| 665 | 664 | #define kmalloc_track_caller(size, flags) \ |
| 666 | 665 | __kmalloc_track_caller(size, flags, _RET_IP_) |
| 667 | 666 | |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <asm/checksum.h> |
| 23 | 23 | |
| 24 | 24 | #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER |
| 25 | −static inline | |
| 25 | +static __always_inline | |
| 26 | 26 | __wsum csum_and_copy_from_user (const void __user *src, void *dst, |
| 27 | 27 | int len) |
| 28 | 28 | { |
| @@ -33,7 +33,7 @@ __wsum csum_and_copy_from_user (const void __user *src, void *dst, · 4 unmodified lines | ||
| 33 | 33 | #endif |
| 34 | 34 | |
| 35 | 35 | #ifndef HAVE_CSUM_COPY_USER |
| 36 | −static __inline__ __wsum csum_and_copy_to_user | |
| 36 | +static __always_inline __wsum csum_and_copy_to_user | |
| 37 | 37 | (const void *src, void __user *dst, int len) |
| 38 | 38 | { |
| 39 | 39 | __wsum sum = csum_partial(src, len, ~0U); |
| @@ -45,7 +45,7 @@ static __inline__ __wsum csum_and_copy_to_user · 5 unmodified lines | ||
| 45 | 45 | #endif |
| 46 | 46 | |
| 47 | 47 | #ifndef _HAVE_ARCH_CSUM_AND_COPY |
| 48 | −static inline __wsum | |
| 48 | +static __always_inline __wsum | |
| 49 | 49 | csum_partial_copy_nocheck(const void *src, void *dst, int len) |
| 50 | 50 | { |
| 51 | 51 | memcpy(dst, src, len); |
| @@ -54,7 +54,7 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len) · 2 unmodified lines | ||
| 54 | 54 | #endif |
| 55 | 55 | |
| 56 | 56 | #ifndef HAVE_ARCH_CSUM_ADD |
| 57 | −static inline __wsum csum_add(__wsum csum, __wsum addend) | |
| 57 | +static __always_inline __wsum csum_add(__wsum csum, __wsum addend) | |
| 58 | 58 | { |
| 59 | 59 | u32 res = (__force u32)csum; |
| 60 | 60 | res += (__force u32)addend; |
| @@ -62,12 +62,12 @@ static inline __wsum csum_add(__wsum csum, __wsum addend) · 1 unmodified line | ||
| 62 | 62 | } |
| 63 | 63 | #endif |
| 64 | 64 | |
| 65 | −static inline __wsum csum_sub(__wsum csum, __wsum addend) | |
| 65 | +static __always_inline __wsum csum_sub(__wsum csum, __wsum addend) | |
| 66 | 66 | { |
| 67 | 67 | return csum_add(csum, ~addend); |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | −static inline __sum16 csum16_add(__sum16 csum, __be16 addend) | |
| 70 | +static __always_inline __sum16 csum16_add(__sum16 csum, __be16 addend) | |
| 71 | 71 | { |
| 72 | 72 | u16 res = (__force u16)csum; |
| 73 | 73 | |
| @@ -75,12 +75,12 @@ static inline __sum16 csum16_add(__sum16 csum, __be16 addend) · 1 unmodified line | ||
| 75 | 75 | return (__force __sum16)(res + (res < (__force u16)addend)); |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | −static inline __sum16 csum16_sub(__sum16 csum, __be16 addend) | |
| 78 | +static __always_inline __sum16 csum16_sub(__sum16 csum, __be16 addend) | |
| 79 | 79 | { |
| 80 | 80 | return csum16_add(csum, ~addend); |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | −static inline __wsum csum_shift(__wsum sum, int offset) | |
| 83 | +static __always_inline __wsum csum_shift(__wsum sum, int offset) | |
| 84 | 84 | { |
| 85 | 85 | /* rotate sum to align it with a 16b boundary */ |
| 86 | 86 | if (offset & 1) |
| @@ -88,42 +88,43 @@ static inline __wsum csum_shift(__wsum sum, int offset) · 1 unmodified line | ||
| 88 | 88 | return sum; |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | −static inline __wsum | |
| 91 | +static __always_inline __wsum | |
| 92 | 92 | csum_block_add(__wsum csum, __wsum csum2, int offset) |
| 93 | 93 | { |
| 94 | 94 | return csum_add(csum, csum_shift(csum2, offset)); |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | −static inline __wsum | |
| 97 | +static __always_inline __wsum | |
| 98 | 98 | csum_block_add_ext(__wsum csum, __wsum csum2, int offset, int len) |
| 99 | 99 | { |
| 100 | 100 | return csum_block_add(csum, csum2, offset); |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | −static inline __wsum | |
| 103 | +static __always_inline __wsum | |
| 104 | 104 | csum_block_sub(__wsum csum, __wsum csum2, int offset) |
| 105 | 105 | { |
| 106 | 106 | return csum_block_add(csum, ~csum2, offset); |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | −static inline __wsum csum_unfold(__sum16 n) | |
| 109 | +static __always_inline __wsum csum_unfold(__sum16 n) | |
| 110 | 110 | { |
| 111 | 111 | return (__force __wsum)n; |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | −static inline __wsum csum_partial_ext(const void *buff, int len, __wsum sum) | |
| 114 | +static __always_inline | |
| 115 | +__wsum csum_partial_ext(const void *buff, int len, __wsum sum) | |
| 115 | 116 | { |
| 116 | 117 | return csum_partial(buff, len, sum); |
| 117 | 118 | } |
| 118 | 119 | |
| 119 | 120 | #define CSUM_MANGLED_0 ((__force __sum16)0xffff) |
| 120 | 121 | |
| 121 | −static inline void csum_replace_by_diff(__sum16 *sum, __wsum diff) | |
| 122 | +static __always_inline void csum_replace_by_diff(__sum16 *sum, __wsum diff) | |
| 122 | 123 | { |
| 123 | 124 | *sum = csum_fold(csum_add(diff, ~csum_unfold(*sum))); |
| 124 | 125 | } |
| 125 | 126 | |
| 126 | −static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to) | |
| 127 | +static __always_inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to) | |
| 127 | 128 | { |
| 128 | 129 | __wsum tmp = csum_sub(~csum_unfold(*sum), (__force __wsum)from); |
| 129 | 130 | |
| @@ -136,11 +137,16 @@ static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to) · 6 unmodified lines | ||
| 136 | 137 | * m : old value of a 16bit field |
| 137 | 138 | * m' : new value of a 16bit field |
| 138 | 139 | */ |
| 139 | −static inline void csum_replace2(__sum16 *sum, __be16 old, __be16 new) | |
| 140 | +static __always_inline void csum_replace2(__sum16 *sum, __be16 old, __be16 new) | |
| 140 | 141 | { |
| 141 | 142 | *sum = ~csum16_add(csum16_sub(~(*sum), old), new); |
| 142 | 143 | } |
| 143 | 144 | |
| 145 | +static inline void csum_replace(__wsum *csum, __wsum old, __wsum new) | |
| 146 | +{ | |
| 147 | + *csum = csum_add(csum_sub(*csum, old), new); | |
| 148 | +} | |
| 149 | + | |
| 144 | 150 | struct sk_buff; |
| 145 | 151 | void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, |
| 146 | 152 | __be32 from, __be32 to, bool pseudohdr); |
| @@ -150,16 +156,16 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, · 3 unmodified lines | ||
| 150 | 156 | void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, |
| 151 | 157 | __wsum diff, bool pseudohdr); |
| 152 | 158 | |
| 153 | −static inline void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, | |
| 154 | − __be16 from, __be16 to, | |
| 155 | − bool pseudohdr) | |
| 159 | +static __always_inline | |
| 160 | +void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, | |
| 161 | + __be16 from, __be16 to, bool pseudohdr) | |
| 156 | 162 | { |
| 157 | 163 | inet_proto_csum_replace4(sum, skb, (__force __be32)from, |
| 158 | 164 | (__force __be32)to, pseudohdr); |
| 159 | 165 | } |
| 160 | 166 | |
| 161 | −static inline __wsum remcsum_adjust(void *ptr, __wsum csum, | |
| 162 | − int start, int offset) | |
| 167 | +static __always_inline __wsum remcsum_adjust(void *ptr, __wsum csum, | |
| 168 | + int start, int offset) | |
| 163 | 169 | { |
| 164 | 170 | __sum16 *psum = (__sum16 *)(ptr + offset); |
| 165 | 171 | __wsum delta; |
| @@ -175,12 +181,12 @@ static inline __wsum remcsum_adjust(void *ptr, __wsum csum, · 9 unmodified lines | ||
| 175 | 181 | return delta; |
| 176 | 182 | } |
| 177 | 183 | |
| 178 | −static inline void remcsum_unadjust(__sum16 *psum, __wsum delta) | |
| 184 | +static __always_inline void remcsum_unadjust(__sum16 *psum, __wsum delta) | |
| 179 | 185 | { |
| 180 | 186 | *psum = csum_fold(csum_sub(delta, (__force __wsum)*psum)); |
| 181 | 187 | } |
| 182 | 188 | |
| 183 | −static inline __wsum wsum_negate(__wsum val) | |
| 189 | +static __always_inline __wsum wsum_negate(__wsum val) | |
| 184 | 190 | { |
| 185 | 191 | return (__force __wsum)-((__force u32)val); |
| 186 | 192 | } |
| @@ -905,9 +905,9 @@ struct nft_expr_ops { · 904 unmodified lines | ||
| 905 | 905 | int (*offload)(struct nft_offload_ctx *ctx, |
| 906 | 906 | struct nft_flow_rule *flow, |
| 907 | 907 | const struct nft_expr *expr); |
| 908 | + bool (*offload_action)(const struct nft_expr *expr); | |
| 908 | 909 | void (*offload_stats)(struct nft_expr *expr, |
| 909 | 910 | const struct flow_stats *stats); |
| 910 | − u32 offload_flags; | |
| 911 | 911 | const struct nft_expr_type *type; |
| 912 | 912 | void *data; |
| 913 | 913 | }; |
| @@ -67,8 +67,6 @@ struct nft_flow_rule { · 66 unmodified lines | ||
| 67 | 67 | struct flow_rule *rule; |
| 68 | 68 | }; |
| 69 | 69 | |
| 70 | −#define NFT_OFFLOAD_F_ACTION (1 << 0) | |
| 71 | − | |
| 72 | 70 | void nft_flow_rule_set_addr_type(struct nft_flow_rule *flow, |
| 73 | 71 | enum flow_dissector_key_id addr_type); |
| 74 | 72 | |
| @@ -509,7 +509,7 @@ struct sock { · 508 unmodified lines | ||
| 509 | 509 | #endif |
| 510 | 510 | u16 sk_tsflags; |
| 511 | 511 | u8 sk_shutdown; |
| 512 | − u32 sk_tskey; | |
| 512 | + atomic_t sk_tskey; | |
| 513 | 513 | atomic_t sk_zckey; |
| 514 | 514 | |
| 515 | 515 | u8 sk_clockid; |
| @@ -2681,7 +2681,7 @@ static inline void _sock_tx_timestamp(struct sock *sk, __u16 tsflags, · 2165 unmodified lines | ||
| 2681 | 2681 | __sock_tx_timestamp(tsflags, tx_flags); |
| 2682 | 2682 | if (tsflags & SOF_TIMESTAMPING_OPT_ID && tskey && |
| 2683 | 2683 | tsflags & SOF_TIMESTAMPING_TX_RECORD_MASK) |
| 2684 | − *tskey = sk->sk_tskey++; | |
| 2684 | + *tskey = atomic_inc_return(&sk->sk_tskey) - 1; | |
| 2685 | 2685 | } |
| 2686 | 2686 | if (unlikely(sock_flag(sk, SOCK_WIFI_STATUS))) |
| 2687 | 2687 | *tx_flags |= SKBTX_WIFI_STATUS; |
| @@ -546,6 +546,7 @@ static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, · 545 unmodified lines | ||
| 546 | 546 | char *buf, size_t nbytes, loff_t off) |
| 547 | 547 | { |
| 548 | 548 | struct cgroup *cgrp; |
| 549 | + struct cgroup_file_ctx *ctx; | |
| 549 | 550 | |
| 550 | 551 | BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX); |
| 551 | 552 | |
| @@ -553,8 +554,9 @@ static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, · 1 unmodified line | ||
| 553 | 554 | * Release agent gets called with all capabilities, |
| 554 | 555 | * require capabilities to set release agent. |
| 555 | 556 | */ |
| 556 | − if ((of->file->f_cred->user_ns != &init_user_ns) || | |
| 557 | − !capable(CAP_SYS_ADMIN)) | |
| 557 | + ctx = of->priv; | |
| 558 | + if ((ctx->ns->user_ns != &init_user_ns) || | |
| 559 | + !file_ns_capable(of->file, &init_user_ns, CAP_SYS_ADMIN)) | |
| 558 | 560 | return -EPERM; |
| 559 | 561 | |
| 560 | 562 | cgrp = cgroup_kn_lock_live(of->kn, false); |
| @@ -6166,6 +6166,20 @@ static int cgroup_css_set_fork(struct kernel_clone_args *kargs) · 6165 unmodified lines | ||
| 6166 | 6166 | if (ret) |
| 6167 | 6167 | goto err; |
| 6168 | 6168 | |
| 6169 | + /* | |
| 6170 | + * Spawning a task directly into a cgroup works by passing a file | |
| 6171 | + * descriptor to the target cgroup directory. This can even be an O_PATH | |
| 6172 | + * file descriptor. But it can never be a cgroup.procs file descriptor. | |
| 6173 | + * This was done on purpose so spawning into a cgroup could be | |
| 6174 | + * conceptualized as an atomic | |
| 6175 | + * | |
| 6176 | + * fd = openat(dfd_cgroup, "cgroup.procs", ...); | |
| 6177 | + * write(fd, <child-pid>, ...); | |
| 6178 | + * | |
| 6179 | + * sequence, i.e. it's a shorthand for the caller opening and writing | |
| 6180 | + * cgroup.procs of the cgroup indicated by @dfd_cgroup. This allows us | |
| 6181 | + * to always use the caller's credentials. | |
| 6182 | + */ | |
| 6169 | 6183 | ret = cgroup_attach_permissions(cset->dfl_cgrp, dst_cgrp, sb, |
| 6170 | 6184 | !(kargs->flags & CLONE_THREAD), |
| 6171 | 6185 | current->nsproxy->cgroup_ns); |
| @@ -2289,6 +2289,7 @@ static void cpuset_attach(struct cgroup_taskset *tset) · 2288 unmodified lines | ||
| 2289 | 2289 | cgroup_taskset_first(tset, &css); |
| 2290 | 2290 | cs = css_cs(css); |
| 2291 | 2291 | |
| 2292 | + cpus_read_lock(); | |
| 2292 | 2293 | percpu_down_write(&cpuset_rwsem); |
| 2293 | 2294 | |
| 2294 | 2295 | guarantee_online_mems(cs, &cpuset_attach_nodemask_to); |
| @@ -2342,6 +2343,7 @@ static void cpuset_attach(struct cgroup_taskset *tset) · 47 unmodified lines | ||
| 2342 | 2343 | wake_up(&cpuset_attach_wq); |
| 2343 | 2344 | |
| 2344 | 2345 | percpu_up_write(&cpuset_rwsem); |
| 2346 | + cpus_read_unlock(); | |
| 2345 | 2347 | } |
| 2346 | 2348 | |
| 2347 | 2349 | /* The various types of files and directories in a cpuset file system */ |
| @@ -3522,8 +3524,8 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs) · 1174 unmodified lines | ||
| 3522 | 3524 | return cs; |
| 3523 | 3525 | } |
| 3524 | 3526 | |
| 3525 | −/** | |
| 3526 | − * cpuset_node_allowed - Can we allocate on a memory node? | |
| 3527 | +/* | |
| 3528 | + * __cpuset_node_allowed - Can we allocate on a memory node? | |
| 3527 | 3529 | * @node: is this an allowed node? |
| 3528 | 3530 | * @gfp_mask: memory allocation flags |
| 3529 | 3531 | * |
| @@ -3694,8 +3696,8 @@ void cpuset_print_current_mems_allowed(void) · 164 unmodified lines | ||
| 3694 | 3696 | |
| 3695 | 3697 | int cpuset_memory_pressure_enabled __read_mostly; |
| 3696 | 3698 | |
| 3697 | −/** | |
| 3698 | − * cpuset_memory_pressure_bump - keep stats of per-cpuset reclaims. | |
| 3699 | +/* | |
| 3700 | + * __cpuset_memory_pressure_bump - keep stats of per-cpuset reclaims. | |
| 3699 | 3701 | * |
| 3700 | 3702 | * Keep a running average of the rate of synchronous (direct) |
| 3701 | 3703 | * page reclaim efforts initiated by tasks in each cpuset. |
| @@ -3710,7 +3712,7 @@ int cpuset_memory_pressure_enabled __read_mostly; · 8 unmodified lines | ||
| 3710 | 3712 | * "memory_pressure". Value displayed is an integer |
| 3711 | 3713 | * representing the recent rate of entry into the synchronous |
| 3712 | 3714 | * (direct) page reclaim by any task attached to the cpuset. |
| 3713 | − **/ | |
| 3715 | + */ | |
| 3714 | 3716 | |
| 3715 | 3717 | void __cpuset_memory_pressure_bump(void) |
| 3716 | 3718 | { |
| @@ -665,21 +665,16 @@ EXPORT_SYMBOL(cred_fscmp); · 664 unmodified lines | ||
| 665 | 665 | |
| 666 | 666 | int set_cred_ucounts(struct cred *new) |
| 667 | 667 | { |
| 668 | − struct task_struct *task = current; | |
| 669 | − const struct cred *old = task->real_cred; | |
| 670 | 668 | struct ucounts *new_ucounts, *old_ucounts = new->ucounts; |
| 671 | 669 | |
| 672 | − if (new->user == old->user && new->user_ns == old->user_ns) | |
| 673 | − return 0; | |
| 674 | − | |
| 675 | 670 | /* |
| 676 | 671 | * This optimization is needed because alloc_ucounts() uses locks |
| 677 | 672 | * for table lookups. |
| 678 | 673 | */ |
| 679 | − if (old_ucounts->ns == new->user_ns && uid_eq(old_ucounts->uid, new->euid)) | |
| 674 | + if (old_ucounts->ns == new->user_ns && uid_eq(old_ucounts->uid, new->uid)) | |
| 680 | 675 | return 0; |
| 681 | 676 | |
| 682 | − if (!(new_ucounts = alloc_ucounts(new->user_ns, new->euid))) | |
| 677 | + if (!(new_ucounts = alloc_ucounts(new->user_ns, new->uid))) | |
| 683 | 678 | return -EAGAIN; |
| 684 | 679 | |
| 685 | 680 | new->ucounts = new_ucounts; |
| @@ -2021,18 +2021,18 @@ static __latent_entropy struct task_struct *copy_process( · 2020 unmodified lines | ||
| 2021 | 2021 | #ifdef CONFIG_PROVE_LOCKING |
| 2022 | 2022 | DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); |
| 2023 | 2023 | #endif |
| 2024 | + retval = copy_creds(p, clone_flags); | |
| 2025 | + if (retval < 0) | |
| 2026 | + goto bad_fork_free; | |
| 2027 | + | |
| 2024 | 2028 | retval = -EAGAIN; |
| 2025 | 2029 | if (is_ucounts_overlimit(task_ucounts(p), UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC))) { |
| 2026 | 2030 | if (p->real_cred->user != INIT_USER && |
| 2027 | 2031 | !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) |
| 2028 | − goto bad_fork_free; | |
| 2032 | + goto bad_fork_cleanup_count; | |
| 2029 | 2033 | } |
| 2030 | 2034 | current->flags &= ~PF_NPROC_EXCEEDED; |
| 2031 | 2035 | |
| 2032 | − retval = copy_creds(p, clone_flags); | |
| 2033 | − if (retval < 0) | |
| 2034 | − goto bad_fork_free; | |
| 2035 | − | |
| 2036 | 2036 | /* |
| 2037 | 2037 | * If multiple threads are within copy_process(), then this check |
| 2038 | 2038 | * triggers too late. This doesn't hurt, the check is only there |
| @@ -2266,6 +2266,17 @@ static __latent_entropy struct task_struct *copy_process( · 227 unmodified lines | ||
| 2266 | 2266 | if (retval) |
| 2267 | 2267 | goto bad_fork_put_pidfd; |
| 2268 | 2268 | |
| 2269 | + /* | |
| 2270 | + * Now that the cgroups are pinned, re-clone the parent cgroup and put | |
| 2271 | + * the new task on the correct runqueue. All this *before* the task | |
| 2272 | + * becomes visible. | |
| 2273 | + * | |
| 2274 | + * This isn't part of ->can_fork() because while the re-cloning is | |
| 2275 | + * cgroup specific, it unconditionally needs to place the task on a | |
| 2276 | + * runqueue. | |
| 2277 | + */ | |
| 2278 | + sched_cgroup_fork(p, args); | |
| 2279 | + | |
| 2269 | 2280 | /* |
| 2270 | 2281 | * From this point on we must avoid any synchronous user-space |
| 2271 | 2282 | * communication until we take the tasklist-lock. In particular, we do |
| @@ -2323,10 +2334,6 @@ static __latent_entropy struct task_struct *copy_process( · 51 unmodified lines | ||
| 2323 | 2334 | goto bad_fork_cancel_cgroup; |
| 2324 | 2335 | } |
| 2325 | 2336 | |
| 2326 | − /* past the last point of failure */ | |
| 2327 | − if (pidfile) | |
| 2328 | − fd_install(pidfd, pidfile); | |
| 2329 | − | |
| 2330 | 2337 | init_task_pid_links(p); |
| 2331 | 2338 | if (likely(p->pid)) { |
| 2332 | 2339 | ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace); |
| @@ -2375,8 +2382,11 @@ static __latent_entropy struct task_struct *copy_process( · 42 unmodified lines | ||
| 2375 | 2382 | syscall_tracepoint_update(p); |
| 2376 | 2383 | write_unlock_irq(&tasklist_lock); |
| 2377 | 2384 | |
| 2385 | + if (pidfile) | |
| 2386 | + fd_install(pidfd, pidfile); | |
| 2387 | + | |
| 2378 | 2388 | proc_fork_connector(p); |
| 2379 | − sched_post_fork(p, args); | |
| 2389 | + sched_post_fork(p); | |
| 2380 | 2390 | cgroup_post_fork(p, args); |
| 2381 | 2391 | perf_event_fork(p); |
| 2382 | 2392 | |
| @@ -3462,7 +3462,7 @@ struct lock_class *lock_chain_get_class(struct lock_chain *chain, int i) · 3461 unmodified lines | ||
| 3462 | 3462 | u16 chain_hlock = chain_hlocks[chain->base + i]; |
| 3463 | 3463 | unsigned int class_idx = chain_hlock_class_idx(chain_hlock); |
| 3464 | 3464 | |
| 3465 | − return lock_classes + class_idx - 1; | |
| 3465 | + return lock_classes + class_idx; | |
| 3466 | 3466 | } |
| 3467 | 3467 | |
| 3468 | 3468 | /* |
| @@ -3530,7 +3530,7 @@ static void print_chain_keys_chain(struct lock_chain *chain) · 61 unmodified lines | ||
| 3530 | 3530 | hlock_id = chain_hlocks[chain->base + i]; |
| 3531 | 3531 | chain_key = print_chain_key_iteration(hlock_id, chain_key); |
| 3532 | 3532 | |
| 3533 | − print_lock_name(lock_classes + chain_hlock_class_idx(hlock_id) - 1); | |
| 3533 | + print_lock_name(lock_classes + chain_hlock_class_idx(hlock_id)); | |
| 3534 | 3534 | printk("\n"); |
| 3535 | 3535 | } |
| 3536 | 3536 | } |
| @@ -1214,9 +1214,8 @@ int tg_nop(struct task_group *tg, void *data) · 1213 unmodified lines | ||
| 1214 | 1214 | } |
| 1215 | 1215 | #endif |
| 1216 | 1216 | |
| 1217 | −static void set_load_weight(struct task_struct *p) | |
| 1217 | +static void set_load_weight(struct task_struct *p, bool update_load) | |
| 1218 | 1218 | { |
| 1219 | − bool update_load = !(READ_ONCE(p->__state) & TASK_NEW); | |
| 1220 | 1219 | int prio = p->static_prio - MAX_RT_PRIO; |
| 1221 | 1220 | struct load_weight *load = &p->se.load; |
| 1222 | 1221 | |
| @@ -4407,7 +4406,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) · 3184 unmodified lines | ||
| 4407 | 4406 | p->static_prio = NICE_TO_PRIO(0); |
| 4408 | 4407 | |
| 4409 | 4408 | p->prio = p->normal_prio = p->static_prio; |
| 4410 | − set_load_weight(p); | |
| 4409 | + set_load_weight(p, false); | |
| 4411 | 4410 | |
| 4412 | 4411 | /* |
| 4413 | 4412 | * We don't need the reset flag anymore after the fork. It has |
| @@ -4425,6 +4424,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) · 11 unmodified lines | ||
| 4425 | 4424 | |
| 4426 | 4425 | init_entity_runnable_average(&p->se); |
| 4427 | 4426 | |
| 4427 | + | |
| 4428 | 4428 | #ifdef CONFIG_SCHED_INFO |
| 4429 | 4429 | if (likely(sched_info_on())) |
| 4430 | 4430 | memset(&p->sched_info, 0, sizeof(p->sched_info)); |
| @@ -4440,18 +4440,23 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) · 9 unmodified lines | ||
| 4440 | 4440 | return 0; |
| 4441 | 4441 | } |
| 4442 | 4442 | |
| 4443 | −void sched_post_fork(struct task_struct *p, struct kernel_clone_args *kargs) | |
| 4443 | +void sched_cgroup_fork(struct task_struct *p, struct kernel_clone_args *kargs) | |
| 4444 | 4444 | { |
| 4445 | 4445 | unsigned long flags; |
| 4446 | −#ifdef CONFIG_CGROUP_SCHED | |
| 4447 | − struct task_group *tg; | |
| 4448 | −#endif | |
| 4449 | 4446 | |
| 4447 | + /* | |
| 4448 | + * Because we're not yet on the pid-hash, p->pi_lock isn't strictly | |
| 4449 | + * required yet, but lockdep gets upset if rules are violated. | |
| 4450 | + */ | |
| 4450 | 4451 | raw_spin_lock_irqsave(&p->pi_lock, flags); |
| 4451 | 4452 | #ifdef CONFIG_CGROUP_SCHED |
| 4452 | − tg = container_of(kargs->cset->subsys[cpu_cgrp_id], | |
| 4453 | − struct task_group, css); | |
| 4454 | − p->sched_task_group = autogroup_task_group(p, tg); | |
| 4453 | + if (1) { | |
| 4454 | + struct task_group *tg; | |
| 4455 | + tg = container_of(kargs->cset->subsys[cpu_cgrp_id], | |
| 4456 | + struct task_group, css); | |
| 4457 | + tg = autogroup_task_group(p, tg); | |
| 4458 | + p->sched_task_group = tg; | |
| 4459 | + } | |
| 4455 | 4460 | #endif |
| 4456 | 4461 | rseq_migrate(p); |
| 4457 | 4462 | /* |
| @@ -4462,7 +4467,10 @@ void sched_post_fork(struct task_struct *p, struct kernel_clone_args *kargs) · 4 unmodified lines | ||
| 4462 | 4467 | if (p->sched_class->task_fork) |
| 4463 | 4468 | p->sched_class->task_fork(p); |
| 4464 | 4469 | raw_spin_unlock_irqrestore(&p->pi_lock, flags); |
| 4470 | +} | |
| 4465 | 4471 | |
| 4472 | +void sched_post_fork(struct task_struct *p) | |
| 4473 | +{ | |
| 4466 | 4474 | uclamp_post_fork(p); |
| 4467 | 4475 | } |
| 4468 | 4476 | |
| @@ -6922,7 +6930,7 @@ void set_user_nice(struct task_struct *p, long nice) · 2453 unmodified lines | ||
| 6922 | 6930 | put_prev_task(rq, p); |
| 6923 | 6931 | |
| 6924 | 6932 | p->static_prio = NICE_TO_PRIO(nice); |
| 6925 | − set_load_weight(p); | |
| 6933 | + set_load_weight(p, true); | |
| 6926 | 6934 | old_prio = p->prio; |
| 6927 | 6935 | p->prio = effective_prio(p); |
| 6928 | 6936 | |
| @@ -7213,7 +7221,7 @@ static void __setscheduler_params(struct task_struct *p, · 284 unmodified lines | ||
| 7213 | 7221 | */ |
| 7214 | 7222 | p->rt_priority = attr->sched_priority; |
| 7215 | 7223 | p->normal_prio = normal_prio(p); |
| 7216 | − set_load_weight(p); | |
| 7224 | + set_load_weight(p, true); | |
| 7217 | 7225 | } |
| 7218 | 7226 | |
| 7219 | 7227 | /* |
| @@ -9446,7 +9454,7 @@ void __init sched_init(void) · 2226 unmodified lines | ||
| 9446 | 9454 | #endif |
| 9447 | 9455 | } |
| 9448 | 9456 | |
| 9449 | − set_load_weight(&init_task); | |
| 9457 | + set_load_weight(&init_task, false); | |
| 9450 | 9458 | |
| 9451 | 9459 | /* |
| 9452 | 9460 | * The boot idle thread does lazy MMU switching as well: |
| @@ -472,6 +472,16 @@ static int set_user(struct cred *new) · 471 unmodified lines | ||
| 472 | 472 | if (!new_user) |
| 473 | 473 | return -EAGAIN; |
| 474 | 474 | |
| 475 | + free_uid(new->user); | |
| 476 | + new->user = new_user; | |
| 477 | + return 0; | |
| 478 | +} | |
| 479 | + | |
| 480 | +static void flag_nproc_exceeded(struct cred *new) | |
| 481 | +{ | |
| 482 | + if (new->ucounts == current_ucounts()) | |
| 483 | + return; | |
| 484 | + | |
| 475 | 485 | /* |
| 476 | 486 | * We don't fail in case of NPROC limit excess here because too many |
| 477 | 487 | * poorly written programs don't check set*uid() return code, assuming |
| @@ -480,15 +490,10 @@ static int set_user(struct cred *new) · 2 unmodified lines | ||
| 480 | 490 | * failure to the execve() stage. |
| 481 | 491 | */ |
| 482 | 492 | if (is_ucounts_overlimit(new->ucounts, UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC)) && |
| 483 | − new_user != INIT_USER && | |
| 484 | − !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) | |
| 493 | + new->user != INIT_USER) | |
| 485 | 494 | current->flags |= PF_NPROC_EXCEEDED; |
| 486 | 495 | else |
| 487 | 496 | current->flags &= ~PF_NPROC_EXCEEDED; |
| 488 | − | |
| 489 | − free_uid(new->user); | |
| 490 | − new->user = new_user; | |
| 491 | − return 0; | |
| 492 | 497 | } |
| 493 | 498 | |
| 494 | 499 | /* |
| @@ -563,6 +568,7 @@ long __sys_setreuid(uid_t ruid, uid_t euid) · 68 unmodified lines | ||
| 563 | 568 | if (retval < 0) |
| 564 | 569 | goto error; |
| 565 | 570 | |
| 571 | + flag_nproc_exceeded(new); | |
| 566 | 572 | return commit_creds(new); |
| 567 | 573 | |
| 568 | 574 | error: |
| @@ -625,6 +631,7 @@ long __sys_setuid(uid_t uid) · 56 unmodified lines | ||
| 625 | 631 | if (retval < 0) |
| 626 | 632 | goto error; |
| 627 | 633 | |
| 634 | + flag_nproc_exceeded(new); | |
| 628 | 635 | return commit_creds(new); |
| 629 | 636 | |
| 630 | 637 | error: |
| @@ -704,6 +711,7 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) · 73 unmodified lines | ||
| 704 | 711 | if (retval < 0) |
| 705 | 712 | goto error; |
| 706 | 713 | |
| 714 | + flag_nproc_exceeded(new); | |
| 707 | 715 | return commit_creds(new); |
| 708 | 716 | |
| 709 | 717 | error: |
| @@ -350,7 +350,8 @@ bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsign · 349 unmodified lines | ||
| 350 | 350 | if (rlimit > LONG_MAX) |
| 351 | 351 | max = LONG_MAX; |
| 352 | 352 | for (iter = ucounts; iter; iter = iter->ns->ucounts) { |
| 353 | − if (get_ucounts_value(iter, type) > max) | |
| 353 | + long val = get_ucounts_value(iter, type); | |
| 354 | + if (val < 0 || val > max) | |
| 354 | 355 | return true; |
| 355 | 356 | max = READ_ONCE(iter->ns->ucount_max[type]); |
| 356 | 357 | } |
| @@ -414,6 +414,7 @@ static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t by · 413 unmodified lines | ||
| 414 | 414 | return 0; |
| 415 | 415 | |
| 416 | 416 | buf->ops = &page_cache_pipe_buf_ops; |
| 417 | + buf->flags = 0; | |
| 417 | 418 | get_page(page); |
| 418 | 419 | buf->page = page; |
| 419 | 420 | buf->offset = offset; |
| @@ -577,6 +578,7 @@ static size_t push_pipe(struct iov_iter *i, size_t size, · 157 unmodified lines | ||
| 577 | 578 | break; |
| 578 | 579 | |
| 579 | 580 | buf->ops = &default_pipe_buf_ops; |
| 581 | + buf->flags = 0; | |
| 580 | 582 | buf->page = page; |
| 581 | 583 | buf->offset = 0; |
| 582 | 584 | buf->len = min_t(ssize_t, left, PAGE_SIZE); |
| @@ -2006,7 +2006,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv, · 2005 unmodified lines | ||
| 2006 | 2006 | /* set the end-packet for broadcast */ |
| 2007 | 2007 | session->pkt.last = session->pkt.total; |
| 2008 | 2008 | |
| 2009 | − skcb->tskey = session->sk->sk_tskey++; | |
| 2009 | + skcb->tskey = atomic_inc_return(&session->sk->sk_tskey) - 1; | |
| 2010 | 2010 | session->tskey = skcb->tskey; |
| 2011 | 2011 | |
| 2012 | 2012 | return session; |
| @@ -213,7 +213,7 @@ static ssize_t speed_show(struct device *dev, · 212 unmodified lines | ||
| 213 | 213 | if (!rtnl_trylock()) |
| 214 | 214 | return restart_syscall(); |
| 215 | 215 | |
| 216 | − if (netif_running(netdev)) { | |
| 216 | + if (netif_running(netdev) && netif_device_present(netdev)) { | |
| 217 | 217 | struct ethtool_link_ksettings cmd; |
| 218 | 218 | |
| 219 | 219 | if (!__ethtool_get_link_ksettings(netdev, &cmd)) |
| @@ -2307,7 +2307,7 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta) · 2306 unmodified lines | ||
| 2307 | 2307 | /* Free pulled out fragments. */ |
| 2308 | 2308 | while ((list = skb_shinfo(skb)->frag_list) != insp) { |
| 2309 | 2309 | skb_shinfo(skb)->frag_list = list->next; |
| 2310 | − kfree_skb(list); | |
| 2310 | + consume_skb(list); | |
| 2311 | 2311 | } |
| 2312 | 2312 | /* And insert new clone at head. */ |
| 2313 | 2313 | if (clone) { |
| @@ -4761,7 +4761,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb, · 2447 unmodified lines | ||
| 4761 | 4761 | if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) { |
| 4762 | 4762 | serr->ee.ee_data = skb_shinfo(skb)->tskey; |
| 4763 | 4763 | if (sk_is_tcp(sk)) |
| 4764 | − serr->ee.ee_data -= sk->sk_tskey; | |
| 4764 | + serr->ee.ee_data -= atomic_read(&sk->sk_tskey); | |
| 4765 | 4765 | } |
| 4766 | 4766 | |
| 4767 | 4767 | err = sock_queue_err_skb(sk, skb); |
| @@ -6132,7 +6132,7 @@ static int pskb_carve_frag_list(struct sk_buff *skb, · 1364 unmodified lines | ||
| 6132 | 6132 | /* Free pulled out fragments. */ |
| 6133 | 6133 | while ((list = shinfo->frag_list) != insp) { |
| 6134 | 6134 | shinfo->frag_list = list->next; |
| 6135 | − kfree_skb(list); | |
| 6135 | + consume_skb(list); | |
| 6136 | 6136 | } |
| 6137 | 6137 | /* And insert new clone at head. */ |
| 6138 | 6138 | if (clone) { |
| @@ -879,9 +879,9 @@ int sock_set_timestamping(struct sock *sk, int optname, · 878 unmodified lines | ||
| 879 | 879 | if ((1 << sk->sk_state) & |
| 880 | 880 | (TCPF_CLOSE | TCPF_LISTEN)) |
| 881 | 881 | return -EINVAL; |
| 882 | − sk->sk_tskey = tcp_sk(sk)->snd_una; | |
| 882 | + atomic_set(&sk->sk_tskey, tcp_sk(sk)->snd_una); | |
| 883 | 883 | } else { |
| 884 | − sk->sk_tskey = 0; | |
| 884 | + atomic_set(&sk->sk_tskey, 0); | |
| 885 | 885 | } |
| 886 | 886 | } |
| 887 | 887 | |
| @@ -260,11 +260,16 @@ static void dsa_netdev_ops_set(struct net_device *dev, · 259 unmodified lines | ||
| 260 | 260 | dev->dsa_ptr->netdev_ops = ops; |
| 261 | 261 | } |
| 262 | 262 | |
| 263 | +/* Keep the master always promiscuous if the tagging protocol requires that | |
| 264 | + * (garbles MAC DA) or if it doesn't support unicast filtering, case in which | |
| 265 | + * it would revert to promiscuous mode as soon as we call dev_uc_add() on it | |
| 266 | + * anyway. | |
| 267 | + */ | |
| 263 | 268 | static void dsa_master_set_promiscuity(struct net_device *dev, int inc) |
| 264 | 269 | { |
| 265 | 270 | const struct dsa_device_ops *ops = dev->dsa_ptr->tag_ops; |
| 266 | 271 | |
| 267 | − if (!ops->promisc_on_master) | |
| 272 | + if ((dev->priv_flags & IFF_UNICAST_FLT) && !ops->promisc_on_master) | |
| 268 | 273 | return; |
| 269 | 274 | |
| 270 | 275 | ASSERT_RTNL(); |
| @@ -395,10 +395,17 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) · 394 unmodified lines | ||
| 395 | 395 | .tree_index = dp->ds->dst->index, |
| 396 | 396 | .sw_index = dp->ds->index, |
| 397 | 397 | .port = dp->index, |
| 398 | − .bridge = *dp->bridge, | |
| 399 | 398 | }; |
| 400 | 399 | int err; |
| 401 | 400 | |
| 401 | + /* If the port could not be offloaded to begin with, then | |
| 402 | + * there is nothing to do. | |
| 403 | + */ | |
| 404 | + if (!dp->bridge) | |
| 405 | + return; | |
| 406 | + | |
| 407 | + info.bridge = *dp->bridge; | |
| 408 | + | |
| 402 | 409 | /* Here the port is already unbridged. Reflect the current configuration |
| 403 | 410 | * so that drivers can program their chips accordingly. |
| 404 | 411 | */ |
| @@ -781,9 +788,15 @@ int dsa_port_host_fdb_add(struct dsa_port *dp, const unsigned char *addr, · 376 unmodified lines | ||
| 781 | 788 | struct dsa_port *cpu_dp = dp->cpu_dp; |
| 782 | 789 | int err; |
| 783 | 790 | |
| 784 | − err = dev_uc_add(cpu_dp->master, addr); | |
| 785 | − if (err) | |
| 786 | − return err; | |
| 791 | + /* Avoid a call to __dev_set_promiscuity() on the master, which | |
| 792 | + * requires rtnl_lock(), since we can't guarantee that is held here, | |
| 793 | + * and we can't take it either. | |
| 794 | + */ | |
| 795 | + if (cpu_dp->master->priv_flags & IFF_UNICAST_FLT) { | |
| 796 | + err = dev_uc_add(cpu_dp->master, addr); | |
| 797 | + if (err) | |
| 798 | + return err; | |
| 799 | + } | |
| 787 | 800 | |
| 788 | 801 | return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_ADD, &info); |
| 789 | 802 | } |
| @@ -800,9 +813,11 @@ int dsa_port_host_fdb_del(struct dsa_port *dp, const unsigned char *addr, · 10 unmodified lines | ||
| 800 | 813 | struct dsa_port *cpu_dp = dp->cpu_dp; |
| 801 | 814 | int err; |
| 802 | 815 | |
| 803 | − err = dev_uc_del(cpu_dp->master, addr); | |
| 804 | − if (err) | |
| 805 | − return err; | |
| 816 | + if (cpu_dp->master->priv_flags & IFF_UNICAST_FLT) { | |
| 817 | + err = dev_uc_del(cpu_dp->master, addr); | |
| 818 | + if (err) | |
| 819 | + return err; | |
| 820 | + } | |
| 806 | 821 | |
| 807 | 822 | return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_DEL, &info); |
| 808 | 823 | } |
| @@ -1376,8 +1376,11 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb, · 1375 unmodified lines | ||
| 1376 | 1376 | } |
| 1377 | 1377 | |
| 1378 | 1378 | ops = rcu_dereference(inet_offloads[proto]); |
| 1379 | − if (likely(ops && ops->callbacks.gso_segment)) | |
| 1379 | + if (likely(ops && ops->callbacks.gso_segment)) { | |
| 1380 | 1380 | segs = ops->callbacks.gso_segment(skb, features); |
| 1381 | + if (!segs) | |
| 1382 | + skb->network_header = skb_mac_header(skb) + nhoff - skb->head; | |
| 1383 | + } | |
| 1381 | 1384 | |
| 1382 | 1385 | if (IS_ERR_OR_NULL(segs)) |
| 1383 | 1386 | goto out; |
| @@ -991,7 +991,7 @@ static int __ip_append_data(struct sock *sk, · 990 unmodified lines | ||
| 991 | 991 | |
| 992 | 992 | if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && |
| 993 | 993 | sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) |
| 994 | − tskey = sk->sk_tskey++; | |
| 994 | + tskey = atomic_inc_return(&sk->sk_tskey) - 1; | |
| 995 | 995 | |
| 996 | 996 | hh_len = LL_RESERVED_SPACE(rt->dst.dev); |
| 997 | 997 | |
| @@ -187,7 +187,6 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) · 186 unmodified lines | ||
| 187 | 187 | (int)ident, &ipv6_hdr(skb)->daddr, dif); |
| 188 | 188 | #endif |
| 189 | 189 | } else { |
| 190 | − pr_err("ping: protocol(%x) is not supported\n", ntohs(skb->protocol)); | |
| 191 | 190 | return NULL; |
| 192 | 191 | } |
| 193 | 192 | |
| @@ -846,7 +846,7 @@ udp_tunnel_nic_unregister(struct net_device *dev, struct udp_tunnel_nic *utn) · 845 unmodified lines | ||
| 846 | 846 | list_for_each_entry(node, &info->shared->devices, list) |
| 847 | 847 | if (node->dev == dev) |
| 848 | 848 | break; |
| 849 | − if (node->dev != dev) | |
| 849 | + if (list_entry_is_head(node, &info->shared->devices, list)) | |
| 850 | 850 | return; |
| 851 | 851 | |
| 852 | 852 | list_del(&node->list); |
| @@ -4996,6 +4996,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, · 4995 unmodified lines | ||
| 4996 | 4996 | nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid)) |
| 4997 | 4997 | goto error; |
| 4998 | 4998 | |
| 4999 | + spin_lock_bh(&ifa->lock); | |
| 4999 | 5000 | if (!((ifa->flags&IFA_F_PERMANENT) && |
| 5000 | 5001 | (ifa->prefered_lft == INFINITY_LIFE_TIME))) { |
| 5001 | 5002 | preferred = ifa->prefered_lft; |
| @@ -5017,6 +5018,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, · 15 unmodified lines | ||
| 5017 | 5018 | preferred = INFINITY_LIFE_TIME; |
| 5018 | 5019 | valid = INFINITY_LIFE_TIME; |
| 5019 | 5020 | } |
| 5021 | + spin_unlock_bh(&ifa->lock); | |
| 5020 | 5022 | |
| 5021 | 5023 | if (!ipv6_addr_any(&ifa->peer_addr)) { |
| 5022 | 5024 | if (nla_put_in6_addr(skb, IFA_LOCAL, &ifa->addr) < 0 || |
| @@ -114,6 +114,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, · 113 unmodified lines | ||
| 114 | 114 | if (likely(ops && ops->callbacks.gso_segment)) { |
| 115 | 115 | skb_reset_transport_header(skb); |
| 116 | 116 | segs = ops->callbacks.gso_segment(skb, features); |
| 117 | + if (!segs) | |
| 118 | + skb->network_header = skb_mac_header(skb) + nhoff - skb->head; | |
| 117 | 119 | } |
| 118 | 120 | |
| 119 | 121 | if (IS_ERR_OR_NULL(segs)) |
| @@ -1464,7 +1464,7 @@ static int __ip6_append_data(struct sock *sk, · 1463 unmodified lines | ||
| 1464 | 1464 | |
| 1465 | 1465 | if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && |
| 1466 | 1466 | sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) |
| 1467 | − tskey = sk->sk_tskey++; | |
| 1467 | + tskey = atomic_inc_return(&sk->sk_tskey) - 1; | |
| 1468 | 1468 | |
| 1469 | 1469 | hh_len = LL_RESERVED_SPACE(rt->dst.dev); |
| 1470 | 1470 | |
| @@ -35,12 +35,14 @@ static const struct snmp_mib mptcp_snmp_list[] = { · 34 unmodified lines | ||
| 35 | 35 | SNMP_MIB_ITEM("AddAddr", MPTCP_MIB_ADDADDR), |
| 36 | 36 | SNMP_MIB_ITEM("EchoAdd", MPTCP_MIB_ECHOADD), |
| 37 | 37 | SNMP_MIB_ITEM("PortAdd", MPTCP_MIB_PORTADD), |
| 38 | + SNMP_MIB_ITEM("AddAddrDrop", MPTCP_MIB_ADDADDRDROP), | |
| 38 | 39 | SNMP_MIB_ITEM("MPJoinPortSynRx", MPTCP_MIB_JOINPORTSYNRX), |
| 39 | 40 | SNMP_MIB_ITEM("MPJoinPortSynAckRx", MPTCP_MIB_JOINPORTSYNACKRX), |
| 40 | 41 | SNMP_MIB_ITEM("MPJoinPortAckRx", MPTCP_MIB_JOINPORTACKRX), |
| 41 | 42 | SNMP_MIB_ITEM("MismatchPortSynRx", MPTCP_MIB_MISMATCHPORTSYNRX), |
| 42 | 43 | SNMP_MIB_ITEM("MismatchPortAckRx", MPTCP_MIB_MISMATCHPORTACKRX), |
| 43 | 44 | SNMP_MIB_ITEM("RmAddr", MPTCP_MIB_RMADDR), |
| 45 | + SNMP_MIB_ITEM("RmAddrDrop", MPTCP_MIB_RMADDRDROP), | |
| 44 | 46 | SNMP_MIB_ITEM("RmSubflow", MPTCP_MIB_RMSUBFLOW), |
| 45 | 47 | SNMP_MIB_ITEM("MPPrioTx", MPTCP_MIB_MPPRIOTX), |
| 46 | 48 | SNMP_MIB_ITEM("MPPrioRx", MPTCP_MIB_MPPRIORX), |
| @@ -28,12 +28,14 @@ enum linux_mptcp_mib_field { · 27 unmodified lines | ||
| 28 | 28 | MPTCP_MIB_ADDADDR, /* Received ADD_ADDR with echo-flag=0 */ |
| 29 | 29 | MPTCP_MIB_ECHOADD, /* Received ADD_ADDR with echo-flag=1 */ |
| 30 | 30 | MPTCP_MIB_PORTADD, /* Received ADD_ADDR with a port-number */ |
| 31 | + MPTCP_MIB_ADDADDRDROP, /* Dropped incoming ADD_ADDR */ | |
| 31 | 32 | MPTCP_MIB_JOINPORTSYNRX, /* Received a SYN MP_JOIN with a different port-number */ |
| 32 | 33 | MPTCP_MIB_JOINPORTSYNACKRX, /* Received a SYNACK MP_JOIN with a different port-number */ |
| 33 | 34 | MPTCP_MIB_JOINPORTACKRX, /* Received an ACK MP_JOIN with a different port-number */ |
| 34 | 35 | MPTCP_MIB_MISMATCHPORTSYNRX, /* Received a SYN MP_JOIN with a mismatched port-number */ |
| 35 | 36 | MPTCP_MIB_MISMATCHPORTACKRX, /* Received an ACK MP_JOIN with a mismatched port-number */ |
| 36 | 37 | MPTCP_MIB_RMADDR, /* Received RM_ADDR */ |
| 38 | + MPTCP_MIB_RMADDRDROP, /* Dropped incoming RM_ADDR */ | |
| 37 | 39 | MPTCP_MIB_RMSUBFLOW, /* Remove a subflow */ |
| 38 | 40 | MPTCP_MIB_MPPRIOTX, /* Transmit a MP_PRIO */ |
| 39 | 41 | MPTCP_MIB_MPPRIORX, /* Received a MP_PRIO */ |
| @@ -213,6 +213,8 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk, · 212 unmodified lines | ||
| 213 | 213 | mptcp_pm_add_addr_send_ack(msk); |
| 214 | 214 | } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) { |
| 215 | 215 | pm->remote = *addr; |
| 216 | + } else { | |
| 217 | + __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP); | |
| 216 | 218 | } |
| 217 | 219 | |
| 218 | 220 | spin_unlock_bh(&pm->lock); |
| @@ -253,8 +255,10 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, · 34 unmodified lines | ||
| 253 | 255 | mptcp_event_addr_removed(msk, rm_list->ids[i]); |
| 254 | 256 | |
| 255 | 257 | spin_lock_bh(&pm->lock); |
| 256 | − mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED); | |
| 257 | − pm->rm_list_rx = *rm_list; | |
| 258 | + if (mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED)) | |
| 259 | + pm->rm_list_rx = *rm_list; | |
| 260 | + else | |
| 261 | + __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_RMADDRDROP); | |
| 258 | 262 | spin_unlock_bh(&pm->lock); |
| 259 | 263 | } |
| 260 | 264 | |
| @@ -546,6 +546,16 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) · 545 unmodified lines | ||
| 546 | 546 | if (msk->pm.add_addr_signaled < add_addr_signal_max) { |
| 547 | 547 | local = select_signal_address(pernet, msk); |
| 548 | 548 | |
| 549 | + /* due to racing events on both ends we can reach here while | |
| 550 | + * previous add address is still running: if we invoke now | |
| 551 | + * mptcp_pm_announce_addr(), that will fail and the | |
| 552 | + * corresponding id will be marked as used. | |
| 553 | + * Instead let the PM machinery reschedule us when the | |
| 554 | + * current address announce will be completed. | |
| 555 | + */ | |
| 556 | + if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) | |
| 557 | + return; | |
| 558 | + | |
| 549 | 559 | if (local) { |
| 550 | 560 | if (mptcp_pm_alloc_anno_list(msk, local)) { |
| 551 | 561 | __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); |
| @@ -650,6 +660,7 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) · 98 unmodified lines | ||
| 650 | 660 | unsigned int add_addr_accept_max; |
| 651 | 661 | struct mptcp_addr_info remote; |
| 652 | 662 | unsigned int subflows_max; |
| 663 | + bool reset_port = false; | |
| 653 | 664 | int i, nr; |
| 654 | 665 | |
| 655 | 666 | add_addr_accept_max = mptcp_pm_get_add_addr_accept_max(msk); |
| @@ -659,15 +670,19 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) · 3 unmodified lines | ||
| 659 | 670 | msk->pm.add_addr_accepted, add_addr_accept_max, |
| 660 | 671 | msk->pm.remote.family); |
| 661 | 672 | |
| 662 | − if (lookup_subflow_by_daddr(&msk->conn_list, &msk->pm.remote)) | |
| 673 | + remote = msk->pm.remote; | |
| 674 | + if (lookup_subflow_by_daddr(&msk->conn_list, &remote)) | |
| 663 | 675 | goto add_addr_echo; |
| 664 | 676 | |
| 677 | + /* pick id 0 port, if none is provided the remote address */ | |
| 678 | + if (!remote.port) { | |
| 679 | + reset_port = true; | |
| 680 | + remote.port = sk->sk_dport; | |
| 681 | + } | |
| 682 | + | |
| 665 | 683 | /* connect to the specified remote address, using whatever |
| 666 | 684 | * local address the routing configuration will pick. |
| 667 | 685 | */ |
| 668 | − remote = msk->pm.remote; | |
| 669 | − if (!remote.port) | |
| 670 | − remote.port = sk->sk_dport; | |
| 671 | 686 | nr = fill_local_addresses_vec(msk, addrs); |
| 672 | 687 | |
| 673 | 688 | msk->pm.add_addr_accepted++; |
| @@ -680,8 +695,12 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) · 6 unmodified lines | ||
| 680 | 695 | __mptcp_subflow_connect(sk, &addrs[i], &remote); |
| 681 | 696 | spin_lock_bh(&msk->pm.lock); |
| 682 | 697 | |
| 698 | + /* be sure to echo exactly the received address */ | |
| 699 | + if (reset_port) | |
| 700 | + remote.port = 0; | |
| 701 | + | |
| 683 | 702 | add_addr_echo: |
| 684 | − mptcp_pm_announce_addr(msk, &msk->pm.remote, true); | |
| 703 | + mptcp_pm_announce_addr(msk, &remote, true); | |
| 685 | 704 | mptcp_pm_nl_addr_send_ack(msk); |
| 686 | 705 | } |
| 687 | 706 | |
| @@ -6551,12 +6551,15 @@ static int nf_tables_updobj(const struct nft_ctx *ctx, · 6550 unmodified lines | ||
| 6551 | 6551 | { |
| 6552 | 6552 | struct nft_object *newobj; |
| 6553 | 6553 | struct nft_trans *trans; |
| 6554 | − int err; | |
| 6554 | + int err = -ENOMEM; | |
| 6555 | + | |
| 6556 | + if (!try_module_get(type->owner)) | |
| 6557 | + return -ENOENT; | |
| 6555 | 6558 | |
| 6556 | 6559 | trans = nft_trans_alloc(ctx, NFT_MSG_NEWOBJ, |
| 6557 | 6560 | sizeof(struct nft_trans_obj)); |
| 6558 | 6561 | if (!trans) |
| 6559 | − return -ENOMEM; | |
| 6562 | + goto err_trans; | |
| 6560 | 6563 | |
| 6561 | 6564 | newobj = nft_obj_init(ctx, type, attr); |
| 6562 | 6565 | if (IS_ERR(newobj)) { |
| @@ -6573,6 +6576,8 @@ static int nf_tables_updobj(const struct nft_ctx *ctx, · 10 unmodified lines | ||
| 6573 | 6576 | |
| 6574 | 6577 | err_free_trans: |
| 6575 | 6578 | kfree(trans); |
| 6579 | +err_trans: | |
| 6580 | + module_put(type->owner); | |
| 6576 | 6581 | return err; |
| 6577 | 6582 | } |
| 6578 | 6583 | |
| @@ -8185,7 +8190,7 @@ static void nft_obj_commit_update(struct nft_trans *trans) · 1606 unmodified lines | ||
| 8185 | 8190 | if (obj->ops->update) |
| 8186 | 8191 | obj->ops->update(obj, newobj); |
| 8187 | 8192 | |
| 8188 | − kfree(newobj); | |
| 8193 | + nft_obj_destroy(&trans->ctx, newobj); | |
| 8189 | 8194 | } |
| 8190 | 8195 | |
| 8191 | 8196 | static void nft_commit_release(struct nft_trans *trans) |
| @@ -8976,7 +8981,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) · 784 unmodified lines | ||
| 8976 | 8981 | break; |
| 8977 | 8982 | case NFT_MSG_NEWOBJ: |
| 8978 | 8983 | if (nft_trans_obj_update(trans)) { |
| 8979 | − kfree(nft_trans_obj_newobj(trans)); | |
| 8984 | + nft_obj_destroy(&trans->ctx, nft_trans_obj_newobj(trans)); | |
| 8980 | 8985 | nft_trans_destroy(trans); |
| 8981 | 8986 | } else { |
| 8982 | 8987 | trans->ctx.table->use--; |
| @@ -9636,10 +9641,13 @@ EXPORT_SYMBOL_GPL(__nft_release_basechain); · 653 unmodified lines | ||
| 9636 | 9641 | |
| 9637 | 9642 | static void __nft_release_hook(struct net *net, struct nft_table *table) |
| 9638 | 9643 | { |
| 9644 | + struct nft_flowtable *flowtable; | |
| 9639 | 9645 | struct nft_chain *chain; |
| 9640 | 9646 | |
| 9641 | 9647 | list_for_each_entry(chain, &table->chains, list) |
| 9642 | 9648 | nf_tables_unregister_hook(net, table, chain); |
| 9649 | + list_for_each_entry(flowtable, &table->flowtables, list) | |
| 9650 | + nft_unregister_flowtable_net_hooks(net, &flowtable->hook_list); | |
| 9643 | 9651 | } |
| 9644 | 9652 | |
| 9645 | 9653 | static void __nft_release_hooks(struct net *net) |
| @@ -94,7 +94,8 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net, · 93 unmodified lines | ||
| 94 | 94 | |
| 95 | 95 | expr = nft_expr_first(rule); |
| 96 | 96 | while (nft_expr_more(rule, expr)) { |
| 97 | − if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION) | |
| 97 | + if (expr->ops->offload_action && | |
| 98 | + expr->ops->offload_action(expr)) | |
| 98 | 99 | num_actions++; |
| 99 | 100 | |
| 100 | 101 | expr = nft_expr_next(expr); |
| @@ -67,6 +67,11 @@ static int nft_dup_netdev_offload(struct nft_offload_ctx *ctx, · 66 unmodified lines | ||
| 67 | 67 | return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_MIRRED, oif); |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | +static bool nft_dup_netdev_offload_action(const struct nft_expr *expr) | |
| 71 | +{ | |
| 72 | + return true; | |
| 73 | +} | |
| 74 | + | |
| 70 | 75 | static struct nft_expr_type nft_dup_netdev_type; |
| 71 | 76 | static const struct nft_expr_ops nft_dup_netdev_ops = { |
| 72 | 77 | .type = &nft_dup_netdev_type, |
| @@ -75,6 +80,7 @@ static const struct nft_expr_ops nft_dup_netdev_ops = { · 2 unmodified lines | ||
| 75 | 80 | .init = nft_dup_netdev_init, |
| 76 | 81 | .dump = nft_dup_netdev_dump, |
| 77 | 82 | .offload = nft_dup_netdev_offload, |
| 83 | + .offload_action = nft_dup_netdev_offload_action, | |
| 78 | 84 | }; |
| 79 | 85 | |
| 80 | 86 | static struct nft_expr_type nft_dup_netdev_type __read_mostly = { |
| @@ -79,6 +79,11 @@ static int nft_fwd_netdev_offload(struct nft_offload_ctx *ctx, · 78 unmodified lines | ||
| 79 | 79 | return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_REDIRECT, oif); |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | +static bool nft_fwd_netdev_offload_action(const struct nft_expr *expr) | |
| 83 | +{ | |
| 84 | + return true; | |
| 85 | +} | |
| 86 | + | |
| 82 | 87 | struct nft_fwd_neigh { |
| 83 | 88 | u8 sreg_dev; |
| 84 | 89 | u8 sreg_addr; |
| @@ -222,6 +227,7 @@ static const struct nft_expr_ops nft_fwd_netdev_ops = { · 137 unmodified lines | ||
| 222 | 227 | .dump = nft_fwd_netdev_dump, |
| 223 | 228 | .validate = nft_fwd_validate, |
| 224 | 229 | .offload = nft_fwd_netdev_offload, |
| 230 | + .offload_action = nft_fwd_netdev_offload_action, | |
| 225 | 231 | }; |
| 226 | 232 | |
| 227 | 233 | static const struct nft_expr_ops * |
| @@ -213,6 +213,16 @@ static int nft_immediate_offload(struct nft_offload_ctx *ctx, · 212 unmodified lines | ||
| 213 | 213 | return 0; |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | +static bool nft_immediate_offload_action(const struct nft_expr *expr) | |
| 217 | +{ | |
| 218 | + const struct nft_immediate_expr *priv = nft_expr_priv(expr); | |
| 219 | + | |
| 220 | + if (priv->dreg == NFT_REG_VERDICT) | |
| 221 | + return true; | |
| 222 | + | |
| 223 | + return false; | |
| 224 | +} | |
| 225 | + | |
| 216 | 226 | static const struct nft_expr_ops nft_imm_ops = { |
| 217 | 227 | .type = &nft_imm_type, |
| 218 | 228 | .size = NFT_EXPR_SIZE(sizeof(struct nft_immediate_expr)), |
| @@ -224,7 +234,7 @@ static const struct nft_expr_ops nft_imm_ops = { · 5 unmodified lines | ||
| 224 | 234 | .dump = nft_immediate_dump, |
| 225 | 235 | .validate = nft_immediate_validate, |
| 226 | 236 | .offload = nft_immediate_offload, |
| 227 | − .offload_flags = NFT_OFFLOAD_F_ACTION, | |
| 237 | + .offload_action = nft_immediate_offload_action, | |
| 228 | 238 | }; |
| 229 | 239 | |
| 230 | 240 | struct nft_expr_type nft_imm_type __read_mostly = { |
| @@ -340,11 +340,20 @@ static int nft_limit_obj_pkts_dump(struct sk_buff *skb, · 339 unmodified lines | ||
| 340 | 340 | return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS); |
| 341 | 341 | } |
| 342 | 342 | |
| 343 | +static void nft_limit_obj_pkts_destroy(const struct nft_ctx *ctx, | |
| 344 | + struct nft_object *obj) | |
| 345 | +{ | |
| 346 | + struct nft_limit_priv_pkts *priv = nft_obj_data(obj); | |
| 347 | + | |
| 348 | + nft_limit_destroy(ctx, &priv->limit); | |
| 349 | +} | |
| 350 | + | |
| 343 | 351 | static struct nft_object_type nft_limit_obj_type; |
| 344 | 352 | static const struct nft_object_ops nft_limit_obj_pkts_ops = { |
| 345 | 353 | .type = &nft_limit_obj_type, |
| 346 | 354 | .size = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv_pkts)), |
| 347 | 355 | .init = nft_limit_obj_pkts_init, |
| 356 | + .destroy = nft_limit_obj_pkts_destroy, | |
| 348 | 357 | .eval = nft_limit_obj_pkts_eval, |
| 349 | 358 | .dump = nft_limit_obj_pkts_dump, |
| 350 | 359 | }; |
| @@ -378,11 +387,20 @@ static int nft_limit_obj_bytes_dump(struct sk_buff *skb, · 27 unmodified lines | ||
| 378 | 387 | return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES); |
| 379 | 388 | } |
| 380 | 389 | |
| 390 | +static void nft_limit_obj_bytes_destroy(const struct nft_ctx *ctx, | |
| 391 | + struct nft_object *obj) | |
| 392 | +{ | |
| 393 | + struct nft_limit_priv *priv = nft_obj_data(obj); | |
| 394 | + | |
| 395 | + nft_limit_destroy(ctx, priv); | |
| 396 | +} | |
| 397 | + | |
| 381 | 398 | static struct nft_object_type nft_limit_obj_type; |
| 382 | 399 | static const struct nft_object_ops nft_limit_obj_bytes_ops = { |
| 383 | 400 | .type = &nft_limit_obj_type, |
| 384 | 401 | .size = sizeof(struct nft_limit_priv), |
| 385 | 402 | .init = nft_limit_obj_bytes_init, |
| 403 | + .destroy = nft_limit_obj_bytes_destroy, | |
| 386 | 404 | .eval = nft_limit_obj_bytes_eval, |
| 387 | 405 | .dump = nft_limit_obj_bytes_dump, |
| 388 | 406 | }; |
| @@ -220,8 +220,10 @@ static void socket_mt_destroy(const struct xt_mtdtor_param *par) · 219 unmodified lines | ||
| 220 | 220 | { |
| 221 | 221 | if (par->family == NFPROTO_IPV4) |
| 222 | 222 | nf_defrag_ipv4_disable(par->net); |
| 223 | +#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) | |
| 223 | 224 | else if (par->family == NFPROTO_IPV6) |
| 224 | 225 | nf_defrag_ipv6_disable(par->net); |
| 226 | +#endif | |
| 225 | 227 | } |
| 226 | 228 | |
| 227 | 229 | static struct xt_match socket_mt_reg[] __read_mostly = { |
| @@ -423,12 +423,43 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto, · 422 unmodified lines | ||
| 423 | 423 | memcpy(addr, new_addr, sizeof(__be32[4])); |
| 424 | 424 | } |
| 425 | 425 | |
| 426 | −static void set_ipv6_fl(struct ipv6hdr *nh, u32 fl, u32 mask) | |
| 426 | +static void set_ipv6_dsfield(struct sk_buff *skb, struct ipv6hdr *nh, u8 ipv6_tclass, u8 mask) | |
| 427 | 427 | { |
| 428 | + u8 old_ipv6_tclass = ipv6_get_dsfield(nh); | |
| 429 | + | |
| 430 | + ipv6_tclass = OVS_MASKED(old_ipv6_tclass, ipv6_tclass, mask); | |
| 431 | + | |
| 432 | + if (skb->ip_summed == CHECKSUM_COMPLETE) | |
| 433 | + csum_replace(&skb->csum, (__force __wsum)(old_ipv6_tclass << 12), | |
| 434 | + (__force __wsum)(ipv6_tclass << 12)); | |
| 435 | + | |
| 436 | + ipv6_change_dsfield(nh, ~mask, ipv6_tclass); | |
| 437 | +} | |
| 438 | + | |
| 439 | +static void set_ipv6_fl(struct sk_buff *skb, struct ipv6hdr *nh, u32 fl, u32 mask) | |
| 440 | +{ | |
| 441 | + u32 ofl; | |
| 442 | + | |
| 443 | + ofl = nh->flow_lbl[0] << 16 | nh->flow_lbl[1] << 8 | nh->flow_lbl[2]; | |
| 444 | + fl = OVS_MASKED(ofl, fl, mask); | |
| 445 | + | |
| 428 | 446 | /* Bits 21-24 are always unmasked, so this retains their values. */ |
| 429 | − OVS_SET_MASKED(nh->flow_lbl[0], (u8)(fl >> 16), (u8)(mask >> 16)); | |
| 430 | − OVS_SET_MASKED(nh->flow_lbl[1], (u8)(fl >> 8), (u8)(mask >> 8)); | |
| 431 | − OVS_SET_MASKED(nh->flow_lbl[2], (u8)fl, (u8)mask); | |
| 447 | + nh->flow_lbl[0] = (u8)(fl >> 16); | |
| 448 | + nh->flow_lbl[1] = (u8)(fl >> 8); | |
| 449 | + nh->flow_lbl[2] = (u8)fl; | |
| 450 | + | |
| 451 | + if (skb->ip_summed == CHECKSUM_COMPLETE) | |
| 452 | + csum_replace(&skb->csum, (__force __wsum)htonl(ofl), (__force __wsum)htonl(fl)); | |
| 453 | +} | |
| 454 | + | |
| 455 | +static void set_ipv6_ttl(struct sk_buff *skb, struct ipv6hdr *nh, u8 new_ttl, u8 mask) | |
| 456 | +{ | |
| 457 | + new_ttl = OVS_MASKED(nh->hop_limit, new_ttl, mask); | |
| 458 | + | |
| 459 | + if (skb->ip_summed == CHECKSUM_COMPLETE) | |
| 460 | + csum_replace(&skb->csum, (__force __wsum)(nh->hop_limit << 8), | |
| 461 | + (__force __wsum)(new_ttl << 8)); | |
| 462 | + nh->hop_limit = new_ttl; | |
| 432 | 463 | } |
| 433 | 464 | |
| 434 | 465 | static void set_ip_ttl(struct sk_buff *skb, struct iphdr *nh, u8 new_ttl, |
| @@ -546,18 +577,17 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key, · 111 unmodified lines | ||
| 546 | 577 | } |
| 547 | 578 | } |
| 548 | 579 | if (mask->ipv6_tclass) { |
| 549 | − ipv6_change_dsfield(nh, ~mask->ipv6_tclass, key->ipv6_tclass); | |
| 580 | + set_ipv6_dsfield(skb, nh, key->ipv6_tclass, mask->ipv6_tclass); | |
| 550 | 581 | flow_key->ip.tos = ipv6_get_dsfield(nh); |
| 551 | 582 | } |
| 552 | 583 | if (mask->ipv6_label) { |
| 553 | − set_ipv6_fl(nh, ntohl(key->ipv6_label), | |
| 584 | + set_ipv6_fl(skb, nh, ntohl(key->ipv6_label), | |
| 554 | 585 | ntohl(mask->ipv6_label)); |
| 555 | 586 | flow_key->ipv6.label = |
| 556 | 587 | *(__be32 *)nh & htonl(IPV6_FLOWINFO_FLOWLABEL); |
| 557 | 588 | } |
| 558 | 589 | if (mask->ipv6_hlimit) { |
| 559 | − OVS_SET_MASKED(nh->hop_limit, key->ipv6_hlimit, | |
| 560 | − mask->ipv6_hlimit); | |
| 590 | + set_ipv6_ttl(skb, nh, key->ipv6_hlimit, mask->ipv6_hlimit); | |
| 561 | 591 | flow_key->ip.ttl = nh->hop_limit; |
| 562 | 592 | } |
| 563 | 593 | return 0; |
| @@ -274,7 +274,7 @@ static int tcf_action_offload_add_ex(struct tc_action *action, · 273 unmodified lines | ||
| 274 | 274 | err = tc_setup_action(&fl_action->action, actions); |
| 275 | 275 | if (err) { |
| 276 | 276 | NL_SET_ERR_MSG_MOD(extack, |
| 277 | − "Failed to setup tc actions for offload\n"); | |
| 277 | + "Failed to setup tc actions for offload"); | |
| 278 | 278 | goto fl_err; |
| 279 | 279 | } |
| 280 | 280 | |
| @@ -527,11 +527,6 @@ static bool tcf_ct_flow_table_lookup(struct tcf_ct_params *p, · 526 unmodified lines | ||
| 527 | 527 | struct nf_conn *ct; |
| 528 | 528 | u8 dir; |
| 529 | 529 | |
| 530 | − /* Previously seen or loopback */ | |
| 531 | − ct = nf_ct_get(skb, &ctinfo); | |
| 532 | − if ((ct && !nf_ct_is_template(ct)) || ctinfo == IP_CT_UNTRACKED) | |
| 533 | − return false; | |
| 534 | − | |
| 535 | 530 | switch (family) { |
| 536 | 531 | case NFPROTO_IPV4: |
| 537 | 532 | if (!tcf_ct_flow_table_fill_tuple_ipv4(skb, &tuple, &tcph)) |
| @@ -113,7 +113,7 @@ static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name) · 112 unmodified lines | ||
| 113 | 113 | pnettable = &sn->pnettable; |
| 114 | 114 | |
| 115 | 115 | /* remove table entry */ |
| 116 | − write_lock(&pnettable->lock); | |
| 116 | + mutex_lock(&pnettable->lock); | |
| 117 | 117 | list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist, |
| 118 | 118 | list) { |
| 119 | 119 | if (!pnet_name || |
| @@ -131,7 +131,7 @@ static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name) · 11 unmodified lines | ||
| 131 | 131 | rc = 0; |
| 132 | 132 | } |
| 133 | 133 | } |
| 134 | − write_unlock(&pnettable->lock); | |
| 134 | + mutex_unlock(&pnettable->lock); | |
| 135 | 135 | |
| 136 | 136 | /* if this is not the initial namespace, stop here */ |
| 137 | 137 | if (net != &init_net) |
| @@ -192,7 +192,7 @@ static int smc_pnet_add_by_ndev(struct net_device *ndev) · 54 unmodified lines | ||
| 192 | 192 | sn = net_generic(net, smc_net_id); |
| 193 | 193 | pnettable = &sn->pnettable; |
| 194 | 194 | |
| 195 | − write_lock(&pnettable->lock); | |
| 195 | + mutex_lock(&pnettable->lock); | |
| 196 | 196 | list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist, list) { |
| 197 | 197 | if (pnetelem->type == SMC_PNET_ETH && !pnetelem->ndev && |
| 198 | 198 | !strncmp(pnetelem->eth_name, ndev->name, IFNAMSIZ)) { |
| @@ -206,7 +206,7 @@ static int smc_pnet_add_by_ndev(struct net_device *ndev) · 7 unmodified lines | ||
| 206 | 206 | break; |
| 207 | 207 | } |
| 208 | 208 | } |
| 209 | − write_unlock(&pnettable->lock); | |
| 209 | + mutex_unlock(&pnettable->lock); | |
| 210 | 210 | return rc; |
| 211 | 211 | } |
| 212 | 212 | |
| @@ -224,7 +224,7 @@ static int smc_pnet_remove_by_ndev(struct net_device *ndev) · 11 unmodified lines | ||
| 224 | 224 | sn = net_generic(net, smc_net_id); |
| 225 | 225 | pnettable = &sn->pnettable; |
| 226 | 226 | |
| 227 | − write_lock(&pnettable->lock); | |
| 227 | + mutex_lock(&pnettable->lock); | |
| 228 | 228 | list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist, list) { |
| 229 | 229 | if (pnetelem->type == SMC_PNET_ETH && pnetelem->ndev == ndev) { |
| 230 | 230 | dev_put_track(pnetelem->ndev, &pnetelem->dev_tracker); |
| @@ -237,7 +237,7 @@ static int smc_pnet_remove_by_ndev(struct net_device *ndev) · 6 unmodified lines | ||
| 237 | 237 | break; |
| 238 | 238 | } |
| 239 | 239 | } |
| 240 | − write_unlock(&pnettable->lock); | |
| 240 | + mutex_unlock(&pnettable->lock); | |
| 241 | 241 | return rc; |
| 242 | 242 | } |
| 243 | 243 | |
| @@ -370,7 +370,7 @@ static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net, · 126 unmodified lines | ||
| 370 | 370 | strncpy(new_pe->eth_name, eth_name, IFNAMSIZ); |
| 371 | 371 | rc = -EEXIST; |
| 372 | 372 | new_netdev = true; |
| 373 | − write_lock(&pnettable->lock); | |
| 373 | + mutex_lock(&pnettable->lock); | |
| 374 | 374 | list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) { |
| 375 | 375 | if (tmp_pe->type == SMC_PNET_ETH && |
| 376 | 376 | !strncmp(tmp_pe->eth_name, eth_name, IFNAMSIZ)) { |
| @@ -385,9 +385,9 @@ static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net, · 8 unmodified lines | ||
| 385 | 385 | GFP_ATOMIC); |
| 386 | 386 | } |
| 387 | 387 | list_add_tail(&new_pe->list, &pnettable->pnetlist); |
| 388 | − write_unlock(&pnettable->lock); | |
| 388 | + mutex_unlock(&pnettable->lock); | |
| 389 | 389 | } else { |
| 390 | − write_unlock(&pnettable->lock); | |
| 390 | + mutex_unlock(&pnettable->lock); | |
| 391 | 391 | kfree(new_pe); |
| 392 | 392 | goto out_put; |
| 393 | 393 | } |
| @@ -448,7 +448,7 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name, · 54 unmodified lines | ||
| 448 | 448 | new_pe->ib_port = ib_port; |
| 449 | 449 | |
| 450 | 450 | new_ibdev = true; |
| 451 | − write_lock(&pnettable->lock); | |
| 451 | + mutex_lock(&pnettable->lock); | |
| 452 | 452 | list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) { |
| 453 | 453 | if (tmp_pe->type == SMC_PNET_IB && |
| 454 | 454 | !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX)) { |
| @@ -458,9 +458,9 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name, · 3 unmodified lines | ||
| 458 | 458 | } |
| 459 | 459 | if (new_ibdev) { |
| 460 | 460 | list_add_tail(&new_pe->list, &pnettable->pnetlist); |
| 461 | − write_unlock(&pnettable->lock); | |
| 461 | + mutex_unlock(&pnettable->lock); | |
| 462 | 462 | } else { |
| 463 | − write_unlock(&pnettable->lock); | |
| 463 | + mutex_unlock(&pnettable->lock); | |
| 464 | 464 | kfree(new_pe); |
| 465 | 465 | } |
| 466 | 466 | return (new_ibdev) ? 0 : -EEXIST; |
| @@ -605,7 +605,7 @@ static int _smc_pnet_dump(struct net *net, struct sk_buff *skb, u32 portid, · 138 unmodified lines | ||
| 605 | 605 | pnettable = &sn->pnettable; |
| 606 | 606 | |
| 607 | 607 | /* dump pnettable entries */ |
| 608 | − read_lock(&pnettable->lock); | |
| 608 | + mutex_lock(&pnettable->lock); | |
| 609 | 609 | list_for_each_entry(pnetelem, &pnettable->pnetlist, list) { |
| 610 | 610 | if (pnetid && !smc_pnet_match(pnetelem->pnet_name, pnetid)) |
| 611 | 611 | continue; |
| @@ -620,7 +620,7 @@ static int _smc_pnet_dump(struct net *net, struct sk_buff *skb, u32 portid, · 8 unmodified lines | ||
| 620 | 620 | break; |
| 621 | 621 | } |
| 622 | 622 | } |
| 623 | − read_unlock(&pnettable->lock); | |
| 623 | + mutex_unlock(&pnettable->lock); | |
| 624 | 624 | return idx; |
| 625 | 625 | } |
| 626 | 626 | |
| @@ -864,7 +864,7 @@ int smc_pnet_net_init(struct net *net) · 237 unmodified lines | ||
| 864 | 864 | struct smc_pnetids_ndev *pnetids_ndev = &sn->pnetids_ndev; |
| 865 | 865 | |
| 866 | 866 | INIT_LIST_HEAD(&pnettable->pnetlist); |
| 867 | − rwlock_init(&pnettable->lock); | |
| 867 | + mutex_init(&pnettable->lock); | |
| 868 | 868 | INIT_LIST_HEAD(&pnetids_ndev->list); |
| 869 | 869 | rwlock_init(&pnetids_ndev->lock); |
| 870 | 870 | |
| @@ -947,7 +947,7 @@ static int smc_pnet_find_ndev_pnetid_by_table(struct net_device *ndev, · 76 unmodified lines | ||
| 947 | 947 | sn = net_generic(net, smc_net_id); |
| 948 | 948 | pnettable = &sn->pnettable; |
| 949 | 949 | |
| 950 | − read_lock(&pnettable->lock); | |
| 950 | + mutex_lock(&pnettable->lock); | |
| 951 | 951 | list_for_each_entry(pnetelem, &pnettable->pnetlist, list) { |
| 952 | 952 | if (pnetelem->type == SMC_PNET_ETH && ndev == pnetelem->ndev) { |
| 953 | 953 | /* get pnetid of netdev device */ |
| @@ -956,7 +956,7 @@ static int smc_pnet_find_ndev_pnetid_by_table(struct net_device *ndev, · 2 unmodified lines | ||
| 956 | 956 | break; |
| 957 | 957 | } |
| 958 | 958 | } |
| 959 | − read_unlock(&pnettable->lock); | |
| 959 | + mutex_unlock(&pnettable->lock); | |
| 960 | 960 | return rc; |
| 961 | 961 | } |
| 962 | 962 | |
| @@ -1159,7 +1159,7 @@ int smc_pnetid_by_table_ib(struct smc_ib_device *smcibdev, u8 ib_port) · 196 unmodified lines | ||
| 1159 | 1159 | sn = net_generic(&init_net, smc_net_id); |
| 1160 | 1160 | pnettable = &sn->pnettable; |
| 1161 | 1161 | |
| 1162 | − read_lock(&pnettable->lock); | |
| 1162 | + mutex_lock(&pnettable->lock); | |
| 1163 | 1163 | list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) { |
| 1164 | 1164 | if (tmp_pe->type == SMC_PNET_IB && |
| 1165 | 1165 | !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX) && |
| @@ -1169,7 +1169,7 @@ int smc_pnetid_by_table_ib(struct smc_ib_device *smcibdev, u8 ib_port) · 3 unmodified lines | ||
| 1169 | 1169 | break; |
| 1170 | 1170 | } |
| 1171 | 1171 | } |
| 1172 | − read_unlock(&pnettable->lock); | |
| 1172 | + mutex_unlock(&pnettable->lock); | |
| 1173 | 1173 | |
| 1174 | 1174 | return rc; |
| 1175 | 1175 | } |
| @@ -1188,7 +1188,7 @@ int smc_pnetid_by_table_smcd(struct smcd_dev *smcddev) · 12 unmodified lines | ||
| 1188 | 1188 | sn = net_generic(&init_net, smc_net_id); |
| 1189 | 1189 | pnettable = &sn->pnettable; |
| 1190 | 1190 | |
| 1191 | − read_lock(&pnettable->lock); | |
| 1191 | + mutex_lock(&pnettable->lock); | |
| 1192 | 1192 | list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) { |
| 1193 | 1193 | if (tmp_pe->type == SMC_PNET_IB && |
| 1194 | 1194 | !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX)) { |
| @@ -1197,7 +1197,7 @@ int smc_pnetid_by_table_smcd(struct smcd_dev *smcddev) · 2 unmodified lines | ||
| 1197 | 1197 | break; |
| 1198 | 1198 | } |
| 1199 | 1199 | } |
| 1200 | − read_unlock(&pnettable->lock); | |
| 1200 | + mutex_unlock(&pnettable->lock); | |
| 1201 | 1201 | |
| 1202 | 1202 | return rc; |
| 1203 | 1203 | } |
| @@ -29,7 +29,7 @@ struct smc_link_group; · 28 unmodified lines | ||
| 29 | 29 | * @pnetlist: List of PNETIDs |
| 30 | 30 | */ |
| 31 | 31 | struct smc_pnettable { |
| 32 | − rwlock_t lock; | |
| 32 | + struct mutex lock; | |
| 33 | 33 | struct list_head pnetlist; |
| 34 | 34 | }; |
| 35 | 35 | |
| @@ -967,7 +967,7 @@ static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg, · 966 unmodified lines | ||
| 967 | 967 | list_for_each_entry(p, &sr->all_publ, all_publ) |
| 968 | 968 | if (p->key == *last_key) |
| 969 | 969 | break; |
| 970 | − if (p->key != *last_key) | |
| 970 | + if (list_entry_is_head(p, &sr->all_publ, all_publ)) | |
| 971 | 971 | return -EPIPE; |
| 972 | 972 | } else { |
| 973 | 973 | p = list_first_entry(&sr->all_publ, |
| @@ -3749,7 +3749,7 @@ static int __tipc_nl_list_sk_publ(struct sk_buff *skb, · 3748 unmodified lines | ||
| 3749 | 3749 | if (p->key == *last_publ) |
| 3750 | 3750 | break; |
| 3751 | 3751 | } |
| 3752 | − if (p->key != *last_publ) { | |
| 3752 | + if (list_entry_is_head(p, &tsk->publications, binding_sock)) { | |
| 3753 | 3753 | /* We never set seq or call nl_dump_check_consistent() |
| 3754 | 3754 | * this means that setting prev_seq here will cause the |
| 3755 | 3755 | * consistence check to fail in the netlink callback |
| @@ -77,7 +77,7 @@ void selinux_ima_measure_state_locked(struct selinux_state *state) · 76 unmodified lines | ||
| 77 | 77 | size_t policy_len; |
| 78 | 78 | int rc = 0; |
| 79 | 79 | |
| 80 | − WARN_ON(!mutex_is_locked(&state->policy_mutex)); | |
| 80 | + lockdep_assert_held(&state->policy_mutex); | |
| 81 | 81 | |
| 82 | 82 | state_str = selinux_ima_collect_state(state); |
| 83 | 83 | if (!state_str) { |
| @@ -117,7 +117,7 @@ void selinux_ima_measure_state_locked(struct selinux_state *state) · 33 unmodified lines | ||
| 117 | 117 | */ |
| 118 | 118 | void selinux_ima_measure_state(struct selinux_state *state) |
| 119 | 119 | { |
| 120 | − WARN_ON(mutex_is_locked(&state->policy_mutex)); | |
| 120 | + lockdep_assert_not_held(&state->policy_mutex); | |
| 121 | 121 | |
| 122 | 122 | mutex_lock(&state->policy_mutex); |
| 123 | 123 | selinux_ima_measure_state_locked(state); |
| @@ -511,7 +511,8 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size) · 510 unmodified lines | ||
| 511 | 511 | DEFAULT_GFP, 0); |
| 512 | 512 | if (!sgt) |
| 513 | 513 | return NULL; |
| 514 | − dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, dmab->dev.dir); | |
| 514 | + dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, | |
| 515 | + sg_dma_address(sgt->sgl)); | |
| 515 | 516 | p = dma_vmap_noncontiguous(dmab->dev.dev, size, sgt); |
| 516 | 517 | if (p) |
| 517 | 518 | dmab->private_data = sgt; |
| @@ -540,9 +541,9 @@ static void snd_dma_noncontig_sync(struct snd_dma_buffer *dmab, · 22 unmodified lines | ||
| 540 | 541 | if (mode == SNDRV_DMA_SYNC_CPU) { |
| 541 | 542 | if (dmab->dev.dir == DMA_TO_DEVICE) |
| 542 | 543 | return; |
| 544 | + invalidate_kernel_vmap_range(dmab->area, dmab->bytes); | |
| 543 | 545 | dma_sync_sgtable_for_cpu(dmab->dev.dev, dmab->private_data, |
| 544 | 546 | dmab->dev.dir); |
| 545 | − invalidate_kernel_vmap_range(dmab->area, dmab->bytes); | |
| 546 | 547 | } else { |
| 547 | 548 | if (dmab->dev.dir == DMA_FROM_DEVICE) |
| 548 | 549 | return; |
| @@ -671,9 +672,13 @@ static const struct snd_malloc_ops snd_dma_sg_wc_ops = { · 122 unmodified lines | ||
| 671 | 672 | */ |
| 672 | 673 | static void *snd_dma_noncoherent_alloc(struct snd_dma_buffer *dmab, size_t size) |
| 673 | 674 | { |
| 674 | − dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, dmab->dev.dir); | |
| 675 | − return dma_alloc_noncoherent(dmab->dev.dev, size, &dmab->addr, | |
| 676 | − dmab->dev.dir, DEFAULT_GFP); | |
| 675 | + void *p; | |
| 676 | + | |
| 677 | + p = dma_alloc_noncoherent(dmab->dev.dev, size, &dmab->addr, | |
| 678 | + dmab->dev.dir, DEFAULT_GFP); | |
| 679 | + if (p) | |
| 680 | + dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, dmab->addr); | |
| 681 | + return p; | |
| 677 | 682 | } |
| 678 | 683 | |
| 679 | 684 | static void snd_dma_noncoherent_free(struct snd_dma_buffer *dmab) |
| @@ -1615,6 +1615,7 @@ static const struct snd_pci_quirk probe_mask_list[] = { · 1614 unmodified lines | ||
| 1615 | 1615 | /* forced codec slots */ |
| 1616 | 1616 | SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103), |
| 1617 | 1617 | SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103), |
| 1618 | + SND_PCI_QUIRK(0x1558, 0x0351, "Schenker Dock 15", 0x105), | |
| 1618 | 1619 | /* WinFast VP200 H (Teradici) user reported broken communication */ |
| 1619 | 1620 | SND_PCI_QUIRK(0x3a21, 0x040d, "WinFast VP200 H", 0x101), |
| 1620 | 1621 | {} |
| @@ -1798,8 +1799,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, · 177 unmodified lines | ||
| 1798 | 1799 | |
| 1799 | 1800 | assign_position_fix(chip, check_position_fix(chip, position_fix[dev])); |
| 1800 | 1801 | |
| 1801 | − check_probe_mask(chip, dev); | |
| 1802 | − | |
| 1803 | 1802 | if (single_cmd < 0) /* allow fallback to single_cmd at errors */ |
| 1804 | 1803 | chip->fallback_to_single_cmd = 1; |
| 1805 | 1804 | else /* explicitly set to single_cmd or not */ |
| @@ -1825,6 +1824,8 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, · 19 unmodified lines | ||
| 1825 | 1824 | chip->bus.core.needs_damn_long_delay = 1; |
| 1826 | 1825 | } |
| 1827 | 1826 | |
| 1827 | + check_probe_mask(chip, dev); | |
| 1828 | + | |
| 1828 | 1829 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); |
| 1829 | 1830 | if (err < 0) { |
| 1830 | 1831 | dev_err(card->dev, "Error creating device [card]!\n"); |
| @@ -1940,6 +1941,7 @@ static int azx_first_init(struct azx *chip) · 109 unmodified lines | ||
| 1940 | 1941 | dma_bits = 32; |
| 1941 | 1942 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(dma_bits))) |
| 1942 | 1943 | dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)); |
| 1944 | + dma_set_max_seg_size(&pci->dev, UINT_MAX); | |
| 1943 | 1945 | |
| 1944 | 1946 | /* read number of streams from GCAP register instead of using |
| 1945 | 1947 | * hardcoded value |
| @@ -138,6 +138,22 @@ struct alc_spec { · 137 unmodified lines | ||
| 138 | 138 | * COEF access helper functions |
| 139 | 139 | */ |
| 140 | 140 | |
| 141 | +static void coef_mutex_lock(struct hda_codec *codec) | |
| 142 | +{ | |
| 143 | + struct alc_spec *spec = codec->spec; | |
| 144 | + | |
| 145 | + snd_hda_power_up_pm(codec); | |
| 146 | + mutex_lock(&spec->coef_mutex); | |
| 147 | +} | |
| 148 | + | |
| 149 | +static void coef_mutex_unlock(struct hda_codec *codec) | |
| 150 | +{ | |
| 151 | + struct alc_spec *spec = codec->spec; | |
| 152 | + | |
| 153 | + mutex_unlock(&spec->coef_mutex); | |
| 154 | + snd_hda_power_down_pm(codec); | |
| 155 | +} | |
| 156 | + | |
| 141 | 157 | static int __alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid, |
| 142 | 158 | unsigned int coef_idx) |
| 143 | 159 | { |
| @@ -151,12 +167,11 @@ static int __alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid, · 7 unmodified lines | ||
| 151 | 167 | static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid, |
| 152 | 168 | unsigned int coef_idx) |
| 153 | 169 | { |
| 154 | − struct alc_spec *spec = codec->spec; | |
| 155 | 170 | unsigned int val; |
| 156 | 171 | |
| 157 | − mutex_lock(&spec->coef_mutex); | |
| 172 | + coef_mutex_lock(codec); | |
| 158 | 173 | val = __alc_read_coefex_idx(codec, nid, coef_idx); |
| 159 | − mutex_unlock(&spec->coef_mutex); | |
| 174 | + coef_mutex_unlock(codec); | |
| 160 | 175 | return val; |
| 161 | 176 | } |
| 162 | 177 | |
| @@ -173,11 +188,9 @@ static void __alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, · 10 unmodified lines | ||
| 173 | 188 | static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, |
| 174 | 189 | unsigned int coef_idx, unsigned int coef_val) |
| 175 | 190 | { |
| 176 | − struct alc_spec *spec = codec->spec; | |
| 177 | − | |
| 178 | − mutex_lock(&spec->coef_mutex); | |
| 191 | + coef_mutex_lock(codec); | |
| 179 | 192 | __alc_write_coefex_idx(codec, nid, coef_idx, coef_val); |
| 180 | − mutex_unlock(&spec->coef_mutex); | |
| 193 | + coef_mutex_unlock(codec); | |
| 181 | 194 | } |
| 182 | 195 | |
| 183 | 196 | #define alc_write_coef_idx(codec, coef_idx, coef_val) \ |
| @@ -198,11 +211,9 @@ static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid, · 14 unmodified lines | ||
| 198 | 211 | unsigned int coef_idx, unsigned int mask, |
| 199 | 212 | unsigned int bits_set) |
| 200 | 213 | { |
| 201 | − struct alc_spec *spec = codec->spec; | |
| 202 | − | |
| 203 | − mutex_lock(&spec->coef_mutex); | |
| 214 | + coef_mutex_lock(codec); | |
| 204 | 215 | __alc_update_coefex_idx(codec, nid, coef_idx, mask, bits_set); |
| 205 | − mutex_unlock(&spec->coef_mutex); | |
| 216 | + coef_mutex_unlock(codec); | |
| 206 | 217 | } |
| 207 | 218 | |
| 208 | 219 | #define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \ |
| @@ -235,9 +246,7 @@ struct coef_fw { · 26 unmodified lines | ||
| 235 | 246 | static void alc_process_coef_fw(struct hda_codec *codec, |
| 236 | 247 | const struct coef_fw *fw) |
| 237 | 248 | { |
| 238 | − struct alc_spec *spec = codec->spec; | |
| 239 | − | |
| 240 | − mutex_lock(&spec->coef_mutex); | |
| 249 | + coef_mutex_lock(codec); | |
| 241 | 250 | for (; fw->nid; fw++) { |
| 242 | 251 | if (fw->mask == (unsigned short)-1) |
| 243 | 252 | __alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val); |
| @@ -245,7 +254,7 @@ static void alc_process_coef_fw(struct hda_codec *codec, · 1 unmodified line | ||
| 245 | 254 | __alc_update_coefex_idx(codec, fw->nid, fw->idx, |
| 246 | 255 | fw->mask, fw->val); |
| 247 | 256 | } |
| 248 | − mutex_unlock(&spec->coef_mutex); | |
| 257 | + coef_mutex_unlock(codec); | |
| 249 | 258 | } |
| 250 | 259 | |
| 251 | 260 | /* |
| @@ -9170,6 +9179,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 8918 unmodified lines | ||
| 9170 | 9179 | SND_PCI_QUIRK(0x17aa, 0x3824, "Legion Y9000X 2020", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS), |
| 9171 | 9180 | SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF), |
| 9172 | 9181 | SND_PCI_QUIRK(0x17aa, 0x3834, "Lenovo IdeaPad Slim 9i 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), |
| 9182 | + SND_PCI_QUIRK(0x17aa, 0x383d, "Legion Y9000X 2019", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS), | |
| 9173 | 9183 | SND_PCI_QUIRK(0x17aa, 0x3843, "Yoga 9i", ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP), |
| 9174 | 9184 | SND_PCI_QUIRK(0x17aa, 0x3847, "Legion 7 16ACHG6", ALC287_FIXUP_LEGION_16ACHG6), |
| 9175 | 9185 | SND_PCI_QUIRK(0x17aa, 0x384a, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), |
| @@ -21,7 +21,6 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/gpio/consumer.h> |
| 22 | 22 | |
| 23 | 23 | #define EN_SPKR_GPIO_GB 0x11F |
| 24 | −#define EN_SPKR_GPIO_NK 0x146 | |
| 25 | 24 | #define EN_SPKR_GPIO_NONE -EINVAL |
| 26 | 25 | |
| 27 | 26 | enum be_id { |
| @@ -37,7 +37,7 @@ static struct acp_card_drvdata sof_rt5682_max_data = { · 36 unmodified lines | ||
| 37 | 37 | .hs_codec_id = RT5682, |
| 38 | 38 | .amp_codec_id = MAX98360A, |
| 39 | 39 | .dmic_codec_id = DMIC, |
| 40 | − .gpio_spkr_en = EN_SPKR_GPIO_NK, | |
| 40 | + .gpio_spkr_en = EN_SPKR_GPIO_NONE, | |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | 43 | static struct acp_card_drvdata sof_rt5682s_max_data = { |
| @@ -47,7 +47,7 @@ static struct acp_card_drvdata sof_rt5682s_max_data = { · 3 unmodified lines | ||
| 47 | 47 | .hs_codec_id = RT5682S, |
| 48 | 48 | .amp_codec_id = MAX98360A, |
| 49 | 49 | .dmic_codec_id = DMIC, |
| 50 | − .gpio_spkr_en = EN_SPKR_GPIO_NK, | |
| 50 | + .gpio_spkr_en = EN_SPKR_GPIO_NONE, | |
| 51 | 51 | }; |
| 52 | 52 | |
| 53 | 53 | static const struct snd_kcontrol_new acp_controls[] = { |
| @@ -1022,11 +1022,13 @@ static void rt5668_jack_detect_handler(struct work_struct *work) · 1021 unmodified lines | ||
| 1022 | 1022 | container_of(work, struct rt5668_priv, jack_detect_work.work); |
| 1023 | 1023 | int val, btn_type; |
| 1024 | 1024 | |
| 1025 | − while (!rt5668->component) | |
| 1026 | − usleep_range(10000, 15000); | |
| 1027 | − | |
| 1028 | − while (!rt5668->component->card->instantiated) | |
| 1029 | − usleep_range(10000, 15000); | |
| 1025 | + if (!rt5668->component || !rt5668->component->card || | |
| 1026 | + !rt5668->component->card->instantiated) { | |
| 1027 | + /* card not yet ready, try later */ | |
| 1028 | + mod_delayed_work(system_power_efficient_wq, | |
| 1029 | + &rt5668->jack_detect_work, msecs_to_jiffies(15)); | |
| 1030 | + return; | |
| 1031 | + } | |
| 1030 | 1032 | |
| 1031 | 1033 | mutex_lock(&rt5668->calibrate_mutex); |
| 1032 | 1034 | |
| @@ -1092,11 +1092,13 @@ void rt5682_jack_detect_handler(struct work_struct *work) · 1091 unmodified lines | ||
| 1092 | 1092 | struct snd_soc_dapm_context *dapm; |
| 1093 | 1093 | int val, btn_type; |
| 1094 | 1094 | |
| 1095 | − while (!rt5682->component) | |
| 1096 | − usleep_range(10000, 15000); | |
| 1097 | − | |
| 1098 | − while (!rt5682->component->card->instantiated) | |
| 1099 | − usleep_range(10000, 15000); | |
| 1095 | + if (!rt5682->component || !rt5682->component->card || | |
| 1096 | + !rt5682->component->card->instantiated) { | |
| 1097 | + /* card not yet ready, try later */ | |
| 1098 | + mod_delayed_work(system_power_efficient_wq, | |
| 1099 | + &rt5682->jack_detect_work, msecs_to_jiffies(15)); | |
| 1100 | + return; | |
| 1101 | + } | |
| 1100 | 1102 | |
| 1101 | 1103 | dapm = snd_soc_component_get_dapm(rt5682->component); |
| 1102 | 1104 | |
| @@ -824,11 +824,13 @@ static void rt5682s_jack_detect_handler(struct work_struct *work) · 823 unmodified lines | ||
| 824 | 824 | container_of(work, struct rt5682s_priv, jack_detect_work.work); |
| 825 | 825 | int val, btn_type; |
| 826 | 826 | |
| 827 | − while (!rt5682s->component) | |
| 828 | − usleep_range(10000, 15000); | |
| 829 | − | |
| 830 | − while (!rt5682s->component->card->instantiated) | |
| 831 | − usleep_range(10000, 15000); | |
| 827 | + if (!rt5682s->component || !rt5682s->component->card || | |
| 828 | + !rt5682s->component->card->instantiated) { | |
| 829 | + /* card not yet ready, try later */ | |
| 830 | + mod_delayed_work(system_power_efficient_wq, | |
| 831 | + &rt5682s->jack_detect_work, msecs_to_jiffies(15)); | |
| 832 | + return; | |
| 833 | + } | |
| 832 | 834 | |
| 833 | 835 | mutex_lock(&rt5682s->jdet_mutex); |
| 834 | 836 | mutex_lock(&rt5682s->calibrate_mutex); |
| @@ -38,10 +38,12 @@ static void tas2770_reset(struct tas2770_priv *tas2770) · 37 unmodified lines | ||
| 38 | 38 | gpiod_set_value_cansleep(tas2770->reset_gpio, 0); |
| 39 | 39 | msleep(20); |
| 40 | 40 | gpiod_set_value_cansleep(tas2770->reset_gpio, 1); |
| 41 | + usleep_range(1000, 2000); | |
| 41 | 42 | } |
| 42 | 43 | |
| 43 | 44 | snd_soc_component_write(tas2770->component, TAS2770_SW_RST, |
| 44 | 45 | TAS2770_RST); |
| 46 | + usleep_range(1000, 2000); | |
| 45 | 47 | } |
| 46 | 48 | |
| 47 | 49 | static int tas2770_set_bias_level(struct snd_soc_component *component, |
| @@ -110,6 +112,7 @@ static int tas2770_codec_resume(struct snd_soc_component *component) · 62 unmodified lines | ||
| 110 | 112 | |
| 111 | 113 | if (tas2770->sdz_gpio) { |
| 112 | 114 | gpiod_set_value_cansleep(tas2770->sdz_gpio, 1); |
| 115 | + usleep_range(1000, 2000); | |
| 113 | 116 | } else { |
| 114 | 117 | ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL, |
| 115 | 118 | TAS2770_PWR_CTRL_MASK, |
| @@ -510,8 +513,10 @@ static int tas2770_codec_probe(struct snd_soc_component *component) · 394 unmodified lines | ||
| 510 | 513 | |
| 511 | 514 | tas2770->component = component; |
| 512 | 515 | |
| 513 | − if (tas2770->sdz_gpio) | |
| 516 | + if (tas2770->sdz_gpio) { | |
| 514 | 517 | gpiod_set_value_cansleep(tas2770->sdz_gpio, 1); |
| 518 | + usleep_range(1000, 2000); | |
| 519 | + } | |
| 515 | 520 | |
| 516 | 521 | tas2770_reset(tas2770); |
| 517 | 522 | |
| @@ -1441,7 +1441,8 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) · 1440 unmodified lines | ||
| 1441 | 1441 | int ret, i; |
| 1442 | 1442 | |
| 1443 | 1443 | for (i = 0; i < 5; ++i) { |
| 1444 | − ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, &coeff_v1, sizeof(coeff_v1)); | |
| 1444 | + ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, &coeff_v1, | |
| 1445 | + min(cs_ctl->len, sizeof(coeff_v1))); | |
| 1445 | 1446 | if (ret < 0) |
| 1446 | 1447 | return ret; |
| 1447 | 1448 | |
| @@ -952,6 +952,7 @@ static int skl_first_init(struct hdac_bus *bus) · 951 unmodified lines | ||
| 952 | 952 | /* allow 64bit DMA address if supported by H/W */ |
| 953 | 953 | if (dma_set_mask_and_coherent(bus->dev, DMA_BIT_MASK(64))) |
| 954 | 954 | dma_set_mask_and_coherent(bus->dev, DMA_BIT_MASK(32)); |
| 955 | + dma_set_max_seg_size(bus->dev, UINT_MAX); | |
| 955 | 956 | |
| 956 | 957 | /* initialize streams */ |
| 957 | 958 | snd_hdac_ext_stream_init_all |
| @@ -524,7 +524,7 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component, · 523 unmodified lines | ||
| 524 | 524 | return -EINVAL; |
| 525 | 525 | } |
| 526 | 526 | |
| 527 | − ret = regmap_update_bits(map, reg_irqclr, val_irqclr, val_irqclr); | |
| 527 | + ret = regmap_write_bits(map, reg_irqclr, val_irqclr, val_irqclr); | |
| 528 | 528 | if (ret) { |
| 529 | 529 | dev_err(soc_runtime->dev, "error writing to irqclear reg: %d\n", ret); |
| 530 | 530 | return ret; |
| @@ -665,7 +665,7 @@ static irqreturn_t lpass_dma_interrupt_handler( · 134 unmodified lines | ||
| 665 | 665 | return -EINVAL; |
| 666 | 666 | } |
| 667 | 667 | if (interrupts & LPAIF_IRQ_PER(chan)) { |
| 668 | − rv = regmap_update_bits(map, reg, mask, (LPAIF_IRQ_PER(chan) | val)); | |
| 668 | + rv = regmap_write_bits(map, reg, mask, (LPAIF_IRQ_PER(chan) | val)); | |
| 669 | 669 | if (rv) { |
| 670 | 670 | dev_err(soc_runtime->dev, |
| 671 | 671 | "error writing to irqclear reg: %d\n", rv); |
| @@ -676,7 +676,7 @@ static irqreturn_t lpass_dma_interrupt_handler( · 4 unmodified lines | ||
| 676 | 676 | } |
| 677 | 677 | |
| 678 | 678 | if (interrupts & LPAIF_IRQ_XRUN(chan)) { |
| 679 | − rv = regmap_update_bits(map, reg, mask, (LPAIF_IRQ_XRUN(chan) | val)); | |
| 679 | + rv = regmap_write_bits(map, reg, mask, (LPAIF_IRQ_XRUN(chan) | val)); | |
| 680 | 680 | if (rv) { |
| 681 | 681 | dev_err(soc_runtime->dev, |
| 682 | 682 | "error writing to irqclear reg: %d\n", rv); |
| @@ -688,7 +688,7 @@ static irqreturn_t lpass_dma_interrupt_handler( · 5 unmodified lines | ||
| 688 | 688 | } |
| 689 | 689 | |
| 690 | 690 | if (interrupts & LPAIF_IRQ_ERR(chan)) { |
| 691 | − rv = regmap_update_bits(map, reg, mask, (LPAIF_IRQ_ERR(chan) | val)); | |
| 691 | + rv = regmap_write_bits(map, reg, mask, (LPAIF_IRQ_ERR(chan) | val)); | |
| 692 | 692 | if (rv) { |
| 693 | 693 | dev_err(soc_runtime->dev, |
| 694 | 694 | "error writing to irqclear reg: %d\n", rv); |
| @@ -308,7 +308,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, · 307 unmodified lines | ||
| 308 | 308 | unsigned int sign_bit = mc->sign_bit; |
| 309 | 309 | unsigned int mask = (1 << fls(max)) - 1; |
| 310 | 310 | unsigned int invert = mc->invert; |
| 311 | − int err; | |
| 311 | + int err, ret; | |
| 312 | 312 | bool type_2r = false; |
| 313 | 313 | unsigned int val2 = 0; |
| 314 | 314 | unsigned int val, val_mask; |
| @@ -350,12 +350,18 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, · 35 unmodified lines | ||
| 350 | 350 | err = snd_soc_component_update_bits(component, reg, val_mask, val); |
| 351 | 351 | if (err < 0) |
| 352 | 352 | return err; |
| 353 | + ret = err; | |
| 353 | 354 | |
| 354 | − if (type_2r) | |
| 355 | + if (type_2r) { | |
| 355 | 356 | err = snd_soc_component_update_bits(component, reg2, val_mask, |
| 356 | − val2); | |
| 357 | + val2); | |
| 358 | + /* Don't discard any error code or drop change flag */ | |
| 359 | + if (ret == 0 || err < 0) { | |
| 360 | + ret = err; | |
| 361 | + } | |
| 362 | + } | |
| 357 | 363 | |
| 358 | − return err; | |
| 364 | + return ret; | |
| 359 | 365 | } |
| 360 | 366 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw); |
| 361 | 367 | |
| @@ -421,6 +427,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, · 59 unmodified lines | ||
| 421 | 427 | int min = mc->min; |
| 422 | 428 | unsigned int mask = (1U << (fls(min + max) - 1)) - 1; |
| 423 | 429 | int err = 0; |
| 430 | + int ret; | |
| 424 | 431 | unsigned int val, val_mask; |
| 425 | 432 | |
| 426 | 433 | if (ucontrol->value.integer.value[0] < 0) |
| @@ -437,6 +444,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, · 10 unmodified lines | ||
| 437 | 444 | err = snd_soc_component_update_bits(component, reg, val_mask, val); |
| 438 | 445 | if (err < 0) |
| 439 | 446 | return err; |
| 447 | + ret = err; | |
| 440 | 448 | |
| 441 | 449 | if (snd_soc_volsw_is_stereo(mc)) { |
| 442 | 450 | unsigned int val2; |
| @@ -447,6 +455,11 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, · 4 unmodified lines | ||
| 447 | 455 | |
| 448 | 456 | err = snd_soc_component_update_bits(component, reg2, val_mask, |
| 449 | 457 | val2); |
| 458 | + | |
| 459 | + /* Don't discard any error code or drop change flag */ | |
| 460 | + if (ret == 0 || err < 0) { | |
| 461 | + ret = err; | |
| 462 | + } | |
| 450 | 463 | } |
| 451 | 464 | return err; |
| 452 | 465 | } |
| @@ -506,7 +519,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, · 53 unmodified lines | ||
| 506 | 519 | unsigned int mask = (1 << fls(max)) - 1; |
| 507 | 520 | unsigned int invert = mc->invert; |
| 508 | 521 | unsigned int val, val_mask; |
| 509 | − int ret; | |
| 522 | + int err, ret; | |
| 510 | 523 | |
| 511 | 524 | if (invert) |
| 512 | 525 | val = (max - ucontrol->value.integer.value[0]) & mask; |
| @@ -515,9 +528,10 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, · 2 unmodified lines | ||
| 515 | 528 | val_mask = mask << shift; |
| 516 | 529 | val = val << shift; |
| 517 | 530 | |
| 518 | − ret = snd_soc_component_update_bits(component, reg, val_mask, val); | |
| 519 | − if (ret < 0) | |
| 520 | − return ret; | |
| 531 | + err = snd_soc_component_update_bits(component, reg, val_mask, val); | |
| 532 | + if (err < 0) | |
| 533 | + return err; | |
| 534 | + ret = err; | |
| 521 | 535 | |
| 522 | 536 | if (snd_soc_volsw_is_stereo(mc)) { |
| 523 | 537 | if (invert) |
| @@ -527,8 +541,12 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, · 3 unmodified lines | ||
| 527 | 541 | val_mask = mask << shift; |
| 528 | 542 | val = val << shift; |
| 529 | 543 | |
| 530 | − ret = snd_soc_component_update_bits(component, rreg, val_mask, | |
| 544 | + err = snd_soc_component_update_bits(component, rreg, val_mask, | |
| 531 | 545 | val); |
| 546 | + /* Don't discard any error code or drop change flag */ | |
| 547 | + if (ret == 0 || err < 0) { | |
| 548 | + ret = err; | |
| 549 | + } | |
| 532 | 550 | } |
| 533 | 551 | |
| 534 | 552 | return ret; |
| @@ -877,6 +895,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, · 342 unmodified lines | ||
| 877 | 895 | unsigned long mask = (1UL<<mc->nbits)-1; |
| 878 | 896 | long max = mc->max; |
| 879 | 897 | long val = ucontrol->value.integer.value[0]; |
| 898 | + int ret = 0; | |
| 880 | 899 | unsigned int i; |
| 881 | 900 | |
| 882 | 901 | if (val < mc->min || val > mc->max) |
| @@ -891,9 +910,11 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, · 8 unmodified lines | ||
| 891 | 910 | regmask, regval); |
| 892 | 911 | if (err < 0) |
| 893 | 912 | return err; |
| 913 | + if (err > 0) | |
| 914 | + ret = err; | |
| 894 | 915 | } |
| 895 | 916 | |
| 896 | − return 0; | |
| 917 | + return ret; | |
| 897 | 918 | } |
| 898 | 919 | EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx); |
| 899 | 920 | |
| @@ -956,6 +956,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) · 955 unmodified lines | ||
| 956 | 956 | dev_dbg(sdev->dev, "DMA mask is 32 bit\n"); |
| 957 | 957 | dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)); |
| 958 | 958 | } |
| 959 | + dma_set_max_seg_size(&pci->dev, UINT_MAX); | |
| 959 | 960 | |
| 960 | 961 | /* init streams */ |
| 961 | 962 | ret = hda_dsp_stream_init(sdev); |
| @@ -47,13 +47,13 @@ struct snd_usb_implicit_fb_match { · 46 unmodified lines | ||
| 47 | 47 | static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = { |
| 48 | 48 | /* Generic matching */ |
| 49 | 49 | IMPLICIT_FB_GENERIC_DEV(0x0499, 0x1509), /* Steinberg UR22 */ |
| 50 | − IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2080), /* M-Audio FastTrack Ultra */ | |
| 51 | − IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2081), /* M-Audio FastTrack Ultra */ | |
| 52 | 50 | IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2030), /* M-Audio Fast Track C400 */ |
| 53 | 51 | IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2031), /* M-Audio Fast Track C600 */ |
| 54 | 52 | |
| 55 | 53 | /* Fixed EP */ |
| 56 | 54 | /* FIXME: check the availability of generic matching */ |
| 55 | + IMPLICIT_FB_FIXED_DEV(0x0763, 0x2080, 0x81, 2), /* M-Audio FastTrack Ultra */ | |
| 56 | + IMPLICIT_FB_FIXED_DEV(0x0763, 0x2081, 0x81, 2), /* M-Audio FastTrack Ultra */ | |
| 57 | 57 | IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */ |
| 58 | 58 | IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0001, 0x81, 2), /* Solid State Logic SSL2 */ |
| 59 | 59 | IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0002, 0x81, 2), /* Solid State Logic SSL2+ */ |
| @@ -3678,17 +3678,14 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list) · 3677 unmodified lines | ||
| 3678 | 3678 | err = snd_usb_set_cur_mix_value(cval, c + 1, idx, |
| 3679 | 3679 | cval->cache_val[idx]); |
| 3680 | 3680 | if (err < 0) |
| 3681 | − return err; | |
| 3681 | + break; | |
| 3682 | 3682 | } |
| 3683 | 3683 | idx++; |
| 3684 | 3684 | } |
| 3685 | 3685 | } else { |
| 3686 | 3686 | /* master */ |
| 3687 | − if (cval->cached) { | |
| 3688 | − err = snd_usb_set_cur_mix_value(cval, 0, 0, *cval->cache_val); | |
| 3689 | − if (err < 0) | |
| 3690 | − return err; | |
| 3691 | − } | |
| 3687 | + if (cval->cached) | |
| 3688 | + snd_usb_set_cur_mix_value(cval, 0, 0, *cval->cache_val); | |
| 3692 | 3689 | } |
| 3693 | 3690 | |
| 3694 | 3691 | return 0; |
| @@ -11,7 +11,7 @@ from drgn.helpers.linux import list_for_each_entry, list_empty · 10 unmodified lines | ||
| 11 | 11 | from drgn.helpers.linux import for_each_page |
| 12 | 12 | from drgn.helpers.linux.cpumask import for_each_online_cpu |
| 13 | 13 | from drgn.helpers.linux.percpu import per_cpu_ptr |
| 14 | −from drgn import container_of, FaultError, Object | |
| 14 | +from drgn import container_of, FaultError, Object, cast | |
| 15 | 15 | |
| 16 | 16 | |
| 17 | 17 | DESC = """ |
| @@ -69,15 +69,15 @@ def oo_objects(s): · 51 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | |
| 71 | 71 | def count_partial(n, fn): |
| 72 | − nr_pages = 0 | |
| 73 | − for page in list_for_each_entry('struct page', n.partial.address_of_(), | |
| 74 | − 'lru'): | |
| 75 | − nr_pages += fn(page) | |
| 76 | − return nr_pages | |
| 72 | + nr_objs = 0 | |
| 73 | + for slab in list_for_each_entry('struct slab', n.partial.address_of_(), | |
| 74 | + 'slab_list'): | |
| 75 | + nr_objs += fn(slab) | |
| 76 | + return nr_objs | |
| 77 | 77 | |
| 78 | 78 | |
| 79 | −def count_free(page): | |
| 80 | − return page.objects - page.inuse | |
| 79 | +def count_free(slab): | |
| 80 | + return slab.objects - slab.inuse | |
| 81 | 81 | |
| 82 | 82 | |
| 83 | 83 | def slub_get_slabinfo(s, cfg): |
| @@ -145,14 +145,14 @@ def detect_kernel_config(): · 61 unmodified lines | ||
| 145 | 145 | return cfg |
| 146 | 146 | |
| 147 | 147 | |
| 148 | −def for_each_slab_page(prog): | |
| 148 | +def for_each_slab(prog): | |
| 149 | 149 | PGSlab = 1 << prog.constant('PG_slab') |
| 150 | 150 | PGHead = 1 << prog.constant('PG_head') |
| 151 | 151 | |
| 152 | 152 | for page in for_each_page(prog): |
| 153 | 153 | try: |
| 154 | 154 | if page.flags.value_() & PGSlab: |
| 155 | − yield page | |
| 155 | + yield cast('struct slab *', page) | |
| 156 | 156 | except FaultError: |
| 157 | 157 | pass |
| 158 | 158 | |
| @@ -190,13 +190,13 @@ def main(): · 31 unmodified lines | ||
| 190 | 190 | 'list'): |
| 191 | 191 | obj_cgroups.add(ptr.value_()) |
| 192 | 192 | |
| 193 | − # look over all slab pages, belonging to non-root memcgs | |
| 194 | − # and look for objects belonging to the given memory cgroup | |
| 195 | − for page in for_each_slab_page(prog): | |
| 196 | − objcg_vec_raw = page.memcg_data.value_() | |
| 193 | + # look over all slab folios and look for objects belonging | |
| 194 | + # to the given memory cgroup | |
| 195 | + for slab in for_each_slab(prog): | |
| 196 | + objcg_vec_raw = slab.memcg_data.value_() | |
| 197 | 197 | if objcg_vec_raw == 0: |
| 198 | 198 | continue |
| 199 | − cache = page.slab_cache | |
| 199 | + cache = slab.slab_cache | |
| 200 | 200 | if not cache: |
| 201 | 201 | continue |
| 202 | 202 | addr = cache.value_() |
| @@ -3,8 +3,8 @@ CFLAGS = -Wall · 2 unmodified lines | ||
| 3 | 3 | CFLAGS += -Wno-nonnull |
| 4 | 4 | CFLAGS += -D_GNU_SOURCE |
| 5 | 5 | |
| 6 | −TEST_PROGS := binfmt_script non-regular | |
| 7 | −TEST_GEN_PROGS := execveat load_address_4096 load_address_2097152 load_address_16777216 | |
| 6 | +TEST_PROGS := binfmt_script | |
| 7 | +TEST_GEN_PROGS := execveat load_address_4096 load_address_2097152 load_address_16777216 non-regular | |
| 8 | 8 | TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir |
| 9 | 9 | # Makefile is a run-time dependency, since it's accessed by the execveat test |
| 10 | 10 | TEST_FILES := Makefile |
| @@ -19,7 +19,7 @@ fail() { # mesg · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | FILTER=set_ftrace_filter |
| 21 | 21 | FUNC1="schedule" |
| 22 | −FUNC2="do_softirq" | |
| 22 | +FUNC2="scheduler_tick" | |
| 23 | 23 | |
| 24 | 24 | ALL_FUNCS="#### all functions enabled ####" |
| 25 | 25 | |
| @@ -1236,7 +1236,7 @@ static int get_userns_fd(unsigned long nsid, unsigned long hostid, unsigned long · 1235 unmodified lines | ||
| 1236 | 1236 | } |
| 1237 | 1237 | |
| 1238 | 1238 | /** |
| 1239 | − * Validate that an attached mount in our mount namespace can be idmapped. | |
| 1239 | + * Validate that an attached mount in our mount namespace cannot be idmapped. | |
| 1240 | 1240 | * (The kernel enforces that the mount's mount namespace and the caller's mount |
| 1241 | 1241 | * namespace match.) |
| 1242 | 1242 | */ |
| @@ -1259,7 +1259,7 @@ TEST_F(mount_setattr_idmapped, attached_mount_inside_current_mount_namespace) · 16 unmodified lines | ||
| 1259 | 1259 | |
| 1260 | 1260 | attr.userns_fd = get_userns_fd(0, 10000, 10000); |
| 1261 | 1261 | ASSERT_GE(attr.userns_fd, 0); |
| 1262 | − ASSERT_EQ(sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr)), 0); | |
| 1262 | + ASSERT_NE(sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr)), 0); | |
| 1263 | 1263 | ASSERT_EQ(close(attr.userns_fd), 0); |
| 1264 | 1264 | ASSERT_EQ(close(open_tree_fd), 0); |
| 1265 | 1265 | } |
| @@ -71,6 +71,36 @@ chk_msk_remote_key_nr() · 70 unmodified lines | ||
| 71 | 71 | __chk_nr "grep -c remote_key" $* |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | +# $1: ns, $2: port | |
| 75 | +wait_local_port_listen() | |
| 76 | +{ | |
| 77 | + local listener_ns="${1}" | |
| 78 | + local port="${2}" | |
| 79 | + | |
| 80 | + local port_hex i | |
| 81 | + | |
| 82 | + port_hex="$(printf "%04X" "${port}")" | |
| 83 | + for i in $(seq 10); do | |
| 84 | + ip netns exec "${listener_ns}" cat /proc/net/tcp | \ | |
| 85 | + awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" && | |
| 86 | + break | |
| 87 | + sleep 0.1 | |
| 88 | + done | |
| 89 | +} | |
| 90 | + | |
| 91 | +wait_connected() | |
| 92 | +{ | |
| 93 | + local listener_ns="${1}" | |
| 94 | + local port="${2}" | |
| 95 | + | |
| 96 | + local port_hex i | |
| 97 | + | |
| 98 | + port_hex="$(printf "%04X" "${port}")" | |
| 99 | + for i in $(seq 10); do | |
| 100 | + ip netns exec ${listener_ns} grep -q " 0100007F:${port_hex} " /proc/net/tcp && break | |
| 101 | + sleep 0.1 | |
| 102 | + done | |
| 103 | +} | |
| 74 | 104 | |
| 75 | 105 | trap cleanup EXIT |
| 76 | 106 | ip netns add $ns |
| @@ -81,15 +111,15 @@ echo "a" | \ · 4 unmodified lines | ||
| 81 | 111 | ip netns exec $ns \ |
| 82 | 112 | ./mptcp_connect -p 10000 -l -t ${timeout_poll} \ |
| 83 | 113 | 0.0.0.0 >/dev/null & |
| 84 | −sleep 0.1 | |
| 114 | +wait_local_port_listen $ns 10000 | |
| 85 | 115 | chk_msk_nr 0 "no msk on netns creation" |
| 86 | 116 | |
| 87 | 117 | echo "b" | \ |
| 88 | 118 | timeout ${timeout_test} \ |
| 89 | 119 | ip netns exec $ns \ |
| 90 | − ./mptcp_connect -p 10000 -j -t ${timeout_poll} \ | |
| 120 | + ./mptcp_connect -p 10000 -r 0 -t ${timeout_poll} \ | |
| 91 | 121 | 127.0.0.1 >/dev/null & |
| 92 | −sleep 0.1 | |
| 122 | +wait_connected $ns 10000 | |
| 93 | 123 | chk_msk_nr 2 "after MPC handshake " |
| 94 | 124 | chk_msk_remote_key_nr 2 "....chk remote_key" |
| 95 | 125 | chk_msk_fallback_nr 0 "....chk no fallback" |
| @@ -101,13 +131,13 @@ echo "a" | \ · 5 unmodified lines | ||
| 101 | 131 | ip netns exec $ns \ |
| 102 | 132 | ./mptcp_connect -p 10001 -l -s TCP -t ${timeout_poll} \ |
| 103 | 133 | 0.0.0.0 >/dev/null & |
| 104 | −sleep 0.1 | |
| 134 | +wait_local_port_listen $ns 10001 | |
| 105 | 135 | echo "b" | \ |
| 106 | 136 | timeout ${timeout_test} \ |
| 107 | 137 | ip netns exec $ns \ |
| 108 | − ./mptcp_connect -p 10001 -j -t ${timeout_poll} \ | |
| 138 | + ./mptcp_connect -p 10001 -r 0 -t ${timeout_poll} \ | |
| 109 | 139 | 127.0.0.1 >/dev/null & |
| 110 | −sleep 0.1 | |
| 140 | +wait_connected $ns 10001 | |
| 111 | 141 | chk_msk_fallback_nr 1 "check fallback" |
| 112 | 142 | flush_pids |
| 113 | 143 | |
| @@ -119,7 +149,7 @@ for I in `seq 1 $NR_CLIENTS`; do · 5 unmodified lines | ||
| 119 | 149 | ./mptcp_connect -p $((I+10001)) -l -w 10 \ |
| 120 | 150 | -t ${timeout_poll} 0.0.0.0 >/dev/null & |
| 121 | 151 | done |
| 122 | −sleep 0.1 | |
| 152 | +wait_local_port_listen $ns $((NR_CLIENTS + 10001)) | |
| 123 | 153 | |
| 124 | 154 | for I in `seq 1 $NR_CLIENTS`; do |
| 125 | 155 | echo "b" | \ |
| @@ -799,6 +799,7 @@ chk_join_nr() · 798 unmodified lines | ||
| 799 | 799 | local ack_nr=$4 |
| 800 | 800 | local count |
| 801 | 801 | local dump_stats |
| 802 | + local with_cookie | |
| 802 | 803 | |
| 803 | 804 | printf "%02u %-36s %s" "$TEST_COUNT" "$msg" "syn" |
| 804 | 805 | count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinSynRx | awk '{print $2}'` |
| @@ -812,12 +813,20 @@ chk_join_nr() · 7 unmodified lines | ||
| 812 | 813 | fi |
| 813 | 814 | |
| 814 | 815 | echo -n " - synack" |
| 816 | + with_cookie=`ip netns exec $ns2 sysctl -n net.ipv4.tcp_syncookies` | |
| 815 | 817 | count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinSynAckRx | awk '{print $2}'` |
| 816 | 818 | [ -z "$count" ] && count=0 |
| 817 | 819 | if [ "$count" != "$syn_ack_nr" ]; then |
| 818 | − echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr" | |
| 819 | − ret=1 | |
| 820 | − dump_stats=1 | |
| 820 | + # simult connections exceeding the limit with cookie enabled could go up to | |
| 821 | + # synack validation as the conn limit can be enforced reliably only after | |
| 822 | + # the subflow creation | |
| 823 | + if [ "$with_cookie" = 2 ] && [ "$count" -gt "$syn_ack_nr" ] && [ "$count" -le "$syn_nr" ]; then | |
| 824 | + echo -n "[ ok ]" | |
| 825 | + else | |
| 826 | + echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr" | |
| 827 | + ret=1 | |
| 828 | + dump_stats=1 | |
| 829 | + fi | |
| 821 | 830 | else |
| 822 | 831 | echo -n "[ ok ]" |
| 823 | 832 | fi |
| @@ -891,11 +900,17 @@ chk_add_nr() · 67 unmodified lines | ||
| 891 | 900 | local mis_ack_nr=${8:-0} |
| 892 | 901 | local count |
| 893 | 902 | local dump_stats |
| 903 | + local timeout | |
| 904 | + | |
| 905 | + timeout=`ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout` | |
| 894 | 906 | |
| 895 | 907 | printf "%-39s %s" " " "add" |
| 896 | − count=`ip netns exec $ns2 nstat -as | grep MPTcpExtAddAddr | awk '{print $2}'` | |
| 908 | + count=`ip netns exec $ns2 nstat -as MPTcpExtAddAddr | grep MPTcpExtAddAddr | awk '{print $2}'` | |
| 897 | 909 | [ -z "$count" ] && count=0 |
| 898 | − if [ "$count" != "$add_nr" ]; then | |
| 910 | + | |
| 911 | + # if the test configured a short timeout tolerate greater then expected | |
| 912 | + # add addrs options, due to retransmissions | |
| 913 | + if [ "$count" != "$add_nr" ] && [ "$timeout" -gt 1 -o "$count" -lt "$add_nr" ]; then | |
| 899 | 914 | echo "[fail] got $count ADD_ADDR[s] expected $add_nr" |
| 900 | 915 | ret=1 |
| 901 | 916 | dump_stats=1 |
| @@ -1100,7 +1115,7 @@ wait_for_tw() · 198 unmodified lines | ||
| 1100 | 1115 | local ns=$1 |
| 1101 | 1116 | |
| 1102 | 1117 | while [ $time -lt $timeout_ms ]; do |
| 1103 | − local cnt=$(ip netns exec $ns ss -t state time-wait |wc -l) | |
| 1118 | + local cnt=$(ip netns exec $ns nstat -as TcpAttemptFails | grep TcpAttemptFails | awk '{print $2}') | |
| 1104 | 1119 | |
| 1105 | 1120 | [ "$cnt" = 1 ] && return 1 |
| 1106 | 1121 | time=$((time + 100)) |
| @@ -1297,7 +1312,10 @@ signal_address_tests() · 190 unmodified lines | ||
| 1297 | 1312 | pm_nl_add_endpoint $ns2 10.0.2.2 flags signal |
| 1298 | 1313 | pm_nl_add_endpoint $ns2 10.0.3.2 flags signal |
| 1299 | 1314 | pm_nl_add_endpoint $ns2 10.0.4.2 flags signal |
| 1300 | − run_tests $ns1 $ns2 10.0.1.1 | |
| 1315 | + | |
| 1316 | + # the peer could possibly miss some addr notification, allow retransmission | |
| 1317 | + ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1 | |
| 1318 | + run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow | |
| 1301 | 1319 | chk_join_nr "signal addresses race test" 3 3 3 |
| 1302 | 1320 | |
| 1303 | 1321 | # the server will not signal the address terminating |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | −CFLAGS += -Wl,-no-as-needed -Wall | |
| 2 | +CFLAGS += -Wl,-no-as-needed -Wall -isystem ../../../../usr/include/ | |
| 3 | 3 | LDFLAGS += -lpthread |
| 4 | 4 | |
| 5 | 5 | TEST_GEN_PROGS := seccomp_bpf seccomp_benchmark |