summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pagano <mpagano@gentoo.org>2019-11-10 11:20:21 -0500
committerMike Pagano <mpagano@gentoo.org>2019-11-10 11:20:21 -0500
commitb8aafdcd425c5d7d9ae6dfddacd215b4c1084bbe (patch)
tree0e46d25ec05423909b3cb1ccca384e4405499537
parentLinux patch 4.19.82 (diff)
downloadlinux-patches-b8aafdcd425c5d7d9ae6dfddacd215b4c1084bbe.tar.gz
linux-patches-b8aafdcd425c5d7d9ae6dfddacd215b4c1084bbe.tar.bz2
linux-patches-b8aafdcd425c5d7d9ae6dfddacd215b4c1084bbe.zip
Linux patch 4.19.834.19-82
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r--0000_README4
-rw-r--r--1082_linux-4.19.83.patch4183
2 files changed, 4187 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index 3a289a88..4a7a9266 100644
--- a/0000_README
+++ b/0000_README
@@ -367,6 +367,10 @@ Patch: 1081_linux-4.19.82.patch
From: https://www.kernel.org
Desc: Linux 4.19.82
+Patch: 1082_linux-4.19.83.patch
+From: https://www.kernel.org
+Desc: Linux 4.19.83
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1082_linux-4.19.83.patch b/1082_linux-4.19.83.patch
new file mode 100644
index 00000000..9df0797d
--- /dev/null
+++ b/1082_linux-4.19.83.patch
@@ -0,0 +1,4183 @@
+diff --git a/Makefile b/Makefile
+index 6af1c13d8753..c2c0cf2b1bd7 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 19
+-SUBLEVEL = 82
++SUBLEVEL = 83
+ EXTRAVERSION =
+ NAME = "People's Front"
+
+@@ -835,6 +835,12 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
+ # change __FILE__ to the relative path from the srctree
+ KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=)
+
++# ensure -fcf-protection is disabled when using retpoline as it is
++# incompatible with -mindirect-branch=thunk-extern
++ifdef CONFIG_RETPOLINE
++KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
++endif
++
+ # use the deterministic mode of AR if available
+ KBUILD_ARFLAGS := $(call ar-option,D)
+
+diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
+index a7f697b0290f..90f5bdfa9b3c 100644
+--- a/arch/arm/boot/dts/imx7s.dtsi
++++ b/arch/arm/boot/dts/imx7s.dtsi
+@@ -443,7 +443,7 @@
+ compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt";
+ reg = <0x302d0000 0x10000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clks IMX7D_CLK_DUMMY>,
++ clocks = <&clks IMX7D_GPT1_ROOT_CLK>,
+ <&clks IMX7D_GPT1_ROOT_CLK>;
+ clock-names = "ipg", "per";
+ };
+@@ -452,7 +452,7 @@
+ compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt";
+ reg = <0x302e0000 0x10000>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clks IMX7D_CLK_DUMMY>,
++ clocks = <&clks IMX7D_GPT2_ROOT_CLK>,
+ <&clks IMX7D_GPT2_ROOT_CLK>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+@@ -462,7 +462,7 @@
+ compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt";
+ reg = <0x302f0000 0x10000>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clks IMX7D_CLK_DUMMY>,
++ clocks = <&clks IMX7D_GPT3_ROOT_CLK>,
+ <&clks IMX7D_GPT3_ROOT_CLK>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+@@ -472,7 +472,7 @@
+ compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt";
+ reg = <0x30300000 0x10000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clks IMX7D_CLK_DUMMY>,
++ clocks = <&clks IMX7D_GPT4_ROOT_CLK>,
+ <&clks IMX7D_GPT4_ROOT_CLK>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
+index 7d2302e8706c..9354da4efe09 100644
+--- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
++++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
+@@ -196,3 +196,7 @@
+ &twl_gpio {
+ ti,use-leds;
+ };
++
++&twl_keypad {
++ status = "disabled";
++};
+diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
+index 42665914166a..83ca89a35300 100644
+--- a/arch/arm/mach-davinci/dm365.c
++++ b/arch/arm/mach-davinci/dm365.c
+@@ -458,8 +458,8 @@ static s8 dm365_queue_priority_mapping[][2] = {
+ };
+
+ static const struct dma_slave_map dm365_edma_map[] = {
+- { "davinci-mcbsp.0", "tx", EDMA_FILTER_PARAM(0, 2) },
+- { "davinci-mcbsp.0", "rx", EDMA_FILTER_PARAM(0, 3) },
++ { "davinci-mcbsp", "tx", EDMA_FILTER_PARAM(0, 2) },
++ { "davinci-mcbsp", "rx", EDMA_FILTER_PARAM(0, 3) },
+ { "davinci_voicecodec", "tx", EDMA_FILTER_PARAM(0, 2) },
+ { "davinci_voicecodec", "rx", EDMA_FILTER_PARAM(0, 3) },
+ { "spi_davinci.2", "tx", EDMA_FILTER_PARAM(0, 10) },
+diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
+index bd2c739d8083..84a6bbaf8cb2 100644
+--- a/arch/arm/mm/alignment.c
++++ b/arch/arm/mm/alignment.c
+@@ -768,6 +768,36 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
+ return NULL;
+ }
+
++static int alignment_get_arm(struct pt_regs *regs, u32 *ip, unsigned long *inst)
++{
++ u32 instr = 0;
++ int fault;
++
++ if (user_mode(regs))
++ fault = get_user(instr, ip);
++ else
++ fault = probe_kernel_address(ip, instr);
++
++ *inst = __mem_to_opcode_arm(instr);
++
++ return fault;
++}
++
++static int alignment_get_thumb(struct pt_regs *regs, u16 *ip, u16 *inst)
++{
++ u16 instr = 0;
++ int fault;
++
++ if (user_mode(regs))
++ fault = get_user(instr, ip);
++ else
++ fault = probe_kernel_address(ip, instr);
++
++ *inst = __mem_to_opcode_thumb16(instr);
++
++ return fault;
++}
++
+ static int
+ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ {
+@@ -775,10 +805,10 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ unsigned long instr = 0, instrptr;
+ int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
+ unsigned int type;
+- unsigned int fault;
+ u16 tinstr = 0;
+ int isize = 4;
+ int thumb2_32b = 0;
++ int fault;
+
+ if (interrupts_enabled(regs))
+ local_irq_enable();
+@@ -787,15 +817,14 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+
+ if (thumb_mode(regs)) {
+ u16 *ptr = (u16 *)(instrptr & ~1);
+- fault = probe_kernel_address(ptr, tinstr);
+- tinstr = __mem_to_opcode_thumb16(tinstr);
++
++ fault = alignment_get_thumb(regs, ptr, &tinstr);
+ if (!fault) {
+ if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
+ IS_T32(tinstr)) {
+ /* Thumb-2 32-bit */
+- u16 tinst2 = 0;
+- fault = probe_kernel_address(ptr + 1, tinst2);
+- tinst2 = __mem_to_opcode_thumb16(tinst2);
++ u16 tinst2;
++ fault = alignment_get_thumb(regs, ptr + 1, &tinst2);
+ instr = __opcode_thumb32_compose(tinstr, tinst2);
+ thumb2_32b = 1;
+ } else {
+@@ -804,8 +833,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ }
+ }
+ } else {
+- fault = probe_kernel_address((void *)instrptr, instr);
+- instr = __mem_to_opcode_arm(instr);
++ fault = alignment_get_arm(regs, (void *)instrptr, &instr);
+ }
+
+ if (fault) {
+diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S
+index 59d82864c134..9c2978c128d9 100644
+--- a/arch/arm/mm/proc-v7m.S
++++ b/arch/arm/mm/proc-v7m.S
+@@ -135,7 +135,6 @@ __v7m_setup_cont:
+ dsb
+ mov r6, lr @ save LR
+ ldr sp, =init_thread_union + THREAD_START_SP
+- stmia sp, {r0-r3, r12}
+ cpsie i
+ svc #0
+ 1: cpsid i
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
+index 24f1aac366d6..d5b6e8159a33 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
+@@ -63,3 +63,12 @@
+ reg = <1>;
+ };
+ };
++
++&reg_dc1sw {
++ /*
++ * Ethernet PHY needs 30ms to properly power up and some more
++ * to initialize. 100ms should be plenty of time to finish
++ * whole process.
++ */
++ regulator-enable-ramp-delay = <100000>;
++};
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+index c21f2331add6..285cb7143b96 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+@@ -113,6 +113,12 @@
+ };
+
+ &reg_dc1sw {
++ /*
++ * Ethernet PHY needs 30ms to properly power up and some more
++ * to initialize. 100ms should be plenty of time to finish
++ * whole process.
++ */
++ regulator-enable-ramp-delay = <100000>;
+ regulator-name = "vcc-phy";
+ };
+
+diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray-pinctrl.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray-pinctrl.dtsi
+index 8a3a770e8f2c..56789ccf9454 100644
+--- a/arch/arm64/boot/dts/broadcom/stingray/stingray-pinctrl.dtsi
++++ b/arch/arm64/boot/dts/broadcom/stingray/stingray-pinctrl.dtsi
+@@ -42,13 +42,14 @@
+
+ pinmux: pinmux@14029c {
+ compatible = "pinctrl-single";
+- reg = <0x0014029c 0x250>;
++ reg = <0x0014029c 0x26c>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xf>;
+ pinctrl-single,gpio-range = <
+- &range 0 154 MODE_GPIO
++ &range 0 91 MODE_GPIO
++ &range 95 60 MODE_GPIO
+ >;
+ range: gpio-range {
+ #pinctrl-single,gpio-range-cells = <3>;
+diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
+index e283480bfc7e..84101ea1fd2c 100644
+--- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
++++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
+@@ -463,8 +463,7 @@
+ <&pinmux 108 16 27>,
+ <&pinmux 135 77 6>,
+ <&pinmux 141 67 4>,
+- <&pinmux 145 149 6>,
+- <&pinmux 151 91 4>;
++ <&pinmux 145 149 6>;
+ };
+
+ i2c1: i2c@e0000 {
+diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+index 2409344df4fa..e23c5762355d 100644
+--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+@@ -21,7 +21,7 @@
+ */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+- gic_its: gic-its@18200000 {
++ gic_its: gic-its@1820000 {
+ compatible = "arm,gic-v3-its";
+ reg = <0x01820000 0x10000>;
+ msi-controller;
+diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
+index 7019e2967009..bbbf8057565b 100644
+--- a/arch/mips/bcm63xx/prom.c
++++ b/arch/mips/bcm63xx/prom.c
+@@ -84,7 +84,7 @@ void __init prom_init(void)
+ * Here we will start up CPU1 in the background and ask it to
+ * reconfigure itself then go back to sleep.
+ */
+- memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
++ memcpy((void *)0xa0000200, bmips_smp_movevec, 0x20);
+ __sync();
+ set_c0_cause(C_SW0);
+ cpumask_set_cpu(1, &bmips_booted_mask);
+diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h
+index bf6a8afd7ad2..581a6a3c66e4 100644
+--- a/arch/mips/include/asm/bmips.h
++++ b/arch/mips/include/asm/bmips.h
+@@ -75,11 +75,11 @@ static inline int register_bmips_smp_ops(void)
+ #endif
+ }
+
+-extern char bmips_reset_nmi_vec;
+-extern char bmips_reset_nmi_vec_end;
+-extern char bmips_smp_movevec;
+-extern char bmips_smp_int_vec;
+-extern char bmips_smp_int_vec_end;
++extern char bmips_reset_nmi_vec[];
++extern char bmips_reset_nmi_vec_end[];
++extern char bmips_smp_movevec[];
++extern char bmips_smp_int_vec[];
++extern char bmips_smp_int_vec_end[];
+
+ extern int bmips_smp_enabled;
+ extern int bmips_cpu_offset;
+diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
+index 159e83add4bb..5ec546b5eed1 100644
+--- a/arch/mips/kernel/smp-bmips.c
++++ b/arch/mips/kernel/smp-bmips.c
+@@ -457,10 +457,10 @@ static void bmips_wr_vec(unsigned long dst, char *start, char *end)
+
+ static inline void bmips_nmi_handler_setup(void)
+ {
+- bmips_wr_vec(BMIPS_NMI_RESET_VEC, &bmips_reset_nmi_vec,
+- &bmips_reset_nmi_vec_end);
+- bmips_wr_vec(BMIPS_WARM_RESTART_VEC, &bmips_smp_int_vec,
+- &bmips_smp_int_vec_end);
++ bmips_wr_vec(BMIPS_NMI_RESET_VEC, bmips_reset_nmi_vec,
++ bmips_reset_nmi_vec_end);
++ bmips_wr_vec(BMIPS_WARM_RESTART_VEC, bmips_smp_int_vec,
++ bmips_smp_int_vec_end);
+ }
+
+ struct reset_vec_info {
+diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
+index 6a6804c2e1b0..3ce690e5f345 100644
+--- a/arch/powerpc/include/asm/cputable.h
++++ b/arch/powerpc/include/asm/cputable.h
+@@ -214,6 +214,7 @@ static inline void cpu_feature_keys_init(void) { }
+ #define CPU_FTR_P9_TM_XER_SO_BUG LONG_ASM_CONST(0x0000200000000000)
+ #define CPU_FTR_P9_TLBIE_STQ_BUG LONG_ASM_CONST(0x0000400000000000)
+ #define CPU_FTR_P9_TIDR LONG_ASM_CONST(0x0000800000000000)
++#define CPU_FTR_P9_TLBIE_ERAT_BUG LONG_ASM_CONST(0x0001000000000000)
+
+ #ifndef __ASSEMBLY__
+
+@@ -460,7 +461,7 @@ static inline void cpu_feature_keys_init(void) { }
+ CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
+ CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
+ CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_PKEY | \
+- CPU_FTR_P9_TLBIE_STQ_BUG | CPU_FTR_P9_TIDR)
++ CPU_FTR_P9_TLBIE_STQ_BUG | CPU_FTR_P9_TLBIE_ERAT_BUG | CPU_FTR_P9_TIDR)
+ #define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9
+ #define CPU_FTRS_POWER9_DD2_1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1)
+ #define CPU_FTRS_POWER9_DD2_2 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1 | \
+diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
+index f3b8e04eca9c..c6f41907f0d7 100644
+--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
++++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
+@@ -717,6 +717,8 @@ static __init void update_tlbie_feature_flag(unsigned long pvr)
+ WARN_ONCE(1, "Unknown PVR");
+ cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG;
+ }
++
++ cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_ERAT_BUG;
+ }
+ }
+
+diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+index 7c68d834c94a..02ab86be9ded 100644
+--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
++++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+@@ -434,6 +434,37 @@ static inline int is_mmio_hpte(unsigned long v, unsigned long r)
+ (HPTE_R_KEY_HI | HPTE_R_KEY_LO));
+ }
+
++static inline void fixup_tlbie_lpid(unsigned long rb_value, unsigned long lpid)
++{
++
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
++ /* Radix flush for a hash guest */
++
++ unsigned long rb,rs,prs,r,ric;
++
++ rb = PPC_BIT(52); /* IS = 2 */
++ rs = 0; /* lpid = 0 */
++ prs = 0; /* partition scoped */
++ r = 1; /* radix format */
++ ric = 0; /* RIC_FLSUH_TLB */
++
++ /*
++ * Need the extra ptesync to make sure we don't
++ * re-order the tlbie
++ */
++ asm volatile("ptesync": : :"memory");
++ asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
++ : : "r"(rb), "i"(r), "i"(prs),
++ "i"(ric), "r"(rs) : "memory");
++ }
++
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
++ asm volatile("ptesync": : :"memory");
++ asm volatile(PPC_TLBIE_5(%0,%1,0,0,0) : :
++ "r" (rb_value), "r" (lpid));
++ }
++}
++
+ static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues,
+ long npages, int global, bool need_sync)
+ {
+@@ -452,16 +483,7 @@ static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues,
+ "r" (rbvalues[i]), "r" (kvm->arch.lpid));
+ }
+
+- if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
+- /*
+- * Need the extra ptesync to make sure we don't
+- * re-order the tlbie
+- */
+- asm volatile("ptesync": : :"memory");
+- asm volatile(PPC_TLBIE_5(%0,%1,0,0,0) : :
+- "r" (rbvalues[0]), "r" (kvm->arch.lpid));
+- }
+-
++ fixup_tlbie_lpid(rbvalues[i - 1], kvm->arch.lpid);
+ asm volatile("eieio; tlbsync; ptesync" : : : "memory");
+ } else {
+ if (need_sync)
+diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
+index 0c13561d8b80..42a48c5f7b7f 100644
+--- a/arch/powerpc/mm/hash_native_64.c
++++ b/arch/powerpc/mm/hash_native_64.c
+@@ -201,8 +201,31 @@ static inline unsigned long ___tlbie(unsigned long vpn, int psize,
+ return va;
+ }
+
+-static inline void fixup_tlbie(unsigned long vpn, int psize, int apsize, int ssize)
++static inline void fixup_tlbie_vpn(unsigned long vpn, int psize,
++ int apsize, int ssize)
+ {
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
++ /* Radix flush for a hash guest */
++
++ unsigned long rb,rs,prs,r,ric;
++
++ rb = PPC_BIT(52); /* IS = 2 */
++ rs = 0; /* lpid = 0 */
++ prs = 0; /* partition scoped */
++ r = 1; /* radix format */
++ ric = 0; /* RIC_FLSUH_TLB */
++
++ /*
++ * Need the extra ptesync to make sure we don't
++ * re-order the tlbie
++ */
++ asm volatile("ptesync": : :"memory");
++ asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
++ : : "r"(rb), "i"(r), "i"(prs),
++ "i"(ric), "r"(rs) : "memory");
++ }
++
++
+ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
+ /* Need the extra ptesync to ensure we don't reorder tlbie*/
+ asm volatile("ptesync": : :"memory");
+@@ -287,7 +310,7 @@ static inline void tlbie(unsigned long vpn, int psize, int apsize,
+ asm volatile("ptesync": : :"memory");
+ } else {
+ __tlbie(vpn, psize, apsize, ssize);
+- fixup_tlbie(vpn, psize, apsize, ssize);
++ fixup_tlbie_vpn(vpn, psize, apsize, ssize);
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
+ }
+ if (lock_tlbie && !use_local)
+@@ -860,7 +883,7 @@ static void native_flush_hash_range(unsigned long number, int local)
+ /*
+ * Just do one more with the last used values.
+ */
+- fixup_tlbie(vpn, psize, psize, ssize);
++ fixup_tlbie_vpn(vpn, psize, psize, ssize);
+ asm volatile("eieio; tlbsync; ptesync":::"memory");
+
+ if (lock_tlbie)
+diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
+index 0cddae4263f9..62be0e5732b7 100644
+--- a/arch/powerpc/mm/tlb-radix.c
++++ b/arch/powerpc/mm/tlb-radix.c
+@@ -215,21 +215,82 @@ static inline void __tlbie_lpid_va(unsigned long va, unsigned long lpid,
+ trace_tlbie(lpid, 0, rb, rs, ric, prs, r);
+ }
+
+-static inline void fixup_tlbie(void)
++
++static inline void fixup_tlbie_va(unsigned long va, unsigned long pid,
++ unsigned long ap)
+ {
+- unsigned long pid = 0;
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
++ asm volatile("ptesync": : :"memory");
++ __tlbie_va(va, 0, ap, RIC_FLUSH_TLB);
++ }
++
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
++ asm volatile("ptesync": : :"memory");
++ __tlbie_va(va, pid, ap, RIC_FLUSH_TLB);
++ }
++}
++
++static inline void fixup_tlbie_va_range(unsigned long va, unsigned long pid,
++ unsigned long ap)
++{
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
++ asm volatile("ptesync": : :"memory");
++ __tlbie_pid(0, RIC_FLUSH_TLB);
++ }
++
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
++ asm volatile("ptesync": : :"memory");
++ __tlbie_va(va, pid, ap, RIC_FLUSH_TLB);
++ }
++}
++
++static inline void fixup_tlbie_pid(unsigned long pid)
++{
++ /*
++ * We can use any address for the invalidation, pick one which is
++ * probably unused as an optimisation.
++ */
+ unsigned long va = ((1UL << 52) - 1);
+
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
++ asm volatile("ptesync": : :"memory");
++ __tlbie_pid(0, RIC_FLUSH_TLB);
++ }
++
+ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
+ asm volatile("ptesync": : :"memory");
+ __tlbie_va(va, pid, mmu_get_ap(MMU_PAGE_64K), RIC_FLUSH_TLB);
+ }
+ }
+
++
++static inline void fixup_tlbie_lpid_va(unsigned long va, unsigned long lpid,
++ unsigned long ap)
++{
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
++ asm volatile("ptesync": : :"memory");
++ __tlbie_lpid_va(va, 0, ap, RIC_FLUSH_TLB);
++ }
++
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
++ asm volatile("ptesync": : :"memory");
++ __tlbie_lpid_va(va, lpid, ap, RIC_FLUSH_TLB);
++ }
++}
++
+ static inline void fixup_tlbie_lpid(unsigned long lpid)
+ {
++ /*
++ * We can use any address for the invalidation, pick one which is
++ * probably unused as an optimisation.
++ */
+ unsigned long va = ((1UL << 52) - 1);
+
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
++ asm volatile("ptesync": : :"memory");
++ __tlbie_lpid(0, RIC_FLUSH_TLB);
++ }
++
+ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
+ asm volatile("ptesync": : :"memory");
+ __tlbie_lpid_va(va, lpid, mmu_get_ap(MMU_PAGE_64K), RIC_FLUSH_TLB);
+@@ -277,6 +338,7 @@ static inline void _tlbie_pid(unsigned long pid, unsigned long ric)
+ switch (ric) {
+ case RIC_FLUSH_TLB:
+ __tlbie_pid(pid, RIC_FLUSH_TLB);
++ fixup_tlbie_pid(pid);
+ break;
+ case RIC_FLUSH_PWC:
+ __tlbie_pid(pid, RIC_FLUSH_PWC);
+@@ -284,8 +346,8 @@ static inline void _tlbie_pid(unsigned long pid, unsigned long ric)
+ case RIC_FLUSH_ALL:
+ default:
+ __tlbie_pid(pid, RIC_FLUSH_ALL);
++ fixup_tlbie_pid(pid);
+ }
+- fixup_tlbie();
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
+ }
+
+@@ -329,6 +391,7 @@ static inline void _tlbie_lpid(unsigned long lpid, unsigned long ric)
+ switch (ric) {
+ case RIC_FLUSH_TLB:
+ __tlbie_lpid(lpid, RIC_FLUSH_TLB);
++ fixup_tlbie_lpid(lpid);
+ break;
+ case RIC_FLUSH_PWC:
+ __tlbie_lpid(lpid, RIC_FLUSH_PWC);
+@@ -336,8 +399,8 @@ static inline void _tlbie_lpid(unsigned long lpid, unsigned long ric)
+ case RIC_FLUSH_ALL:
+ default:
+ __tlbie_lpid(lpid, RIC_FLUSH_ALL);
++ fixup_tlbie_lpid(lpid);
+ }
+- fixup_tlbie_lpid(lpid);
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
+ }
+
+@@ -410,6 +473,8 @@ static inline void __tlbie_va_range(unsigned long start, unsigned long end,
+
+ for (addr = start; addr < end; addr += page_size)
+ __tlbie_va(addr, pid, ap, RIC_FLUSH_TLB);
++
++ fixup_tlbie_va_range(addr - page_size, pid, ap);
+ }
+
+ static inline void _tlbie_va(unsigned long va, unsigned long pid,
+@@ -419,7 +484,7 @@ static inline void _tlbie_va(unsigned long va, unsigned long pid,
+
+ asm volatile("ptesync": : :"memory");
+ __tlbie_va(va, pid, ap, ric);
+- fixup_tlbie();
++ fixup_tlbie_va(va, pid, ap);
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
+ }
+
+@@ -430,7 +495,7 @@ static inline void _tlbie_lpid_va(unsigned long va, unsigned long lpid,
+
+ asm volatile("ptesync": : :"memory");
+ __tlbie_lpid_va(va, lpid, ap, ric);
+- fixup_tlbie_lpid(lpid);
++ fixup_tlbie_lpid_va(va, lpid, ap);
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
+ }
+
+@@ -442,7 +507,6 @@ static inline void _tlbie_va_range(unsigned long start, unsigned long end,
+ if (also_pwc)
+ __tlbie_pid(pid, RIC_FLUSH_PWC);
+ __tlbie_va_range(start, end, pid, page_size, psize);
+- fixup_tlbie();
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
+ }
+
+@@ -773,7 +837,7 @@ is_local:
+ if (gflush)
+ __tlbie_va_range(gstart, gend, pid,
+ PUD_SIZE, MMU_PAGE_1G);
+- fixup_tlbie();
++
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
+ }
+ }
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index bd9aafe86c2f..867841c56a6d 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -349,17 +349,16 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
+ struct nbd_device *nbd = cmd->nbd;
+ struct nbd_config *config;
+
++ if (!mutex_trylock(&cmd->lock))
++ return BLK_EH_RESET_TIMER;
++
+ if (!refcount_inc_not_zero(&nbd->config_refs)) {
+ cmd->status = BLK_STS_TIMEOUT;
++ mutex_unlock(&cmd->lock);
+ goto done;
+ }
+ config = nbd->config;
+
+- if (!mutex_trylock(&cmd->lock)) {
+- nbd_config_put(nbd);
+- return BLK_EH_RESET_TIMER;
+- }
+-
+ if (config->num_connections > 1) {
+ dev_err_ratelimited(nbd_to_dev(nbd),
+ "Connection timed out, retrying (%d/%d alive)\n",
+@@ -664,6 +663,12 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
+ ret = -ENOENT;
+ goto out;
+ }
++ if (cmd->status != BLK_STS_OK) {
++ dev_err(disk_to_dev(nbd->disk), "Command already handled %p\n",
++ req);
++ ret = -ENOENT;
++ goto out;
++ }
+ if (test_bit(NBD_CMD_REQUEUED, &cmd->flags)) {
+ dev_err(disk_to_dev(nbd->disk), "Raced with timeout on req %p\n",
+ req);
+@@ -745,7 +750,10 @@ static void nbd_clear_req(struct request *req, void *data, bool reserved)
+ {
+ struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
+
++ mutex_lock(&cmd->lock);
+ cmd->status = BLK_STS_IOERR;
++ mutex_unlock(&cmd->lock);
++
+ blk_mq_complete_request(req);
+ }
+
+diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c b/drivers/crypto/chelsio/chtls/chtls_cm.c
+index 0997e166ea57..8b749c721c87 100644
+--- a/drivers/crypto/chelsio/chtls/chtls_cm.c
++++ b/drivers/crypto/chelsio/chtls/chtls_cm.c
+@@ -1276,7 +1276,7 @@ static void make_established(struct sock *sk, u32 snd_isn, unsigned int opt)
+ tp->write_seq = snd_isn;
+ tp->snd_nxt = snd_isn;
+ tp->snd_una = snd_isn;
+- inet_sk(sk)->inet_id = tp->write_seq ^ jiffies;
++ inet_sk(sk)->inet_id = prandom_u32();
+ assign_rxopt(sk, opt);
+
+ if (tp->rcv_wnd > (RCV_BUFSIZ_M << 10))
+diff --git a/drivers/crypto/chelsio/chtls/chtls_io.c b/drivers/crypto/chelsio/chtls/chtls_io.c
+index afebbd87c4aa..1587f4ac6821 100644
+--- a/drivers/crypto/chelsio/chtls/chtls_io.c
++++ b/drivers/crypto/chelsio/chtls/chtls_io.c
+@@ -1716,7 +1716,7 @@ int chtls_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
+ return peekmsg(sk, msg, len, nonblock, flags);
+
+ if (sk_can_busy_loop(sk) &&
+- skb_queue_empty(&sk->sk_receive_queue) &&
++ skb_queue_empty_lockless(&sk->sk_receive_queue) &&
+ sk->sk_state == TCP_ESTABLISHED)
+ sk_busy_loop(sk, nonblock);
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index b0e14a3d54ef..b14ce112703f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -428,7 +428,8 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
+ .interruptible = (bp->type != ttm_bo_type_kernel),
+ .no_wait_gpu = false,
+ .resv = bp->resv,
+- .flags = TTM_OPT_FLAG_ALLOW_RES_EVICT
++ .flags = bp->type != ttm_bo_type_kernel ?
++ TTM_OPT_FLAG_ALLOW_RES_EVICT : 0
+ };
+ struct amdgpu_bo *bo;
+ unsigned long page_align, size = bp->size;
+diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
+index ac9c9486b834..f4e3613f9361 100644
+--- a/drivers/i2c/busses/i2c-stm32f7.c
++++ b/drivers/i2c/busses/i2c-stm32f7.c
+@@ -297,7 +297,7 @@ struct stm32f7_i2c_dev {
+ bool use_dma;
+ };
+
+-/**
++/*
+ * All these values are coming from I2C Specification, Version 6.0, 4th of
+ * April 2014.
+ *
+@@ -1177,6 +1177,8 @@ static void stm32f7_i2c_slave_start(struct stm32f7_i2c_dev *i2c_dev)
+ STM32F7_I2C_CR1_TXIE;
+ stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask);
+
++ /* Write 1st data byte */
++ writel_relaxed(value, base + STM32F7_I2C_TXDR);
+ } else {
+ /* Notify i2c slave that new write transfer is starting */
+ i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value);
+@@ -1486,7 +1488,7 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
+ void __iomem *base = i2c_dev->base;
+ struct device *dev = i2c_dev->dev;
+ struct stm32_i2c_dma *dma = i2c_dev->dma;
+- u32 mask, status;
++ u32 status;
+
+ status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
+
+@@ -1511,12 +1513,15 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
+ f7_msg->result = -EINVAL;
+ }
+
+- /* Disable interrupts */
+- if (stm32f7_i2c_is_slave_registered(i2c_dev))
+- mask = STM32F7_I2C_XFER_IRQ_MASK;
+- else
+- mask = STM32F7_I2C_ALL_IRQ_MASK;
+- stm32f7_i2c_disable_irq(i2c_dev, mask);
++ if (!i2c_dev->slave_running) {
++ u32 mask;
++ /* Disable interrupts */
++ if (stm32f7_i2c_is_slave_registered(i2c_dev))
++ mask = STM32F7_I2C_XFER_IRQ_MASK;
++ else
++ mask = STM32F7_I2C_ALL_IRQ_MASK;
++ stm32f7_i2c_disable_irq(i2c_dev, mask);
++ }
+
+ /* Disable dma */
+ if (i2c_dev->use_dma) {
+diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
+index e7549a2b1482..050d6e040128 100644
+--- a/drivers/irqchip/irq-gic-v3-its.c
++++ b/drivers/irqchip/irq-gic-v3-its.c
+@@ -182,6 +182,22 @@ static DEFINE_IDA(its_vpeid_ida);
+ #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base)
+ #define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K)
+
++static u16 get_its_list(struct its_vm *vm)
++{
++ struct its_node *its;
++ unsigned long its_list = 0;
++
++ list_for_each_entry(its, &its_nodes, entry) {
++ if (!its->is_v4)
++ continue;
++
++ if (vm->vlpi_count[its->list_nr])
++ __set_bit(its->list_nr, &its_list);
++ }
++
++ return (u16)its_list;
++}
++
+ static struct its_collection *dev_event_to_col(struct its_device *its_dev,
+ u32 event)
+ {
+@@ -983,17 +999,15 @@ static void its_send_vmapp(struct its_node *its,
+
+ static void its_send_vmovp(struct its_vpe *vpe)
+ {
+- struct its_cmd_desc desc;
++ struct its_cmd_desc desc = {};
+ struct its_node *its;
+ unsigned long flags;
+ int col_id = vpe->col_idx;
+
+ desc.its_vmovp_cmd.vpe = vpe;
+- desc.its_vmovp_cmd.its_list = (u16)its_list_map;
+
+ if (!its_list_map) {
+ its = list_first_entry(&its_nodes, struct its_node, entry);
+- desc.its_vmovp_cmd.seq_num = 0;
+ desc.its_vmovp_cmd.col = &its->collections[col_id];
+ its_send_single_vcommand(its, its_build_vmovp_cmd, &desc);
+ return;
+@@ -1010,6 +1024,7 @@ static void its_send_vmovp(struct its_vpe *vpe)
+ raw_spin_lock_irqsave(&vmovp_lock, flags);
+
+ desc.its_vmovp_cmd.seq_num = vmovp_seq_num++;
++ desc.its_vmovp_cmd.its_list = get_its_list(vpe->its_vm);
+
+ /* Emit VMOVPs */
+ list_for_each_entry(its, &its_nodes, entry) {
+diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
+index 21786a442368..c67fd2fb333c 100644
+--- a/drivers/isdn/capi/capi.c
++++ b/drivers/isdn/capi/capi.c
+@@ -744,7 +744,7 @@ capi_poll(struct file *file, poll_table *wait)
+
+ poll_wait(file, &(cdev->recvwait), wait);
+ mask = EPOLLOUT | EPOLLWRNORM;
+- if (!skb_queue_empty(&cdev->recvqueue))
++ if (!skb_queue_empty_lockless(&cdev->recvqueue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+ return mask;
+ }
+diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
+index ad534b90ef21..2d3a2cb026d2 100644
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1584,7 +1584,6 @@ int b53_mirror_add(struct dsa_switch *ds, int port,
+ loc = B53_EG_MIR_CTL;
+
+ b53_read16(dev, B53_MGMT_PAGE, loc, &reg);
+- reg &= ~MIRROR_MASK;
+ reg |= BIT(port);
+ b53_write16(dev, B53_MGMT_PAGE, loc, reg);
+
+diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
+index 2fa2caf7a746..ca3655d28e00 100644
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -41,22 +41,11 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
+ unsigned int i;
+ u32 reg, offset;
+
+- if (priv->type == BCM7445_DEVICE_ID)
+- offset = CORE_STS_OVERRIDE_IMP;
+- else
+- offset = CORE_STS_OVERRIDE_IMP2;
+-
+ /* Enable the port memories */
+ reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL);
+ reg &= ~P_TXQ_PSM_VDD(port);
+ core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL);
+
+- /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */
+- reg = core_readl(priv, CORE_IMP_CTL);
+- reg |= (RX_BCST_EN | RX_MCST_EN | RX_UCST_EN);
+- reg &= ~(RX_DIS | TX_DIS);
+- core_writel(priv, reg, CORE_IMP_CTL);
+-
+ /* Enable forwarding */
+ core_writel(priv, SW_FWDG_EN, CORE_SWMODE);
+
+@@ -75,10 +64,27 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
+
+ b53_brcm_hdr_setup(ds, port);
+
+- /* Force link status for IMP port */
+- reg = core_readl(priv, offset);
+- reg |= (MII_SW_OR | LINK_STS);
+- core_writel(priv, reg, offset);
++ if (port == 8) {
++ if (priv->type == BCM7445_DEVICE_ID)
++ offset = CORE_STS_OVERRIDE_IMP;
++ else
++ offset = CORE_STS_OVERRIDE_IMP2;
++
++ /* Force link status for IMP port */
++ reg = core_readl(priv, offset);
++ reg |= (MII_SW_OR | LINK_STS);
++ core_writel(priv, reg, offset);
++
++ /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */
++ reg = core_readl(priv, CORE_IMP_CTL);
++ reg |= (RX_BCST_EN | RX_MCST_EN | RX_UCST_EN);
++ reg &= ~(RX_DIS | TX_DIS);
++ core_writel(priv, reg, CORE_IMP_CTL);
++ } else {
++ reg = core_readl(priv, CORE_G_PCTL_PORT(port));
++ reg &= ~(RX_DIS | TX_DIS);
++ core_writel(priv, reg, CORE_G_PCTL_PORT(port));
++ }
+ }
+
+ static void bcm_sf2_gphy_enable_set(struct dsa_switch *ds, bool enable)
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+index fd587bed32eb..bb60104b4f80 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -2020,6 +2020,8 @@ static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv)
+ */
+ if (priv->internal_phy) {
+ int0_enable |= UMAC_IRQ_LINK_EVENT;
++ if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv))
++ int0_enable |= UMAC_IRQ_PHY_DET_R;
+ } else if (priv->ext_phy) {
+ int0_enable |= UMAC_IRQ_LINK_EVENT;
+ } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
+@@ -2618,11 +2620,14 @@ static void bcmgenet_irq_task(struct work_struct *work)
+ priv->irq0_stat = 0;
+ spin_unlock_irq(&priv->lock);
+
++ if (status & UMAC_IRQ_PHY_DET_R &&
++ priv->dev->phydev->autoneg != AUTONEG_ENABLE)
++ phy_init_hw(priv->dev->phydev);
++
+ /* Link UP/DOWN event */
+- if (status & UMAC_IRQ_LINK_EVENT) {
+- priv->dev->phydev->link = !!(status & UMAC_IRQ_LINK_UP);
++ if (status & UMAC_IRQ_LINK_EVENT)
+ phy_mac_interrupt(priv->dev->phydev);
+- }
++
+ }
+
+ /* bcmgenet_isr1: handle Rx and Tx priority queues */
+@@ -2717,7 +2722,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
+ }
+
+ /* all other interested interrupts handled in bottom half */
+- status &= UMAC_IRQ_LINK_EVENT;
++ status &= (UMAC_IRQ_LINK_EVENT | UMAC_IRQ_PHY_DET_R);
+ if (status) {
+ /* Save irq status for bottom-half processing. */
+ spin_lock_irqsave(&priv->lock, flags);
+diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
+index dba8a0c1eda3..3d834d40e81e 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
+@@ -673,10 +673,10 @@ static void uld_init(struct adapter *adap, struct cxgb4_lld_info *lld)
+ lld->write_cmpl_support = adap->params.write_cmpl_support;
+ }
+
+-static void uld_attach(struct adapter *adap, unsigned int uld)
++static int uld_attach(struct adapter *adap, unsigned int uld)
+ {
+- void *handle;
+ struct cxgb4_lld_info lli;
++ void *handle;
+
+ uld_init(adap, &lli);
+ uld_queue_init(adap, uld, &lli);
+@@ -686,7 +686,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
+ dev_warn(adap->pdev_dev,
+ "could not attach to the %s driver, error %ld\n",
+ adap->uld[uld].name, PTR_ERR(handle));
+- return;
++ return PTR_ERR(handle);
+ }
+
+ adap->uld[uld].handle = handle;
+@@ -694,23 +694,24 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
+
+ if (adap->flags & FULL_INIT_DONE)
+ adap->uld[uld].state_change(handle, CXGB4_STATE_UP);
++
++ return 0;
+ }
+
+-/**
+- * cxgb4_register_uld - register an upper-layer driver
+- * @type: the ULD type
+- * @p: the ULD methods
++/* cxgb4_register_uld - register an upper-layer driver
++ * @type: the ULD type
++ * @p: the ULD methods
+ *
+- * Registers an upper-layer driver with this driver and notifies the ULD
+- * about any presently available devices that support its type. Returns
+- * %-EBUSY if a ULD of the same type is already registered.
++ * Registers an upper-layer driver with this driver and notifies the ULD
++ * about any presently available devices that support its type. Returns
++ * %-EBUSY if a ULD of the same type is already registered.
+ */
+ int cxgb4_register_uld(enum cxgb4_uld type,
+ const struct cxgb4_uld_info *p)
+ {
+- int ret = 0;
+ unsigned int adap_idx = 0;
+ struct adapter *adap;
++ int ret = 0;
+
+ if (type >= CXGB4_ULD_MAX)
+ return -EINVAL;
+@@ -744,12 +745,16 @@ int cxgb4_register_uld(enum cxgb4_uld type,
+ if (ret)
+ goto free_irq;
+ adap->uld[type] = *p;
+- uld_attach(adap, type);
++ ret = uld_attach(adap, type);
++ if (ret)
++ goto free_txq;
+ adap_idx++;
+ }
+ mutex_unlock(&uld_mutex);
+ return 0;
+
++free_txq:
++ release_sge_txq_uld(adap, type);
+ free_irq:
+ if (adap->flags & FULL_INIT_DONE)
+ quiesce_rx_uld(adap, type);
+diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
+index ed6c76d20b45..f6ed889bc36a 100644
+--- a/drivers/net/ethernet/faraday/ftgmac100.c
++++ b/drivers/net/ethernet/faraday/ftgmac100.c
+@@ -739,6 +739,18 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
+ */
+ nfrags = skb_shinfo(skb)->nr_frags;
+
++ /* Setup HW checksumming */
++ csum_vlan = 0;
++ if (skb->ip_summed == CHECKSUM_PARTIAL &&
++ !ftgmac100_prep_tx_csum(skb, &csum_vlan))
++ goto drop;
++
++ /* Add VLAN tag */
++ if (skb_vlan_tag_present(skb)) {
++ csum_vlan |= FTGMAC100_TXDES1_INS_VLANTAG;
++ csum_vlan |= skb_vlan_tag_get(skb) & 0xffff;
++ }
++
+ /* Get header len */
+ len = skb_headlen(skb);
+
+@@ -765,19 +777,6 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
+ if (nfrags == 0)
+ f_ctl_stat |= FTGMAC100_TXDES0_LTS;
+ txdes->txdes3 = cpu_to_le32(map);
+-
+- /* Setup HW checksumming */
+- csum_vlan = 0;
+- if (skb->ip_summed == CHECKSUM_PARTIAL &&
+- !ftgmac100_prep_tx_csum(skb, &csum_vlan))
+- goto drop;
+-
+- /* Add VLAN tag */
+- if (skb_vlan_tag_present(skb)) {
+- csum_vlan |= FTGMAC100_TXDES1_INS_VLANTAG;
+- csum_vlan |= skb_vlan_tag_get(skb) & 0xffff;
+- }
+-
+ txdes->txdes1 = cpu_to_le32(csum_vlan);
+
+ /* Next descriptor */
+diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c
+index a91d49dd92ea..2f8f03e0db81 100644
+--- a/drivers/net/ethernet/hisilicon/hip04_eth.c
++++ b/drivers/net/ethernet/hisilicon/hip04_eth.c
+@@ -174,6 +174,7 @@ struct hip04_priv {
+ dma_addr_t rx_phys[RX_DESC_NUM];
+ unsigned int rx_head;
+ unsigned int rx_buf_size;
++ unsigned int rx_cnt_remaining;
+
+ struct device_node *phy_node;
+ struct phy_device *phy;
+@@ -487,7 +488,6 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget)
+ struct hip04_priv *priv = container_of(napi, struct hip04_priv, napi);
+ struct net_device *ndev = priv->ndev;
+ struct net_device_stats *stats = &ndev->stats;
+- unsigned int cnt = hip04_recv_cnt(priv);
+ struct rx_desc *desc;
+ struct sk_buff *skb;
+ unsigned char *buf;
+@@ -500,8 +500,8 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget)
+
+ /* clean up tx descriptors */
+ tx_remaining = hip04_tx_reclaim(ndev, false);
+-
+- while (cnt && !last) {
++ priv->rx_cnt_remaining += hip04_recv_cnt(priv);
++ while (priv->rx_cnt_remaining && !last) {
+ buf = priv->rx_buf[priv->rx_head];
+ skb = build_skb(buf, priv->rx_buf_size);
+ if (unlikely(!skb)) {
+@@ -547,11 +547,13 @@ refill:
+ hip04_set_recv_desc(priv, phys);
+
+ priv->rx_head = RX_NEXT(priv->rx_head);
+- if (rx >= budget)
++ if (rx >= budget) {
++ --priv->rx_cnt_remaining;
+ goto done;
++ }
+
+- if (--cnt == 0)
+- cnt = hip04_recv_cnt(priv);
++ if (--priv->rx_cnt_remaining == 0)
++ priv->rx_cnt_remaining += hip04_recv_cnt(priv);
+ }
+
+ if (!(priv->reg_inten & RCV_INT)) {
+@@ -636,6 +638,7 @@ static int hip04_mac_open(struct net_device *ndev)
+ int i;
+
+ priv->rx_head = 0;
++ priv->rx_cnt_remaining = 0;
+ priv->tx_head = 0;
+ priv->tx_tail = 0;
+ hip04_reset_ppe(priv);
+diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+index 676428a57662..a4c1ed65f620 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
++++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+@@ -471,12 +471,31 @@ void mlx4_init_quotas(struct mlx4_dev *dev)
+ priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[pf];
+ }
+
+-static int get_max_gauranteed_vfs_counter(struct mlx4_dev *dev)
++static int
++mlx4_calc_res_counter_guaranteed(struct mlx4_dev *dev,
++ struct resource_allocator *res_alloc,
++ int vf)
+ {
+- /* reduce the sink counter */
+- return (dev->caps.max_counters - 1 -
+- (MLX4_PF_COUNTERS_PER_PORT * MLX4_MAX_PORTS))
+- / MLX4_MAX_PORTS;
++ struct mlx4_active_ports actv_ports;
++ int ports, counters_guaranteed;
++
++ /* For master, only allocate according to the number of phys ports */
++ if (vf == mlx4_master_func_num(dev))
++ return MLX4_PF_COUNTERS_PER_PORT * dev->caps.num_ports;
++
++ /* calculate real number of ports for the VF */
++ actv_ports = mlx4_get_active_ports(dev, vf);
++ ports = bitmap_weight(actv_ports.ports, dev->caps.num_ports);
++ counters_guaranteed = ports * MLX4_VF_COUNTERS_PER_PORT;
++
++ /* If we do not have enough counters for this VF, do not
++ * allocate any for it. '-1' to reduce the sink counter.
++ */
++ if ((res_alloc->res_reserved + counters_guaranteed) >
++ (dev->caps.max_counters - 1))
++ return 0;
++
++ return counters_guaranteed;
+ }
+
+ int mlx4_init_resource_tracker(struct mlx4_dev *dev)
+@@ -484,7 +503,6 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev)
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ int i, j;
+ int t;
+- int max_vfs_guarantee_counter = get_max_gauranteed_vfs_counter(dev);
+
+ priv->mfunc.master.res_tracker.slave_list =
+ kcalloc(dev->num_slaves, sizeof(struct slave_list),
+@@ -603,16 +621,8 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev)
+ break;
+ case RES_COUNTER:
+ res_alloc->quota[t] = dev->caps.max_counters;
+- if (t == mlx4_master_func_num(dev))
+- res_alloc->guaranteed[t] =
+- MLX4_PF_COUNTERS_PER_PORT *
+- MLX4_MAX_PORTS;
+- else if (t <= max_vfs_guarantee_counter)
+- res_alloc->guaranteed[t] =
+- MLX4_VF_COUNTERS_PER_PORT *
+- MLX4_MAX_PORTS;
+- else
+- res_alloc->guaranteed[t] = 0;
++ res_alloc->guaranteed[t] =
++ mlx4_calc_res_counter_guaranteed(dev, res_alloc, t);
+ break;
+ default:
+ break;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+index df49dc143c47..9cbc4173973e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+@@ -1267,8 +1267,11 @@ int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget)
+ if (unlikely(!test_bit(MLX5E_RQ_STATE_ENABLED, &rq->state)))
+ return 0;
+
+- if (cq->decmprs_left)
++ if (cq->decmprs_left) {
+ work_done += mlx5e_decompress_cqes_cont(rq, cq, 0, budget);
++ if (cq->decmprs_left || work_done >= budget)
++ goto out;
++ }
+
+ cqe = mlx5_cqwq_get_cqe(&cq->wq);
+ if (!cqe) {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
+index 4382ef85488c..5fb088b54e66 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
+@@ -35,6 +35,7 @@
+ #include <linux/udp.h>
+ #include <net/udp.h>
+ #include "en.h"
++#include "en/port.h"
+
+ enum {
+ MLX5E_ST_LINK_STATE,
+@@ -80,22 +81,12 @@ static int mlx5e_test_link_state(struct mlx5e_priv *priv)
+
+ static int mlx5e_test_link_speed(struct mlx5e_priv *priv)
+ {
+- u32 out[MLX5_ST_SZ_DW(ptys_reg)];
+- u32 eth_proto_oper;
+- int i;
++ u32 speed;
+
+ if (!netif_carrier_ok(priv->netdev))
+ return 1;
+
+- if (mlx5_query_port_ptys(priv->mdev, out, sizeof(out), MLX5_PTYS_EN, 1))
+- return 1;
+-
+- eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
+- for (i = 0; i < MLX5E_LINK_MODES_NUMBER; i++) {
+- if (eth_proto_oper & MLX5E_PROT_MASK(i))
+- return 0;
+- }
+- return 1;
++ return mlx5e_port_linkspeed(priv->mdev, &speed);
+ }
+
+ struct mlx5ehdr {
+diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
+index 0c8b7146637e..4ab87fe84542 100644
+--- a/drivers/net/ethernet/realtek/r8169.c
++++ b/drivers/net/ethernet/realtek/r8169.c
+@@ -1010,6 +1010,10 @@ static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg)
+ {
+ int value;
+
++ /* Work around issue with chip reporting wrong PHY ID */
++ if (reg == MII_PHYSID2)
++ return 0xc912;
++
+ r8168dp_2_mdio_start(tp);
+
+ value = r8169_mdio_read(tp, reg);
+diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
+index b2b6307d64a4..acaf072bb4b0 100644
+--- a/drivers/net/phy/bcm7xxx.c
++++ b/drivers/net/phy/bcm7xxx.c
+@@ -643,6 +643,7 @@ static int bcm7xxx_28nm_probe(struct phy_device *phydev)
+ .name = _name, \
+ .features = PHY_BASIC_FEATURES, \
+ .flags = PHY_IS_INTERNAL, \
++ .soft_reset = genphy_soft_reset, \
+ .config_init = bcm7xxx_config_init, \
+ .suspend = bcm7xxx_suspend, \
+ .resume = bcm7xxx_config_init, \
+diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
+index 85fba64c3fcf..c3cf9ae6d1df 100644
+--- a/drivers/net/usb/cdc_ether.c
++++ b/drivers/net/usb/cdc_ether.c
+@@ -800,6 +800,13 @@ static const struct usb_device_id products[] = {
+ .driver_info = 0,
+ },
+
++/* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */
++{
++ USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0xa387, USB_CLASS_COMM,
++ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
++ .driver_info = 0,
++},
++
+ /* NVIDIA Tegra USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
+ {
+ USB_DEVICE_AND_INTERFACE_INFO(NVIDIA_VENDOR_ID, 0x09ff, USB_CLASS_COMM,
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index e20266bd209e..3a172fcb06fe 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -1278,8 +1278,11 @@ static void lan78xx_status(struct lan78xx_net *dev, struct urb *urb)
+ netif_dbg(dev, link, dev->net, "PHY INTR: 0x%08x\n", intdata);
+ lan78xx_defer_kevent(dev, EVENT_LINK_RESET);
+
+- if (dev->domain_data.phyirq > 0)
++ if (dev->domain_data.phyirq > 0) {
++ local_irq_disable();
+ generic_handle_irq(dev->domain_data.phyirq);
++ local_irq_enable();
++ }
+ } else
+ netdev_warn(dev->net,
+ "unexpected interrupt: 0x%08x\n", intdata);
+@@ -3796,10 +3799,14 @@ static int lan78xx_probe(struct usb_interface *intf,
+ /* driver requires remote-wakeup capability during autosuspend. */
+ intf->needs_remote_wakeup = 1;
+
++ ret = lan78xx_phy_init(dev);
++ if (ret < 0)
++ goto out4;
++
+ ret = register_netdev(netdev);
+ if (ret != 0) {
+ netif_err(dev, probe, netdev, "couldn't register the device\n");
+- goto out4;
++ goto out5;
+ }
+
+ usb_set_intfdata(intf, dev);
+@@ -3812,14 +3819,10 @@ static int lan78xx_probe(struct usb_interface *intf,
+ pm_runtime_set_autosuspend_delay(&udev->dev,
+ DEFAULT_AUTOSUSPEND_DELAY);
+
+- ret = lan78xx_phy_init(dev);
+- if (ret < 0)
+- goto out5;
+-
+ return 0;
+
+ out5:
+- unregister_netdev(netdev);
++ phy_disconnect(netdev->phydev);
+ out4:
+ usb_free_urb(dev->urb_intr);
+ out3:
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index a291e5f2daef..91d47a714afd 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -5339,6 +5339,7 @@ static const struct usb_device_id rtl8152_table[] = {
+ {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)},
+ {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)},
+ {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)},
++ {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa387)},
+ {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)},
+ {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)},
+ {REALTEK_USB_DEVICE(VENDOR_ID_TPLINK, 0x0601)},
+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
+index 0b1ec44acbf9..2a536f84d5f6 100644
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -2174,9 +2174,11 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+ vni = tunnel_id_to_key32(info->key.tun_id);
+ ifindex = 0;
+ dst_cache = &info->dst_cache;
+- if (info->options_len &&
+- info->key.tun_flags & TUNNEL_VXLAN_OPT)
++ if (info->key.tun_flags & TUNNEL_VXLAN_OPT) {
++ if (info->options_len < sizeof(*md))
++ goto drop;
+ md = ip_tunnel_info_opts(info);
++ }
+ ttl = info->key.ttl;
+ tos = info->key.tos;
+ label = info->key.label;
+diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
+index 7f42314da6ae..bac4b4bbc33d 100644
+--- a/drivers/of/unittest.c
++++ b/drivers/of/unittest.c
+@@ -1159,6 +1159,7 @@ static int __init unittest_data_add(void)
+ of_fdt_unflatten_tree(unittest_data, NULL, &unittest_data_node);
+ if (!unittest_data_node) {
+ pr_warn("%s: No tree to attach; not running tests\n", __func__);
++ kfree(unittest_data);
+ return -ENODATA;
+ }
+
+diff --git a/drivers/pinctrl/bcm/pinctrl-ns2-mux.c b/drivers/pinctrl/bcm/pinctrl-ns2-mux.c
+index 4b5cf0e0f16e..951090faa6a9 100644
+--- a/drivers/pinctrl/bcm/pinctrl-ns2-mux.c
++++ b/drivers/pinctrl/bcm/pinctrl-ns2-mux.c
+@@ -640,8 +640,8 @@ static int ns2_pinmux_enable(struct pinctrl_dev *pctrl_dev,
+ const struct ns2_pin_function *func;
+ const struct ns2_pin_group *grp;
+
+- if (grp_select > pinctrl->num_groups ||
+- func_select > pinctrl->num_functions)
++ if (grp_select >= pinctrl->num_groups ||
++ func_select >= pinctrl->num_functions)
+ return -EINVAL;
+
+ func = &pinctrl->functions[func_select];
+diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
+index 6a61028cbb3c..429166e6ec9e 100644
+--- a/drivers/platform/x86/pmc_atom.c
++++ b/drivers/platform/x86/pmc_atom.c
+@@ -445,6 +445,13 @@ static const struct dmi_system_id critclk_systems[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "CB6363"),
+ },
+ },
++ {
++ .ident = "SIMATIC IPC227E",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "SIEMENS AG"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "6ES7647-8B"),
++ },
++ },
+ { /*sentinel*/ }
+ };
+
+diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
+index 210fc20f7de7..b255590aef36 100644
+--- a/drivers/regulator/of_regulator.c
++++ b/drivers/regulator/of_regulator.c
+@@ -214,12 +214,12 @@ static void of_get_regulation_constraints(struct device_node *np,
+ "regulator-off-in-suspend"))
+ suspend_state->enabled = DISABLE_IN_SUSPEND;
+
+- if (!of_property_read_u32(np, "regulator-suspend-min-microvolt",
+- &pval))
++ if (!of_property_read_u32(suspend_np,
++ "regulator-suspend-min-microvolt", &pval))
+ suspend_state->min_uV = pval;
+
+- if (!of_property_read_u32(np, "regulator-suspend-max-microvolt",
+- &pval))
++ if (!of_property_read_u32(suspend_np,
++ "regulator-suspend-max-microvolt", &pval))
+ suspend_state->max_uV = pval;
+
+ if (!of_property_read_u32(suspend_np,
+diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
+index 31c3a236120a..69a377ab2604 100644
+--- a/drivers/regulator/pfuze100-regulator.c
++++ b/drivers/regulator/pfuze100-regulator.c
+@@ -710,7 +710,13 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
+
+ /* SW2~SW4 high bit check and modify the voltage value table */
+ if (i >= sw_check_start && i <= sw_check_end) {
+- regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val);
++ ret = regmap_read(pfuze_chip->regmap,
++ desc->vsel_reg, &val);
++ if (ret) {
++ dev_err(&client->dev, "Fails to read from the register.\n");
++ return ret;
++ }
++
+ if (val & sw_hi) {
+ if (pfuze_chip->chip_id == PFUZE3000 ||
+ pfuze_chip->chip_id == PFUZE3001) {
+diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c
+index cced1ffb896c..89b9314d64c9 100644
+--- a/drivers/regulator/ti-abb-regulator.c
++++ b/drivers/regulator/ti-abb-regulator.c
+@@ -173,19 +173,14 @@ static int ti_abb_wait_txdone(struct device *dev, struct ti_abb *abb)
+ while (timeout++ <= abb->settling_time) {
+ status = ti_abb_check_txdone(abb);
+ if (status)
+- break;
++ return 0;
+
+ udelay(1);
+ }
+
+- if (timeout > abb->settling_time) {
+- dev_warn_ratelimited(dev,
+- "%s:TRANXDONE timeout(%duS) int=0x%08x\n",
+- __func__, timeout, readl(abb->int_base));
+- return -ETIMEDOUT;
+- }
+-
+- return 0;
++ dev_warn_ratelimited(dev, "%s:TRANXDONE timeout(%duS) int=0x%08x\n",
++ __func__, timeout, readl(abb->int_base));
++ return -ETIMEDOUT;
+ }
+
+ /**
+@@ -205,19 +200,14 @@ static int ti_abb_clear_all_txdone(struct device *dev, const struct ti_abb *abb)
+
+ status = ti_abb_check_txdone(abb);
+ if (!status)
+- break;
++ return 0;
+
+ udelay(1);
+ }
+
+- if (timeout > abb->settling_time) {
+- dev_warn_ratelimited(dev,
+- "%s:TRANXDONE timeout(%duS) int=0x%08x\n",
+- __func__, timeout, readl(abb->int_base));
+- return -ETIMEDOUT;
+- }
+-
+- return 0;
++ dev_warn_ratelimited(dev, "%s:TRANXDONE timeout(%duS) int=0x%08x\n",
++ __func__, timeout, readl(abb->int_base));
++ return -ETIMEDOUT;
+ }
+
+ /**
+diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
+index 7c097006c54d..a8ac48027632 100644
+--- a/drivers/scsi/Kconfig
++++ b/drivers/scsi/Kconfig
+@@ -862,7 +862,7 @@ config SCSI_SNI_53C710
+
+ config 53C700_LE_ON_BE
+ bool
+- depends on SCSI_LASI700
++ depends on SCSI_LASI700 || SCSI_SNI_53C710
+ default y
+
+ config SCSI_STEX
+diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
+index 9c21938ed67e..c95c782b93a5 100644
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -526,6 +526,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
+ unsigned int tpg_desc_tbl_off;
+ unsigned char orig_transition_tmo;
+ unsigned long flags;
++ bool transitioning_sense = false;
+
+ if (!pg->expiry) {
+ unsigned long transition_tmo = ALUA_FAILOVER_TIMEOUT * HZ;
+@@ -586,13 +587,19 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
+ goto retry;
+ }
+ /*
+- * Retry on ALUA state transition or if any
+- * UNIT ATTENTION occurred.
++ * If the array returns with 'ALUA state transition'
++ * sense code here it cannot return RTPG data during
++ * transition. So set the state to 'transitioning' directly.
+ */
+ if (sense_hdr.sense_key == NOT_READY &&
+- sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a)
+- err = SCSI_DH_RETRY;
+- else if (sense_hdr.sense_key == UNIT_ATTENTION)
++ sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) {
++ transitioning_sense = true;
++ goto skip_rtpg;
++ }
++ /*
++ * Retry on any other UNIT ATTENTION occurred.
++ */
++ if (sense_hdr.sense_key == UNIT_ATTENTION)
+ err = SCSI_DH_RETRY;
+ if (err == SCSI_DH_RETRY &&
+ pg->expiry != 0 && time_before(jiffies, pg->expiry)) {
+@@ -680,7 +687,11 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
+ off = 8 + (desc[7] * 4);
+ }
+
++ skip_rtpg:
+ spin_lock_irqsave(&pg->lock, flags);
++ if (transitioning_sense)
++ pg->state = SCSI_ACCESS_STATE_TRANSITIONING;
++
+ sdev_printk(KERN_INFO, sdev,
+ "%s: port group %02x state %c %s supports %c%c%c%c%c%c%c\n",
+ ALUA_DH_NAME, pg->group_id, print_alua_state(pg->state),
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 60b6019a2fca..856a7ceb9a04 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -3186,6 +3186,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ req->req_q_in, req->req_q_out, rsp->rsp_q_in, rsp->rsp_q_out);
+
+ ha->wq = alloc_workqueue("qla2xxx_wq", 0, 0);
++ if (unlikely(!ha->wq)) {
++ ret = -ENOMEM;
++ goto probe_failed;
++ }
+
+ if (ha->isp_ops->initialize_adapter(base_vha)) {
+ ql_log(ql_log_fatal, base_vha, 0x00d6,
+diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c
+index 1f9a087daf69..3102a75984d3 100644
+--- a/drivers/scsi/sni_53c710.c
++++ b/drivers/scsi/sni_53c710.c
+@@ -78,10 +78,8 @@ static int snirm710_probe(struct platform_device *dev)
+
+ base = res->start;
+ hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL);
+- if (!hostdata) {
+- dev_printk(KERN_ERR, dev, "Failed to allocate host data\n");
++ if (!hostdata)
+ return -ENOMEM;
+- }
+
+ hostdata->dev = &dev->dev;
+ dma_set_mask(&dev->dev, DMA_BIT_MASK(32));
+diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
+index 47b5ef153135..e9ff2a7c0c0e 100644
+--- a/drivers/target/target_core_device.c
++++ b/drivers/target/target_core_device.c
+@@ -1128,27 +1128,6 @@ passthrough_parse_cdb(struct se_cmd *cmd,
+ struct se_device *dev = cmd->se_dev;
+ unsigned int size;
+
+- /*
+- * Clear a lun set in the cdb if the initiator talking to use spoke
+- * and old standards version, as we can't assume the underlying device
+- * won't choke up on it.
+- */
+- switch (cdb[0]) {
+- case READ_10: /* SBC - RDProtect */
+- case READ_12: /* SBC - RDProtect */
+- case READ_16: /* SBC - RDProtect */
+- case SEND_DIAGNOSTIC: /* SPC - SELF-TEST Code */
+- case VERIFY: /* SBC - VRProtect */
+- case VERIFY_16: /* SBC - VRProtect */
+- case WRITE_VERIFY: /* SBC - VRProtect */
+- case WRITE_VERIFY_12: /* SBC - VRProtect */
+- case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */
+- break;
+- default:
+- cdb[1] &= 0x1f; /* clear logical unit number */
+- break;
+- }
+-
+ /*
+ * For REPORT LUNS we always need to emulate the response, for everything
+ * else, pass it up.
+diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c
+index 127017cc41d9..057b1eaf6d2e 100644
+--- a/drivers/tty/serial/8250/8250_men_mcb.c
++++ b/drivers/tty/serial/8250/8250_men_mcb.c
+@@ -71,8 +71,8 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
+ {
+ struct serial_8250_men_mcb_data *data;
+ struct resource *mem;
+- unsigned int num_ports;
+- unsigned int i;
++ int num_ports;
++ int i;
+ void __iomem *membase;
+
+ mem = mcb_get_resource(mdev, IORESOURCE_MEM);
+@@ -87,7 +87,7 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
+ dev_dbg(&mdev->dev, "found a 16z%03u with %u ports\n",
+ mdev->id, num_ports);
+
+- if (num_ports == 0 || num_ports > 4) {
++ if (num_ports <= 0 || num_ports > 4) {
+ dev_err(&mdev->dev, "unexpected number of ports: %u\n",
+ num_ports);
+ return -ENODEV;
+@@ -132,7 +132,7 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
+
+ static void serial_8250_men_mcb_remove(struct mcb_device *mdev)
+ {
+- unsigned int num_ports, i;
++ int num_ports, i;
+ struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev);
+
+ if (!data)
+diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
+index aa31d36bed00..1a79a9955187 100644
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -1149,7 +1149,7 @@ static int check_pending_gadget_drivers(struct usb_udc *udc)
+ dev_name(&udc->dev)) == 0) {
+ ret = udc_bind_to_driver(udc, driver);
+ if (ret != -EPROBE_DEFER)
+- list_del(&driver->pending);
++ list_del_init(&driver->pending);
+ break;
+ }
+
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 4dbae6e268d6..71c2dd0c7f03 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -1286,6 +1286,11 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
+ struct cifsInodeInfo {
+ bool can_cache_brlcks;
+ struct list_head llist; /* locks helb by this inode */
++ /*
++ * NOTE: Some code paths call down_read(lock_sem) twice, so
++ * we must always use use cifs_down_write() instead of down_write()
++ * for this semaphore to avoid deadlocks.
++ */
+ struct rw_semaphore lock_sem; /* protect the fields above */
+ /* BB add in lists for dirty pages i.e. write caching info for oplock */
+ struct list_head openFileList;
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index 20adda4de83b..d7ac75ea881c 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -159,6 +159,7 @@ extern int cifs_unlock_range(struct cifsFileInfo *cfile,
+ struct file_lock *flock, const unsigned int xid);
+ extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile);
+
++extern void cifs_down_write(struct rw_semaphore *sem);
+ extern struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid,
+ struct file *file,
+ struct tcon_link *tlink,
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index b4e33ef2ff31..a8e2bc47dcf2 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -280,6 +280,13 @@ cifs_has_mand_locks(struct cifsInodeInfo *cinode)
+ return has_locks;
+ }
+
++void
++cifs_down_write(struct rw_semaphore *sem)
++{
++ while (!down_write_trylock(sem))
++ msleep(10);
++}
++
+ struct cifsFileInfo *
+ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+ struct tcon_link *tlink, __u32 oplock)
+@@ -305,7 +312,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+ INIT_LIST_HEAD(&fdlocks->locks);
+ fdlocks->cfile = cfile;
+ cfile->llist = fdlocks;
+- down_write(&cinode->lock_sem);
++ cifs_down_write(&cinode->lock_sem);
+ list_add(&fdlocks->llist, &cinode->llist);
+ up_write(&cinode->lock_sem);
+
+@@ -461,7 +468,7 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_handler)
+ * Delete any outstanding lock records. We'll lose them when the file
+ * is closed anyway.
+ */
+- down_write(&cifsi->lock_sem);
++ cifs_down_write(&cifsi->lock_sem);
+ list_for_each_entry_safe(li, tmp, &cifs_file->llist->locks, llist) {
+ list_del(&li->llist);
+ cifs_del_lock_waiters(li);
+@@ -1016,7 +1023,7 @@ static void
+ cifs_lock_add(struct cifsFileInfo *cfile, struct cifsLockInfo *lock)
+ {
+ struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry));
+- down_write(&cinode->lock_sem);
++ cifs_down_write(&cinode->lock_sem);
+ list_add_tail(&lock->llist, &cfile->llist->locks);
+ up_write(&cinode->lock_sem);
+ }
+@@ -1038,7 +1045,7 @@ cifs_lock_add_if(struct cifsFileInfo *cfile, struct cifsLockInfo *lock,
+
+ try_again:
+ exist = false;
+- down_write(&cinode->lock_sem);
++ cifs_down_write(&cinode->lock_sem);
+
+ exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length,
+ lock->type, &conf_lock, CIFS_LOCK_OP);
+@@ -1060,7 +1067,7 @@ try_again:
+ (lock->blist.next == &lock->blist));
+ if (!rc)
+ goto try_again;
+- down_write(&cinode->lock_sem);
++ cifs_down_write(&cinode->lock_sem);
+ list_del_init(&lock->blist);
+ }
+
+@@ -1113,7 +1120,7 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock)
+ return rc;
+
+ try_again:
+- down_write(&cinode->lock_sem);
++ cifs_down_write(&cinode->lock_sem);
+ if (!cinode->can_cache_brlcks) {
+ up_write(&cinode->lock_sem);
+ return rc;
+@@ -1319,7 +1326,7 @@ cifs_push_locks(struct cifsFileInfo *cfile)
+ int rc = 0;
+
+ /* we are going to update can_cache_brlcks here - need a write access */
+- down_write(&cinode->lock_sem);
++ cifs_down_write(&cinode->lock_sem);
+ if (!cinode->can_cache_brlcks) {
+ up_write(&cinode->lock_sem);
+ return rc;
+@@ -1510,7 +1517,7 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
+ if (!buf)
+ return -ENOMEM;
+
+- down_write(&cinode->lock_sem);
++ cifs_down_write(&cinode->lock_sem);
+ for (i = 0; i < 2; i++) {
+ cur = buf;
+ num = 0;
+diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
+index b204e84b87fb..9168b2266e4f 100644
+--- a/fs/cifs/smb2file.c
++++ b/fs/cifs/smb2file.c
+@@ -137,7 +137,7 @@ smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
+
+ cur = buf;
+
+- down_write(&cinode->lock_sem);
++ cifs_down_write(&cinode->lock_sem);
+ list_for_each_entry_safe(li, tmp, &cfile->llist->locks, llist) {
+ if (flock->fl_start > li->offset ||
+ (flock->fl_start + length) <
+diff --git a/include/linux/gfp.h b/include/linux/gfp.h
+index 24bcc5eec6b4..f78d1e89593f 100644
+--- a/include/linux/gfp.h
++++ b/include/linux/gfp.h
+@@ -325,6 +325,29 @@ static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags)
+ return !!(gfp_flags & __GFP_DIRECT_RECLAIM);
+ }
+
++/**
++ * gfpflags_normal_context - is gfp_flags a normal sleepable context?
++ * @gfp_flags: gfp_flags to test
++ *
++ * Test whether @gfp_flags indicates that the allocation is from the
++ * %current context and allowed to sleep.
++ *
++ * An allocation being allowed to block doesn't mean it owns the %current
++ * context. When direct reclaim path tries to allocate memory, the
++ * allocation context is nested inside whatever %current was doing at the
++ * time of the original allocation. The nested allocation may be allowed
++ * to block but modifying anything %current owns can corrupt the outer
++ * context's expectations.
++ *
++ * %true result from this function indicates that the allocation context
++ * can sleep and use anything that's associated with %current.
++ */
++static inline bool gfpflags_normal_context(const gfp_t gfp_flags)
++{
++ return (gfp_flags & (__GFP_DIRECT_RECLAIM | __GFP_MEMALLOC)) ==
++ __GFP_DIRECT_RECLAIM;
++}
++
+ #ifdef CONFIG_HIGHMEM
+ #define OPT_ZONE_HIGHMEM ZONE_HIGHMEM
+ #else
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 28baccb1efd5..80c3da1aa8b1 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -1251,7 +1251,8 @@ static inline __u32 skb_get_hash_flowi6(struct sk_buff *skb, const struct flowi6
+ return skb->hash;
+ }
+
+-__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb);
++__u32 skb_get_hash_perturb(const struct sk_buff *skb,
++ const siphash_key_t *perturb);
+
+ static inline __u32 skb_get_hash_raw(const struct sk_buff *skb)
+ {
+@@ -1379,6 +1380,19 @@ static inline int skb_queue_empty(const struct sk_buff_head *list)
+ return list->next == (const struct sk_buff *) list;
+ }
+
++/**
++ * skb_queue_empty_lockless - check if a queue is empty
++ * @list: queue head
++ *
++ * Returns true if the queue is empty, false otherwise.
++ * This variant can be used in lockless contexts.
++ */
++static inline bool skb_queue_empty_lockless(const struct sk_buff_head *list)
++{
++ return READ_ONCE(list->next) == (const struct sk_buff *) list;
++}
++
++
+ /**
+ * skb_queue_is_last - check if skb is the last entry in the queue
+ * @list: queue head
+@@ -1723,9 +1737,11 @@ static inline void __skb_insert(struct sk_buff *newsk,
+ struct sk_buff *prev, struct sk_buff *next,
+ struct sk_buff_head *list)
+ {
+- newsk->next = next;
+- newsk->prev = prev;
+- next->prev = prev->next = newsk;
++ /* see skb_queue_empty_lockless() for the opposite READ_ONCE() */
++ WRITE_ONCE(newsk->next, next);
++ WRITE_ONCE(newsk->prev, prev);
++ WRITE_ONCE(next->prev, newsk);
++ WRITE_ONCE(prev->next, newsk);
+ list->qlen++;
+ }
+
+@@ -1736,11 +1752,11 @@ static inline void __skb_queue_splice(const struct sk_buff_head *list,
+ struct sk_buff *first = list->next;
+ struct sk_buff *last = list->prev;
+
+- first->prev = prev;
+- prev->next = first;
++ WRITE_ONCE(first->prev, prev);
++ WRITE_ONCE(prev->next, first);
+
+- last->next = next;
+- next->prev = last;
++ WRITE_ONCE(last->next, next);
++ WRITE_ONCE(next->prev, last);
+ }
+
+ /**
+@@ -1881,8 +1897,8 @@ static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
+ next = skb->next;
+ prev = skb->prev;
+ skb->next = skb->prev = NULL;
+- next->prev = prev;
+- prev->next = next;
++ WRITE_ONCE(next->prev, prev);
++ WRITE_ONCE(prev->next, next);
+ }
+
+ /**
+diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h
+index ba61cdd09eaa..cf8f792743ec 100644
+--- a/include/net/busy_poll.h
++++ b/include/net/busy_poll.h
+@@ -134,7 +134,7 @@ static inline void skb_mark_napi_id(struct sk_buff *skb,
+ static inline void sk_mark_napi_id(struct sock *sk, const struct sk_buff *skb)
+ {
+ #ifdef CONFIG_NET_RX_BUSY_POLL
+- sk->sk_napi_id = skb->napi_id;
++ WRITE_ONCE(sk->sk_napi_id, skb->napi_id);
+ #endif
+ sk_rx_queue_set(sk, skb);
+ }
+@@ -144,8 +144,8 @@ static inline void sk_mark_napi_id_once(struct sock *sk,
+ const struct sk_buff *skb)
+ {
+ #ifdef CONFIG_NET_RX_BUSY_POLL
+- if (!sk->sk_napi_id)
+- sk->sk_napi_id = skb->napi_id;
++ if (!READ_ONCE(sk->sk_napi_id))
++ WRITE_ONCE(sk->sk_napi_id, skb->napi_id);
+ #endif
+ }
+
+diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
+index 6a4586dcdede..4618cbbe3632 100644
+--- a/include/net/flow_dissector.h
++++ b/include/net/flow_dissector.h
+@@ -4,6 +4,7 @@
+
+ #include <linux/types.h>
+ #include <linux/in6.h>
++#include <linux/siphash.h>
+ #include <uapi/linux/if_ether.h>
+
+ /**
+@@ -252,7 +253,7 @@ struct flow_keys_basic {
+ struct flow_keys {
+ struct flow_dissector_key_control control;
+ #define FLOW_KEYS_HASH_START_FIELD basic
+- struct flow_dissector_key_basic basic;
++ struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT);
+ struct flow_dissector_key_tags tags;
+ struct flow_dissector_key_vlan vlan;
+ struct flow_dissector_key_vlan cvlan;
+diff --git a/include/net/fq.h b/include/net/fq.h
+index ac944a686840..c51be50e1349 100644
+--- a/include/net/fq.h
++++ b/include/net/fq.h
+@@ -70,7 +70,7 @@ struct fq {
+ struct list_head backlogs;
+ spinlock_t lock;
+ u32 flows_cnt;
+- u32 perturbation;
++ siphash_key_t perturbation;
+ u32 limit;
+ u32 memory_limit;
+ u32 memory_usage;
+diff --git a/include/net/fq_impl.h b/include/net/fq_impl.h
+index be7c0fab3478..89a012905ef0 100644
+--- a/include/net/fq_impl.h
++++ b/include/net/fq_impl.h
+@@ -118,7 +118,7 @@ static struct fq_flow *fq_flow_classify(struct fq *fq,
+
+ lockdep_assert_held(&fq->lock);
+
+- hash = skb_get_hash_perturb(skb, fq->perturbation);
++ hash = skb_get_hash_perturb(skb, &fq->perturbation);
+ idx = reciprocal_scale(hash, fq->flows_cnt);
+ flow = &fq->flows[idx];
+
+@@ -307,7 +307,7 @@ static int fq_init(struct fq *fq, int flows_cnt)
+ INIT_LIST_HEAD(&fq->backlogs);
+ spin_lock_init(&fq->lock);
+ fq->flows_cnt = max_t(u32, flows_cnt, 1);
+- fq->perturbation = prandom_u32();
++ get_random_bytes(&fq->perturbation, sizeof(fq->perturbation));
+ fq->quantum = 300;
+ fq->limit = 8192;
+ fq->memory_limit = 16 << 20; /* 16 MBytes */
+diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
+index 3f7b166262d7..5007eaba207d 100644
+--- a/include/net/net_namespace.h
++++ b/include/net/net_namespace.h
+@@ -322,7 +322,7 @@ static inline struct net *read_pnet(const possible_net_t *pnet)
+ #define __net_initconst __initconst
+ #endif
+
+-int peernet2id_alloc(struct net *net, struct net *peer);
++int peernet2id_alloc(struct net *net, struct net *peer, gfp_t gfp);
+ int peernet2id(struct net *net, struct net *peer);
+ bool peernet_has_id(struct net *net, struct net *peer);
+ struct net *get_net_ns_by_id(struct net *net, int id);
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 1ece7736c49c..05e8faa84717 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -945,8 +945,8 @@ static inline void sk_incoming_cpu_update(struct sock *sk)
+ {
+ int cpu = raw_smp_processor_id();
+
+- if (unlikely(sk->sk_incoming_cpu != cpu))
+- sk->sk_incoming_cpu = cpu;
++ if (unlikely(READ_ONCE(sk->sk_incoming_cpu) != cpu))
++ WRITE_ONCE(sk->sk_incoming_cpu, cpu);
+ }
+
+ static inline void sock_rps_record_flow_hash(__u32 hash)
+@@ -2216,12 +2216,17 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp,
+ * sk_page_frag - return an appropriate page_frag
+ * @sk: socket
+ *
+- * If socket allocation mode allows current thread to sleep, it means its
+- * safe to use the per task page_frag instead of the per socket one.
++ * Use the per task page_frag instead of the per socket one for
++ * optimization when we know that we're in the normal context and owns
++ * everything that's associated with %current.
++ *
++ * gfpflags_allow_blocking() isn't enough here as direct reclaim may nest
++ * inside other socket operations and end up recursing into sk_page_frag()
++ * while it's already in use.
+ */
+ static inline struct page_frag *sk_page_frag(struct sock *sk)
+ {
+- if (gfpflags_allow_blocking(sk->sk_allocation))
++ if (gfpflags_normal_context(sk->sk_allocation))
+ return &current->task_frag;
+
+ return &sk->sk_frag;
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index bdf104596d12..dac518977e7d 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -448,6 +448,8 @@ static bool synth_field_signed(char *type)
+ {
+ if (strncmp(type, "u", 1) == 0)
+ return false;
++ if (strcmp(type, "gfp_t") == 0)
++ return false;
+
+ return true;
+ }
+diff --git a/net/atm/common.c b/net/atm/common.c
+index a38c174fc766..6772eddf6ec0 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -667,7 +667,7 @@ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+ mask |= EPOLLHUP;
+
+ /* readable? */
+- if (!skb_queue_empty(&sk->sk_receive_queue))
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+
+ /* writable? */
+diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
+index 8d12198eaa94..ee60c30f3be2 100644
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -460,7 +460,7 @@ __poll_t bt_sock_poll(struct file *file, struct socket *sock,
+ if (sk->sk_state == BT_LISTEN)
+ return bt_accept_poll(sk);
+
+- if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
++ if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
+ mask |= EPOLLERR |
+ (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
+
+@@ -470,7 +470,7 @@ __poll_t bt_sock_poll(struct file *file, struct socket *sock,
+ if (sk->sk_shutdown == SHUTDOWN_MASK)
+ mask |= EPOLLHUP;
+
+- if (!skb_queue_empty(&sk->sk_receive_queue))
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+
+ if (sk->sk_state == BT_CLOSED)
+diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
+index 416717c57cd1..4b31f0aaa96d 100644
+--- a/net/caif/caif_socket.c
++++ b/net/caif/caif_socket.c
+@@ -953,7 +953,7 @@ static __poll_t caif_poll(struct file *file,
+ mask |= EPOLLRDHUP;
+
+ /* readable? */
+- if (!skb_queue_empty(&sk->sk_receive_queue) ||
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue) ||
+ (sk->sk_shutdown & RCV_SHUTDOWN))
+ mask |= EPOLLIN | EPOLLRDNORM;
+
+diff --git a/net/core/datagram.c b/net/core/datagram.c
+index a487df53a453..865a8cb7b0bd 100644
+--- a/net/core/datagram.c
++++ b/net/core/datagram.c
+@@ -95,7 +95,7 @@ int __skb_wait_for_more_packets(struct sock *sk, int *err, long *timeo_p,
+ if (error)
+ goto out_err;
+
+- if (sk->sk_receive_queue.prev != skb)
++ if (READ_ONCE(sk->sk_receive_queue.prev) != skb)
+ goto out;
+
+ /* Socket shut down? */
+@@ -279,7 +279,7 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned int flags,
+ break;
+
+ sk_busy_loop(sk, flags & MSG_DONTWAIT);
+- } while (sk->sk_receive_queue.prev != *last);
++ } while (READ_ONCE(sk->sk_receive_queue.prev) != *last);
+
+ error = -EAGAIN;
+
+@@ -842,7 +842,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,
+ mask = 0;
+
+ /* exceptional events? */
+- if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
++ if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
+ mask |= EPOLLERR |
+ (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
+
+@@ -852,7 +852,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,
+ mask |= EPOLLHUP;
+
+ /* readable? */
+- if (!skb_queue_empty(&sk->sk_receive_queue))
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+
+ /* Connection-based need to check for termination and startup */
+diff --git a/net/core/dev.c b/net/core/dev.c
+index ddd8aab20adf..4a2ee1ce6c02 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -9211,7 +9211,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
+ call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
+ rcu_barrier();
+
+- new_nsid = peernet2id_alloc(dev_net(dev), net);
++ new_nsid = peernet2id_alloc(dev_net(dev), net, GFP_KERNEL);
+ /* If there is an ifindex conflict assign a new one */
+ if (__dev_get_by_index(net, dev->ifindex))
+ new_ifindex = dev_new_index(net);
+diff --git a/net/core/ethtool.c b/net/core/ethtool.c
+index 996813f345d5..09d828a6a173 100644
+--- a/net/core/ethtool.c
++++ b/net/core/ethtool.c
+@@ -1482,11 +1482,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
+
+ static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
+ {
+- struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
++ struct ethtool_wolinfo wol;
+
+ if (!dev->ethtool_ops->get_wol)
+ return -EOPNOTSUPP;
+
++ memset(&wol, 0, sizeof(struct ethtool_wolinfo));
++ wol.cmd = ETHTOOL_GWOL;
+ dev->ethtool_ops->get_wol(dev, &wol);
+
+ if (copy_to_user(useraddr, &wol, sizeof(wol)))
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 415b95f76b66..4362ffe9b5ef 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -1077,30 +1077,21 @@ out_bad:
+ }
+ EXPORT_SYMBOL(__skb_flow_dissect);
+
+-static u32 hashrnd __read_mostly;
++static siphash_key_t hashrnd __read_mostly;
+ static __always_inline void __flow_hash_secret_init(void)
+ {
+ net_get_random_once(&hashrnd, sizeof(hashrnd));
+ }
+
+-static __always_inline u32 __flow_hash_words(const u32 *words, u32 length,
+- u32 keyval)
++static const void *flow_keys_hash_start(const struct flow_keys *flow)
+ {
+- return jhash2(words, length, keyval);
+-}
+-
+-static inline const u32 *flow_keys_hash_start(const struct flow_keys *flow)
+-{
+- const void *p = flow;
+-
+- BUILD_BUG_ON(FLOW_KEYS_HASH_OFFSET % sizeof(u32));
+- return (const u32 *)(p + FLOW_KEYS_HASH_OFFSET);
++ BUILD_BUG_ON(FLOW_KEYS_HASH_OFFSET % SIPHASH_ALIGNMENT);
++ return &flow->FLOW_KEYS_HASH_START_FIELD;
+ }
+
+ static inline size_t flow_keys_hash_length(const struct flow_keys *flow)
+ {
+ size_t diff = FLOW_KEYS_HASH_OFFSET + sizeof(flow->addrs);
+- BUILD_BUG_ON((sizeof(*flow) - FLOW_KEYS_HASH_OFFSET) % sizeof(u32));
+ BUILD_BUG_ON(offsetof(typeof(*flow), addrs) !=
+ sizeof(*flow) - sizeof(flow->addrs));
+
+@@ -1115,7 +1106,7 @@ static inline size_t flow_keys_hash_length(const struct flow_keys *flow)
+ diff -= sizeof(flow->addrs.tipckey);
+ break;
+ }
+- return (sizeof(*flow) - diff) / sizeof(u32);
++ return sizeof(*flow) - diff;
+ }
+
+ __be32 flow_get_u32_src(const struct flow_keys *flow)
+@@ -1181,14 +1172,15 @@ static inline void __flow_hash_consistentify(struct flow_keys *keys)
+ }
+ }
+
+-static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval)
++static inline u32 __flow_hash_from_keys(struct flow_keys *keys,
++ const siphash_key_t *keyval)
+ {
+ u32 hash;
+
+ __flow_hash_consistentify(keys);
+
+- hash = __flow_hash_words(flow_keys_hash_start(keys),
+- flow_keys_hash_length(keys), keyval);
++ hash = siphash(flow_keys_hash_start(keys),
++ flow_keys_hash_length(keys), keyval);
+ if (!hash)
+ hash = 1;
+
+@@ -1198,12 +1190,13 @@ static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval)
+ u32 flow_hash_from_keys(struct flow_keys *keys)
+ {
+ __flow_hash_secret_init();
+- return __flow_hash_from_keys(keys, hashrnd);
++ return __flow_hash_from_keys(keys, &hashrnd);
+ }
+ EXPORT_SYMBOL(flow_hash_from_keys);
+
+ static inline u32 ___skb_get_hash(const struct sk_buff *skb,
+- struct flow_keys *keys, u32 keyval)
++ struct flow_keys *keys,
++ const siphash_key_t *keyval)
+ {
+ skb_flow_dissect_flow_keys(skb, keys,
+ FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
+@@ -1251,7 +1244,7 @@ u32 __skb_get_hash_symmetric(const struct sk_buff *skb)
+ NULL, 0, 0, 0,
+ FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
+
+- return __flow_hash_from_keys(&keys, hashrnd);
++ return __flow_hash_from_keys(&keys, &hashrnd);
+ }
+ EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric);
+
+@@ -1271,13 +1264,14 @@ void __skb_get_hash(struct sk_buff *skb)
+
+ __flow_hash_secret_init();
+
+- hash = ___skb_get_hash(skb, &keys, hashrnd);
++ hash = ___skb_get_hash(skb, &keys, &hashrnd);
+
+ __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys));
+ }
+ EXPORT_SYMBOL(__skb_get_hash);
+
+-__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb)
++__u32 skb_get_hash_perturb(const struct sk_buff *skb,
++ const siphash_key_t *perturb)
+ {
+ struct flow_keys keys;
+
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
+index 7320f0844a50..6dab186d4b8f 100644
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -226,11 +226,11 @@ static int __peernet2id(struct net *net, struct net *peer)
+ return __peernet2id_alloc(net, peer, &no);
+ }
+
+-static void rtnl_net_notifyid(struct net *net, int cmd, int id);
++static void rtnl_net_notifyid(struct net *net, int cmd, int id, gfp_t gfp);
+ /* This function returns the id of a peer netns. If no id is assigned, one will
+ * be allocated and returned.
+ */
+-int peernet2id_alloc(struct net *net, struct net *peer)
++int peernet2id_alloc(struct net *net, struct net *peer, gfp_t gfp)
+ {
+ bool alloc = false, alive = false;
+ int id;
+@@ -249,7 +249,7 @@ int peernet2id_alloc(struct net *net, struct net *peer)
+ id = __peernet2id_alloc(net, peer, &alloc);
+ spin_unlock_bh(&net->nsid_lock);
+ if (alloc && id >= 0)
+- rtnl_net_notifyid(net, RTM_NEWNSID, id);
++ rtnl_net_notifyid(net, RTM_NEWNSID, id, gfp);
+ if (alive)
+ put_net(peer);
+ return id;
+@@ -495,7 +495,8 @@ static void unhash_nsid(struct net *net, struct net *last)
+ idr_remove(&tmp->netns_ids, id);
+ spin_unlock_bh(&tmp->nsid_lock);
+ if (id >= 0)
+- rtnl_net_notifyid(tmp, RTM_DELNSID, id);
++ rtnl_net_notifyid(tmp, RTM_DELNSID, id,
++ GFP_KERNEL);
+ if (tmp == last)
+ break;
+ }
+@@ -720,7 +721,7 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
+ err = alloc_netid(net, peer, nsid);
+ spin_unlock_bh(&net->nsid_lock);
+ if (err >= 0) {
+- rtnl_net_notifyid(net, RTM_NEWNSID, err);
++ rtnl_net_notifyid(net, RTM_NEWNSID, err, GFP_KERNEL);
+ err = 0;
+ } else if (err == -ENOSPC && nsid >= 0) {
+ err = -EEXIST;
+@@ -862,12 +863,12 @@ static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb)
+ return skb->len;
+ }
+
+-static void rtnl_net_notifyid(struct net *net, int cmd, int id)
++static void rtnl_net_notifyid(struct net *net, int cmd, int id, gfp_t gfp)
+ {
+ struct sk_buff *msg;
+ int err = -ENOMEM;
+
+- msg = nlmsg_new(rtnl_net_get_size(), GFP_KERNEL);
++ msg = nlmsg_new(rtnl_net_get_size(), gfp);
+ if (!msg)
+ goto out;
+
+@@ -875,7 +876,7 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id)
+ if (err < 0)
+ goto err_out;
+
+- rtnl_notify(msg, net, 0, RTNLGRP_NSID, NULL, 0);
++ rtnl_notify(msg, net, 0, RTNLGRP_NSID, NULL, gfp);
+ return;
+
+ err_out:
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index 3932eed379a4..95768a9fca06 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -1519,7 +1519,7 @@ static noinline_for_stack int nla_put_ifalias(struct sk_buff *skb,
+
+ static int rtnl_fill_link_netnsid(struct sk_buff *skb,
+ const struct net_device *dev,
+- struct net *src_net)
++ struct net *src_net, gfp_t gfp)
+ {
+ bool put_iflink = false;
+
+@@ -1527,7 +1527,7 @@ static int rtnl_fill_link_netnsid(struct sk_buff *skb,
+ struct net *link_net = dev->rtnl_link_ops->get_link_net(dev);
+
+ if (!net_eq(dev_net(dev), link_net)) {
+- int id = peernet2id_alloc(src_net, link_net);
++ int id = peernet2id_alloc(src_net, link_net, gfp);
+
+ if (nla_put_s32(skb, IFLA_LINK_NETNSID, id))
+ return -EMSGSIZE;
+@@ -1585,7 +1585,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
+ int type, u32 pid, u32 seq, u32 change,
+ unsigned int flags, u32 ext_filter_mask,
+ u32 event, int *new_nsid, int new_ifindex,
+- int tgt_netnsid)
++ int tgt_netnsid, gfp_t gfp)
+ {
+ struct ifinfomsg *ifm;
+ struct nlmsghdr *nlh;
+@@ -1677,7 +1677,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
+ goto nla_put_failure;
+ }
+
+- if (rtnl_fill_link_netnsid(skb, dev, src_net))
++ if (rtnl_fill_link_netnsid(skb, dev, src_net, gfp))
+ goto nla_put_failure;
+
+ if (new_nsid &&
+@@ -1933,7 +1933,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+ cb->nlh->nlmsg_seq, 0,
+ flags,
+ ext_filter_mask, 0, NULL, 0,
+- netnsid);
++ netnsid, GFP_KERNEL);
+
+ if (err < 0) {
+ if (likely(skb->len))
+@@ -3215,7 +3215,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
+ err = rtnl_fill_ifinfo(nskb, dev, net,
+ RTM_NEWLINK, NETLINK_CB(skb).portid,
+ nlh->nlmsg_seq, 0, 0, ext_filter_mask,
+- 0, NULL, 0, netnsid);
++ 0, NULL, 0, netnsid, GFP_KERNEL);
+ if (err < 0) {
+ /* -EMSGSIZE implies BUG in if_nlmsg_size */
+ WARN_ON(err == -EMSGSIZE);
+@@ -3325,7 +3325,7 @@ struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
+
+ err = rtnl_fill_ifinfo(skb, dev, dev_net(dev),
+ type, 0, 0, change, 0, 0, event,
+- new_nsid, new_ifindex, -1);
++ new_nsid, new_ifindex, -1, flags);
+ if (err < 0) {
+ /* -EMSGSIZE implies BUG in if_nlmsg_size() */
+ WARN_ON(err == -EMSGSIZE);
+diff --git a/net/core/sock.c b/net/core/sock.c
+index f881eea1c4a4..6c1107821776 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1005,7 +1005,7 @@ set_rcvbuf:
+ break;
+
+ case SO_INCOMING_CPU:
+- sk->sk_incoming_cpu = val;
++ WRITE_ONCE(sk->sk_incoming_cpu, val);
+ break;
+
+ case SO_CNX_ADVICE:
+@@ -1341,7 +1341,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
+ break;
+
+ case SO_INCOMING_CPU:
+- v.val = sk->sk_incoming_cpu;
++ v.val = READ_ONCE(sk->sk_incoming_cpu);
+ break;
+
+ case SO_MEMINFO:
+@@ -3483,7 +3483,7 @@ bool sk_busy_loop_end(void *p, unsigned long start_time)
+ {
+ struct sock *sk = p;
+
+- return !skb_queue_empty(&sk->sk_receive_queue) ||
++ return !skb_queue_empty_lockless(&sk->sk_receive_queue) ||
+ sk_busy_loop_timeout(sk, start_time);
+ }
+ EXPORT_SYMBOL(sk_busy_loop_end);
+diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
+index 8e08cea6f178..176bddacc16e 100644
+--- a/net/dccp/ipv4.c
++++ b/net/dccp/ipv4.c
+@@ -121,7 +121,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+ inet->inet_daddr,
+ inet->inet_sport,
+ inet->inet_dport);
+- inet->inet_id = dp->dccps_iss ^ jiffies;
++ inet->inet_id = prandom_u32();
+
+ err = dccp_connect(sk);
+ rt = NULL;
+@@ -417,7 +417,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
+ RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt));
+ newinet->mc_index = inet_iif(skb);
+ newinet->mc_ttl = ip_hdr(skb)->ttl;
+- newinet->inet_id = jiffies;
++ newinet->inet_id = prandom_u32();
+
+ if (dst == NULL && (dst = inet_csk_route_child_sock(sk, newsk, req)) == NULL)
+ goto put_and_exit;
+diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
+index 7d6ff983ba2c..0e6f32defd67 100644
+--- a/net/decnet/af_decnet.c
++++ b/net/decnet/af_decnet.c
+@@ -1213,7 +1213,7 @@ static __poll_t dn_poll(struct file *file, struct socket *sock, poll_table *wai
+ struct dn_scp *scp = DN_SK(sk);
+ __poll_t mask = datagram_poll(file, sock, wait);
+
+- if (!skb_queue_empty(&scp->other_receive_queue))
++ if (!skb_queue_empty_lockless(&scp->other_receive_queue))
+ mask |= EPOLLRDBAND;
+
+ return mask;
+diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
+index a1917025e155..46ae4dee522a 100644
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -49,7 +49,7 @@ static struct dsa_switch_tree *dsa_tree_alloc(int index)
+ dst->index = index;
+
+ INIT_LIST_HEAD(&dst->list);
+- list_add_tail(&dsa_tree_list, &dst->list);
++ list_add_tail(&dst->list, &dsa_tree_list);
+
+ kref_init(&dst->refcount);
+
+diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
+index 80107a6a2c4a..dc8517c2cdc7 100644
+--- a/net/ipv4/datagram.c
++++ b/net/ipv4/datagram.c
+@@ -77,7 +77,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
+ reuseport_has_conns(sk, true);
+ sk->sk_state = TCP_ESTABLISHED;
+ sk_set_txhash(sk);
+- inet->inet_id = jiffies;
++ inet->inet_id = prandom_u32();
+
+ sk_dst_set(sk, &rt->dst);
+ err = 0;
+diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
+index dae743b649c1..7f4ec36e5f70 100644
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -946,7 +946,7 @@ void fib_modify_prefix_metric(struct in_ifaddr *ifa, u32 new_metric)
+ if (!(dev->flags & IFF_UP) ||
+ ifa->ifa_flags & (IFA_F_SECONDARY | IFA_F_NOPREFIXROUTE) ||
+ ipv4_is_zeronet(prefix) ||
+- prefix == ifa->ifa_local || ifa->ifa_prefixlen == 32)
++ (prefix == ifa->ifa_local && ifa->ifa_prefixlen == 32))
+ return;
+
+ /* add the new */
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index f5c9ef2586de..7be966a60801 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -248,7 +248,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
+ if (sk->sk_bound_dev_if)
+ score += 4;
+ }
+- if (sk->sk_incoming_cpu == raw_smp_processor_id())
++ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
+ score++;
+ }
+ return score;
+diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
+index 0b87558f265e..758a0f86d499 100644
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -589,9 +589,9 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
+ key = &tun_info->key;
+ if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
+ goto err_free_rt;
++ if (tun_info->options_len < sizeof(*md))
++ goto err_free_rt;
+ md = ip_tunnel_info_opts(tun_info);
+- if (!md)
+- goto err_free_rt;
+
+ /* ERSPAN has fixed 8 byte GRE header */
+ version = md->version;
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 611ba174265c..647ba447bf1a 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -595,7 +595,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
+ }
+ /* This barrier is coupled with smp_wmb() in tcp_reset() */
+ smp_rmb();
+- if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
++ if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
+ mask |= EPOLLERR;
+
+ return mask;
+@@ -1948,7 +1948,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
+ if (unlikely(flags & MSG_ERRQUEUE))
+ return inet_recv_error(sk, msg, len, addr_len);
+
+- if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) &&
++ if (sk_can_busy_loop(sk) && skb_queue_empty_lockless(&sk->sk_receive_queue) &&
+ (sk->sk_state == TCP_ESTABLISHED))
+ sk_busy_loop(sk, nonblock);
+
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index b76cf96d5cfe..bfec48849735 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -305,7 +305,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+ inet->inet_daddr);
+ }
+
+- inet->inet_id = tp->write_seq ^ jiffies;
++ inet->inet_id = prandom_u32();
+
+ if (tcp_fastopen_defer_connect(sk, &err))
+ return err;
+@@ -1436,7 +1436,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
+ inet_csk(newsk)->icsk_ext_hdr_len = 0;
+ if (inet_opt)
+ inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
+- newinet->inet_id = newtp->write_seq ^ jiffies;
++ newinet->inet_id = prandom_u32();
+
+ if (!dst) {
+ dst = inet_csk_route_child_sock(sk, newsk, req);
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index aa59acc8ee0e..8877bd140a0d 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -408,7 +408,7 @@ static int compute_score(struct sock *sk, struct net *net,
+ score += 4;
+ }
+
+- if (sk->sk_incoming_cpu == raw_smp_processor_id())
++ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
+ score++;
+ return score;
+ }
+@@ -1270,6 +1270,20 @@ static void udp_set_dev_scratch(struct sk_buff *skb)
+ scratch->_tsize_state |= UDP_SKB_IS_STATELESS;
+ }
+
++static void udp_skb_csum_unnecessary_set(struct sk_buff *skb)
++{
++ /* We come here after udp_lib_checksum_complete() returned 0.
++ * This means that __skb_checksum_complete() might have
++ * set skb->csum_valid to 1.
++ * On 64bit platforms, we can set csum_unnecessary
++ * to true, but only if the skb is not shared.
++ */
++#if BITS_PER_LONG == 64
++ if (!skb_shared(skb))
++ udp_skb_scratch(skb)->csum_unnecessary = true;
++#endif
++}
++
+ static int udp_skb_truesize(struct sk_buff *skb)
+ {
+ return udp_skb_scratch(skb)->_tsize_state & ~UDP_SKB_IS_STATELESS;
+@@ -1504,10 +1518,7 @@ static struct sk_buff *__first_packet_length(struct sock *sk,
+ *total += skb->truesize;
+ kfree_skb(skb);
+ } else {
+- /* the csum related bits could be changed, refresh
+- * the scratch area
+- */
+- udp_set_dev_scratch(skb);
++ udp_skb_csum_unnecessary_set(skb);
+ break;
+ }
+ }
+@@ -1531,7 +1542,7 @@ static int first_packet_length(struct sock *sk)
+
+ spin_lock_bh(&rcvq->lock);
+ skb = __first_packet_length(sk, rcvq, &total);
+- if (!skb && !skb_queue_empty(sk_queue)) {
++ if (!skb && !skb_queue_empty_lockless(sk_queue)) {
+ spin_lock(&sk_queue->lock);
+ skb_queue_splice_tail_init(sk_queue, rcvq);
+ spin_unlock(&sk_queue->lock);
+@@ -1606,7 +1617,7 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags,
+ return skb;
+ }
+
+- if (skb_queue_empty(sk_queue)) {
++ if (skb_queue_empty_lockless(sk_queue)) {
+ spin_unlock_bh(&queue->lock);
+ goto busy_check;
+ }
+@@ -1633,7 +1644,7 @@ busy_check:
+ break;
+
+ sk_busy_loop(sk, flags & MSG_DONTWAIT);
+- } while (!skb_queue_empty(sk_queue));
++ } while (!skb_queue_empty_lockless(sk_queue));
+
+ /* sk_queue is empty, reader_queue may contain peeked packets */
+ } while (timeo &&
+@@ -2640,7 +2651,7 @@ __poll_t udp_poll(struct file *file, struct socket *sock, poll_table *wait)
+ __poll_t mask = datagram_poll(file, sock, wait);
+ struct sock *sk = sock->sk;
+
+- if (!skb_queue_empty(&udp_sk(sk)->reader_queue))
++ if (!skb_queue_empty_lockless(&udp_sk(sk)->reader_queue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+
+ /* Check for false positives due to checksum errors */
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index 3d7c7460a0c5..91d6ea937ffb 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -118,7 +118,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
+ if (sk->sk_bound_dev_if)
+ score++;
+ }
+- if (sk->sk_incoming_cpu == raw_smp_processor_id())
++ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
+ score++;
+ }
+ return score;
+diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
+index a23516e22056..dee4113f21a9 100644
+--- a/net/ipv6/ip6_gre.c
++++ b/net/ipv6/ip6_gre.c
+@@ -1000,9 +1000,9 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
+ dsfield = key->tos;
+ if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
+ goto tx_err;
+- md = ip_tunnel_info_opts(tun_info);
+- if (!md)
++ if (tun_info->options_len < sizeof(*md))
+ goto tx_err;
++ md = ip_tunnel_info_opts(tun_info);
+
+ tun_id = tunnel_id_to_key32(key->tun_id);
+ if (md->version == 1) {
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index d1c59cb6dceb..1979922bcf67 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -154,7 +154,7 @@ static int compute_score(struct sock *sk, struct net *net,
+ score++;
+ }
+
+- if (sk->sk_incoming_cpu == raw_smp_processor_id())
++ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
+ score++;
+
+ return score;
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index e0a2cb8a029f..7d766350c08e 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -566,11 +566,11 @@ static __poll_t llcp_sock_poll(struct file *file, struct socket *sock,
+ if (sk->sk_state == LLCP_LISTEN)
+ return llcp_accept_poll(sk);
+
+- if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
++ if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
+ mask |= EPOLLERR |
+ (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
+
+- if (!skb_queue_empty(&sk->sk_receive_queue))
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+
+ if (sk->sk_state == LLCP_CLOSED)
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 8e396c7c8389..c297fe8afdfe 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -1843,7 +1843,7 @@ static struct genl_family dp_datapath_genl_family __ro_after_init = {
+ /* Called with ovs_mutex or RCU read lock. */
+ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
+ struct net *net, u32 portid, u32 seq,
+- u32 flags, u8 cmd)
++ u32 flags, u8 cmd, gfp_t gfp)
+ {
+ struct ovs_header *ovs_header;
+ struct ovs_vport_stats vport_stats;
+@@ -1864,7 +1864,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
+ goto nla_put_failure;
+
+ if (!net_eq(net, dev_net(vport->dev))) {
+- int id = peernet2id_alloc(net, dev_net(vport->dev));
++ int id = peernet2id_alloc(net, dev_net(vport->dev), gfp);
+
+ if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id))
+ goto nla_put_failure;
+@@ -1905,11 +1905,12 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, struct net *net,
+ struct sk_buff *skb;
+ int retval;
+
+- skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
++ skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!skb)
+ return ERR_PTR(-ENOMEM);
+
+- retval = ovs_vport_cmd_fill_info(vport, skb, net, portid, seq, 0, cmd);
++ retval = ovs_vport_cmd_fill_info(vport, skb, net, portid, seq, 0, cmd,
++ GFP_KERNEL);
+ BUG_ON(retval < 0);
+
+ return skb;
+@@ -2042,7 +2043,7 @@ restart:
+
+ err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
+ info->snd_portid, info->snd_seq, 0,
+- OVS_VPORT_CMD_NEW);
++ OVS_VPORT_CMD_NEW, GFP_KERNEL);
+
+ if (netdev_get_fwd_headroom(vport->dev) > dp->max_headroom)
+ update_headroom(dp);
+@@ -2101,7 +2102,7 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
+
+ err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
+ info->snd_portid, info->snd_seq, 0,
+- OVS_VPORT_CMD_NEW);
++ OVS_VPORT_CMD_NEW, GFP_ATOMIC);
+ BUG_ON(err < 0);
+
+ ovs_unlock();
+@@ -2140,7 +2141,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
+
+ err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
+ info->snd_portid, info->snd_seq, 0,
+- OVS_VPORT_CMD_DEL);
++ OVS_VPORT_CMD_DEL, GFP_KERNEL);
+ BUG_ON(err < 0);
+
+ /* the vport deletion may trigger dp headroom update */
+@@ -2182,7 +2183,7 @@ static int ovs_vport_cmd_get(struct sk_buff *skb, struct genl_info *info)
+ goto exit_unlock_free;
+ err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
+ info->snd_portid, info->snd_seq, 0,
+- OVS_VPORT_CMD_NEW);
++ OVS_VPORT_CMD_NEW, GFP_ATOMIC);
+ BUG_ON(err < 0);
+ rcu_read_unlock();
+
+@@ -2218,7 +2219,8 @@ static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
+ NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq,
+ NLM_F_MULTI,
+- OVS_VPORT_CMD_NEW) < 0)
++ OVS_VPORT_CMD_NEW,
++ GFP_ATOMIC) < 0)
+ goto out;
+
+ j++;
+diff --git a/net/phonet/socket.c b/net/phonet/socket.c
+index 30187990257f..1ae629544444 100644
+--- a/net/phonet/socket.c
++++ b/net/phonet/socket.c
+@@ -351,9 +351,9 @@ static __poll_t pn_socket_poll(struct file *file, struct socket *sock,
+
+ if (sk->sk_state == TCP_CLOSE)
+ return EPOLLERR;
+- if (!skb_queue_empty(&sk->sk_receive_queue))
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+- if (!skb_queue_empty(&pn->ctrlreq_queue))
++ if (!skb_queue_empty_lockless(&pn->ctrlreq_queue))
+ mask |= EPOLLPRI;
+ if (!mask && sk->sk_state == TCP_CLOSE_WAIT)
+ return EPOLLHUP;
+diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c
+index a80fe8aa8527..c53b720674c6 100644
+--- a/net/sched/sch_hhf.c
++++ b/net/sched/sch_hhf.c
+@@ -4,11 +4,11 @@
+ * Copyright (C) 2013 Nandita Dukkipati <nanditad@google.com>
+ */
+
+-#include <linux/jhash.h>
+ #include <linux/jiffies.h>
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/vmalloc.h>
++#include <linux/siphash.h>
+ #include <net/pkt_sched.h>
+ #include <net/sock.h>
+
+@@ -125,7 +125,7 @@ struct wdrr_bucket {
+
+ struct hhf_sched_data {
+ struct wdrr_bucket buckets[WDRR_BUCKET_CNT];
+- u32 perturbation; /* hash perturbation */
++ siphash_key_t perturbation; /* hash perturbation */
+ u32 quantum; /* psched_mtu(qdisc_dev(sch)); */
+ u32 drop_overlimit; /* number of times max qdisc packet
+ * limit was hit
+@@ -263,7 +263,7 @@ static enum wdrr_bucket_idx hhf_classify(struct sk_buff *skb, struct Qdisc *sch)
+ }
+
+ /* Get hashed flow-id of the skb. */
+- hash = skb_get_hash_perturb(skb, q->perturbation);
++ hash = skb_get_hash_perturb(skb, &q->perturbation);
+
+ /* Check if this packet belongs to an already established HH flow. */
+ flow_pos = hash & HHF_BIT_MASK;
+@@ -580,7 +580,7 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt,
+
+ sch->limit = 1000;
+ q->quantum = psched_mtu(qdisc_dev(sch));
+- q->perturbation = prandom_u32();
++ get_random_bytes(&q->perturbation, sizeof(q->perturbation));
+ INIT_LIST_HEAD(&q->new_buckets);
+ INIT_LIST_HEAD(&q->old_buckets);
+
+diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
+index 7cbdad8419b7..1aa95e761671 100644
+--- a/net/sched/sch_sfb.c
++++ b/net/sched/sch_sfb.c
+@@ -22,7 +22,7 @@
+ #include <linux/errno.h>
+ #include <linux/skbuff.h>
+ #include <linux/random.h>
+-#include <linux/jhash.h>
++#include <linux/siphash.h>
+ #include <net/ip.h>
+ #include <net/pkt_sched.h>
+ #include <net/pkt_cls.h>
+@@ -49,7 +49,7 @@ struct sfb_bucket {
+ * (Section 4.4 of SFB reference : moving hash functions)
+ */
+ struct sfb_bins {
+- u32 perturbation; /* jhash perturbation */
++ siphash_key_t perturbation; /* siphash key */
+ struct sfb_bucket bins[SFB_LEVELS][SFB_NUMBUCKETS];
+ };
+
+@@ -221,7 +221,8 @@ static u32 sfb_compute_qlen(u32 *prob_r, u32 *avgpm_r, const struct sfb_sched_da
+
+ static void sfb_init_perturbation(u32 slot, struct sfb_sched_data *q)
+ {
+- q->bins[slot].perturbation = prandom_u32();
++ get_random_bytes(&q->bins[slot].perturbation,
++ sizeof(q->bins[slot].perturbation));
+ }
+
+ static void sfb_swap_slot(struct sfb_sched_data *q)
+@@ -318,9 +319,9 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ /* If using external classifiers, get result and record it. */
+ if (!sfb_classify(skb, fl, &ret, &salt))
+ goto other_drop;
+- sfbhash = jhash_1word(salt, q->bins[slot].perturbation);
++ sfbhash = siphash_1u32(salt, &q->bins[slot].perturbation);
+ } else {
+- sfbhash = skb_get_hash_perturb(skb, q->bins[slot].perturbation);
++ sfbhash = skb_get_hash_perturb(skb, &q->bins[slot].perturbation);
+ }
+
+
+@@ -356,7 +357,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ /* Inelastic flow */
+ if (q->double_buffering) {
+ sfbhash = skb_get_hash_perturb(skb,
+- q->bins[slot].perturbation);
++ &q->bins[slot].perturbation);
+ if (!sfbhash)
+ sfbhash = 1;
+ sfb_skb_cb(skb)->hashes[slot] = sfbhash;
+diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
+index 650f21463853..d483d6ba59b7 100644
+--- a/net/sched/sch_sfq.c
++++ b/net/sched/sch_sfq.c
+@@ -18,7 +18,7 @@
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/skbuff.h>
+-#include <linux/jhash.h>
++#include <linux/siphash.h>
+ #include <linux/slab.h>
+ #include <linux/vmalloc.h>
+ #include <net/netlink.h>
+@@ -121,7 +121,7 @@ struct sfq_sched_data {
+ u8 headdrop;
+ u8 maxdepth; /* limit of packets per flow */
+
+- u32 perturbation;
++ siphash_key_t perturbation;
+ u8 cur_depth; /* depth of longest slot */
+ u8 flags;
+ unsigned short scaled_quantum; /* SFQ_ALLOT_SIZE(quantum) */
+@@ -161,7 +161,7 @@ static inline struct sfq_head *sfq_dep_head(struct sfq_sched_data *q, sfq_index
+ static unsigned int sfq_hash(const struct sfq_sched_data *q,
+ const struct sk_buff *skb)
+ {
+- return skb_get_hash_perturb(skb, q->perturbation) & (q->divisor - 1);
++ return skb_get_hash_perturb(skb, &q->perturbation) & (q->divisor - 1);
+ }
+
+ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
+@@ -611,9 +611,11 @@ static void sfq_perturbation(struct timer_list *t)
+ struct sfq_sched_data *q = from_timer(q, t, perturb_timer);
+ struct Qdisc *sch = q->sch;
+ spinlock_t *root_lock = qdisc_lock(qdisc_root_sleeping(sch));
++ siphash_key_t nkey;
+
++ get_random_bytes(&nkey, sizeof(nkey));
+ spin_lock(root_lock);
+- q->perturbation = prandom_u32();
++ q->perturbation = nkey;
+ if (!q->filter_list && q->tail)
+ sfq_rehash(sch);
+ spin_unlock(root_lock);
+@@ -692,7 +694,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
+ del_timer(&q->perturb_timer);
+ if (q->perturb_period) {
+ mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
+- q->perturbation = prandom_u32();
++ get_random_bytes(&q->perturbation, sizeof(q->perturbation));
+ }
+ sch_tree_unlock(sch);
+ kfree(p);
+@@ -749,7 +751,7 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt,
+ q->quantum = psched_mtu(qdisc_dev(sch));
+ q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
+ q->perturb_period = 0;
+- q->perturbation = prandom_u32();
++ get_random_bytes(&q->perturbation, sizeof(q->perturbation));
+
+ if (opt) {
+ int err = sfq_change(sch, opt);
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 227b050cfe45..c76631552722 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -7939,7 +7939,7 @@ __poll_t sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
+ mask = 0;
+
+ /* Is there any exceptional events? */
+- if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
++ if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
+ mask |= EPOLLERR |
+ (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+@@ -7948,7 +7948,7 @@ __poll_t sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
+ mask |= EPOLLHUP;
+
+ /* Is it readable? Reconsider this code with TCP-style support. */
+- if (!skb_queue_empty(&sk->sk_receive_queue))
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+
+ /* The association is either gone or not ready. */
+@@ -8334,7 +8334,7 @@ struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags,
+ if (sk_can_busy_loop(sk)) {
+ sk_busy_loop(sk, noblock);
+
+- if (!skb_queue_empty(&sk->sk_receive_queue))
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+ continue;
+ }
+
+@@ -8777,7 +8777,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
+ newinet->inet_rcv_saddr = inet->inet_rcv_saddr;
+ newinet->inet_dport = htons(asoc->peer.port);
+ newinet->pmtudisc = inet->pmtudisc;
+- newinet->inet_id = asoc->next_tsn ^ jiffies;
++ newinet->inet_id = prandom_u32();
+
+ newinet->uc_ttl = inet->uc_ttl;
+ newinet->mc_loop = 1;
+diff --git a/net/tipc/socket.c b/net/tipc/socket.c
+index 6c91f1217dcf..5841d62ff580 100644
+--- a/net/tipc/socket.c
++++ b/net/tipc/socket.c
+@@ -731,7 +731,7 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock,
+ /* fall thru' */
+ case TIPC_LISTEN:
+ case TIPC_CONNECTING:
+- if (!skb_queue_empty(&sk->sk_receive_queue))
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+ revents |= EPOLLIN | EPOLLRDNORM;
+ break;
+ case TIPC_OPEN:
+@@ -739,7 +739,7 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock,
+ revents |= EPOLLOUT;
+ if (!tipc_sk_type_connectionless(sk))
+ break;
+- if (skb_queue_empty(&sk->sk_receive_queue))
++ if (skb_queue_empty_lockless(&sk->sk_receive_queue))
+ break;
+ revents |= EPOLLIN | EPOLLRDNORM;
+ break;
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index f601933ad728..231b6c032d2c 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -2661,7 +2661,7 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa
+ mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
+
+ /* readable? */
+- if (!skb_queue_empty(&sk->sk_receive_queue))
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+
+ /* Connection-based need to check for termination and startup */
+@@ -2690,7 +2690,7 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
+ mask = 0;
+
+ /* exceptional events? */
+- if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
++ if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
+ mask |= EPOLLERR |
+ (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
+
+@@ -2700,7 +2700,7 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
+ mask |= EPOLLHUP;
+
+ /* readable? */
+- if (!skb_queue_empty(&sk->sk_receive_queue))
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+
+ /* Connection-based need to check for termination and startup */
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 2a4613b239e0..b2724fb06bbb 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -873,7 +873,7 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+ * the queue and write as long as the socket isn't shutdown for
+ * sending.
+ */
+- if (!skb_queue_empty(&sk->sk_receive_queue) ||
++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue) ||
+ (sk->sk_shutdown & RCV_SHUTDOWN)) {
+ mask |= EPOLLIN | EPOLLRDNORM;
+ }
+diff --git a/net/wireless/Makefile b/net/wireless/Makefile
+index 1d84f91bbfb0..8158b375d170 100644
+--- a/net/wireless/Makefile
++++ b/net/wireless/Makefile
+@@ -38,6 +38,7 @@ $(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%) \
+ @(set -e; \
+ allf=""; \
+ for f in $^ ; do \
++ test -f $$f || continue;\
+ # similar to hexdump -v -e '1/1 "0x%.2x," "\n"' \
+ thisf=$$(od -An -v -tx1 < $$f | \
+ sed -e 's/ /\n/g' | \
+diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
+index e3de1ff3b6c2..439e40245bb0 100644
+--- a/sound/soc/codecs/pcm3168a.c
++++ b/sound/soc/codecs/pcm3168a.c
+@@ -24,8 +24,7 @@
+
+ #define PCM3168A_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_3LE | \
+- SNDRV_PCM_FMTBIT_S24_LE | \
+- SNDRV_PCM_FMTBIT_S32_LE)
++ SNDRV_PCM_FMTBIT_S24_LE)
+
+ #define PCM3168A_FMT_I2S 0x0
+ #define PCM3168A_FMT_LEFT_J 0x1
+diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c
+index 6f5dac09cede..21e7c430baf7 100644
+--- a/sound/soc/codecs/rt5682.c
++++ b/sound/soc/codecs/rt5682.c
+@@ -982,6 +982,16 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component,
+ {
+ struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
+
++ rt5682->hs_jack = hs_jack;
++
++ if (!hs_jack) {
++ regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2,
++ RT5682_JD1_EN_MASK, RT5682_JD1_DIS);
++ regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL,
++ RT5682_POW_JDH | RT5682_POW_JDL, 0);
++ return 0;
++ }
++
+ switch (rt5682->pdata.jd_src) {
+ case RT5682_JD1:
+ snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_2,
+@@ -1019,8 +1029,6 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component,
+ break;
+ }
+
+- rt5682->hs_jack = hs_jack;
+-
+ return 0;
+ }
+
+diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
+index 14f1b0c0d286..01acb8da2f48 100644
+--- a/sound/soc/codecs/wm8994.c
++++ b/sound/soc/codecs/wm8994.c
+@@ -537,13 +537,10 @@ static SOC_ENUM_SINGLE_DECL(dac_osr,
+ static SOC_ENUM_SINGLE_DECL(adc_osr,
+ WM8994_OVERSAMPLING, 1, osr_text);
+
+-static const struct snd_kcontrol_new wm8994_snd_controls[] = {
++static const struct snd_kcontrol_new wm8994_common_snd_controls[] = {
+ SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
+ WM8994_AIF1_ADC1_RIGHT_VOLUME,
+ 1, 119, 0, digital_tlv),
+-SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
+- WM8994_AIF1_ADC2_RIGHT_VOLUME,
+- 1, 119, 0, digital_tlv),
+ SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
+ WM8994_AIF2_ADC_RIGHT_VOLUME,
+ 1, 119, 0, digital_tlv),
+@@ -560,8 +557,6 @@ SOC_ENUM("AIF2DACR Source", aif2dacr_src),
+
+ SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
+ WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
+-SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
+- WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
+ SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME,
+ WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
+
+@@ -569,17 +564,12 @@ SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv),
+ SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv),
+
+ SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0),
+-SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
+ SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0),
+
+ WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2),
+ WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1),
+ WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0),
+
+-WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
+-WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
+-WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
+-
+ WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2),
+ WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1),
+ WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0),
+@@ -598,9 +588,6 @@ SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
+ SOC_ENUM("AIF1ADC1 HPF Mode", aif1adc1_hpf),
+ SOC_DOUBLE("AIF1ADC1 HPF Switch", WM8994_AIF1_ADC1_FILTERS, 12, 11, 1, 0),
+
+-SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf),
+-SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0),
+-
+ SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf),
+ SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0),
+
+@@ -641,6 +628,24 @@ SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF2_DAC_FILTERS_2,
+ 8, 1, 0),
+ };
+
++/* Controls not available on WM1811 */
++static const struct snd_kcontrol_new wm8994_snd_controls[] = {
++SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
++ WM8994_AIF1_ADC2_RIGHT_VOLUME,
++ 1, 119, 0, digital_tlv),
++SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
++ WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
++
++SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
++
++WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
++WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
++WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
++
++SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf),
++SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0),
++};
++
+ static const struct snd_kcontrol_new wm8994_eq_controls[] = {
+ SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0,
+ eq_tlv),
+@@ -4262,13 +4267,15 @@ static int wm8994_component_probe(struct snd_soc_component *component)
+ wm8994_handle_pdata(wm8994);
+
+ wm_hubs_add_analogue_controls(component);
+- snd_soc_add_component_controls(component, wm8994_snd_controls,
+- ARRAY_SIZE(wm8994_snd_controls));
++ snd_soc_add_component_controls(component, wm8994_common_snd_controls,
++ ARRAY_SIZE(wm8994_common_snd_controls));
+ snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
+ ARRAY_SIZE(wm8994_dapm_widgets));
+
+ switch (control->type) {
+ case WM8994:
++ snd_soc_add_component_controls(component, wm8994_snd_controls,
++ ARRAY_SIZE(wm8994_snd_controls));
+ snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
+ ARRAY_SIZE(wm8994_specific_dapm_widgets));
+ if (control->revision < 4) {
+@@ -4288,8 +4295,10 @@ static int wm8994_component_probe(struct snd_soc_component *component)
+ }
+ break;
+ case WM8958:
++ snd_soc_add_component_controls(component, wm8994_snd_controls,
++ ARRAY_SIZE(wm8994_snd_controls));
+ snd_soc_add_component_controls(component, wm8958_snd_controls,
+- ARRAY_SIZE(wm8958_snd_controls));
++ ARRAY_SIZE(wm8958_snd_controls));
+ snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
+ ARRAY_SIZE(wm8958_dapm_widgets));
+ if (control->revision < 1) {
+diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
+index ee85056a8577..b114fc7b2a95 100644
+--- a/sound/soc/codecs/wm_adsp.c
++++ b/sound/soc/codecs/wm_adsp.c
+@@ -1147,8 +1147,7 @@ static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len)
+ }
+
+ if (in) {
+- if (in & WMFW_CTL_FLAG_READABLE)
+- out |= rd;
++ out |= rd;
+ if (in & WMFW_CTL_FLAG_WRITEABLE)
+ out |= wr;
+ if (in & WMFW_CTL_FLAG_VOLATILE)
+diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
+index 11399f81c92f..b86f76c3598c 100644
+--- a/sound/soc/rockchip/rockchip_i2s.c
++++ b/sound/soc/rockchip/rockchip_i2s.c
+@@ -677,7 +677,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
+ ret = rockchip_pcm_platform_register(&pdev->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "Could not register PCM\n");
+- return ret;
++ goto err_suspend;
+ }
+
+ return 0;
+diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
+index 763c2edf52e7..1452e5153c60 100644
+--- a/tools/perf/builtin-c2c.c
++++ b/tools/perf/builtin-c2c.c
+@@ -2626,6 +2626,7 @@ static int build_cl_output(char *cl_sort, bool no_source)
+ bool add_sym = false;
+ bool add_dso = false;
+ bool add_src = false;
++ int ret = 0;
+
+ if (!buf)
+ return -ENOMEM;
+@@ -2644,7 +2645,8 @@ static int build_cl_output(char *cl_sort, bool no_source)
+ add_dso = true;
+ } else if (strcmp(tok, "offset")) {
+ pr_err("unrecognized sort token: %s\n", tok);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto err;
+ }
+ }
+
+@@ -2667,13 +2669,15 @@ static int build_cl_output(char *cl_sort, bool no_source)
+ add_sym ? "symbol," : "",
+ add_dso ? "dso," : "",
+ add_src ? "cl_srcline," : "",
+- "node") < 0)
+- return -ENOMEM;
++ "node") < 0) {
++ ret = -ENOMEM;
++ goto err;
++ }
+
+ c2c.show_src = add_src;
+-
++err:
+ free(buf);
+- return 0;
++ return ret;
+ }
+
+ static int setup_coalesce(const char *coalesce, bool no_source)
+diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
+index b63bca4b0c2a..56dd5d1476e0 100644
+--- a/tools/perf/builtin-kmem.c
++++ b/tools/perf/builtin-kmem.c
+@@ -686,6 +686,7 @@ static char *compact_gfp_flags(char *gfp_flags)
+ new = realloc(new_flags, len + strlen(cpt) + 2);
+ if (new == NULL) {
+ free(new_flags);
++ free(orig_flags);
+ return NULL;
+ }
+
+diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
+index 2f190aa8fc5f..c0885fb65767 100755
+--- a/tools/testing/selftests/net/fib_tests.sh
++++ b/tools/testing/selftests/net/fib_tests.sh
+@@ -1301,6 +1301,27 @@ ipv4_addr_metric_test()
+ fi
+ log_test $rc 0 "Prefix route with metric on link up"
+
++ # explicitly check for metric changes on edge scenarios
++ run_cmd "$IP addr flush dev dummy2"
++ run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259"
++ run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260"
++ rc=$?
++ if [ $rc -eq 0 ]; then
++ check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260"
++ rc=$?
++ fi
++ log_test $rc 0 "Modify metric of .0/24 address"
++
++ run_cmd "$IP addr flush dev dummy2"
++ run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260"
++ run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 261"
++ rc=$?
++ if [ $rc -eq 0 ]; then
++ check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261"
++ rc=$?
++ fi
++ log_test $rc 0 "Modify metric of address with peer route"
++
+ $IP li del dummy1
+ $IP li del dummy2
+ cleanup
+diff --git a/tools/testing/selftests/net/reuseport_dualstack.c b/tools/testing/selftests/net/reuseport_dualstack.c
+index fe3230c55986..fb7a59ed759e 100644
+--- a/tools/testing/selftests/net/reuseport_dualstack.c
++++ b/tools/testing/selftests/net/reuseport_dualstack.c
+@@ -129,7 +129,7 @@ static void test(int *rcv_fds, int count, int proto)
+ {
+ struct epoll_event ev;
+ int epfd, i, test_fd;
+- uint16_t test_family;
++ int test_family;
+ socklen_t len;
+
+ epfd = epoll_create(1);
+@@ -146,6 +146,7 @@ static void test(int *rcv_fds, int count, int proto)
+ send_from_v4(proto);
+
+ test_fd = receive_once(epfd, proto);
++ len = sizeof(test_family);
+ if (getsockopt(test_fd, SOL_SOCKET, SO_DOMAIN, &test_family, &len))
+ error(1, errno, "failed to read socket domain");
+ if (test_family != AF_INET)
+diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile
+index 33ced6e0ad25..869628234d54 100644
+--- a/tools/testing/selftests/powerpc/mm/Makefile
++++ b/tools/testing/selftests/powerpc/mm/Makefile
+@@ -3,6 +3,7 @@ noarg:
+ $(MAKE) -C ../
+
+ TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao segv_errors
++TEST_GEN_PROGS_EXTENDED := tlbie_test
+ TEST_GEN_FILES := tempfile
+
+ top_srcdir = ../../../../..
+@@ -15,3 +16,4 @@ $(OUTPUT)/prot_sao: ../utils.c
+ $(OUTPUT)/tempfile:
+ dd if=/dev/zero of=$@ bs=64k count=1
+
++$(OUTPUT)/tlbie_test: LDLIBS += -lpthread
+diff --git a/tools/testing/selftests/powerpc/mm/tlbie_test.c b/tools/testing/selftests/powerpc/mm/tlbie_test.c
+new file mode 100644
+index 000000000000..f85a0938ab25
+--- /dev/null
++++ b/tools/testing/selftests/powerpc/mm/tlbie_test.c
+@@ -0,0 +1,734 @@
++// SPDX-License-Identifier: GPL-2.0
++
++/*
++ * Copyright 2019, Nick Piggin, Gautham R. Shenoy, Aneesh Kumar K.V, IBM Corp.
++ */
++
++/*
++ *
++ * Test tlbie/mtpidr race. We have 4 threads doing flush/load/compare/store
++ * sequence in a loop. The same threads also rung a context switch task
++ * that does sched_yield() in loop.
++ *
++ * The snapshot thread mark the mmap area PROT_READ in between, make a copy
++ * and copy it back to the original area. This helps us to detect if any
++ * store continued to happen after we marked the memory PROT_READ.
++ */
++
++#define _GNU_SOURCE
++#include <stdio.h>
++#include <sys/mman.h>
++#include <sys/types.h>
++#include <sys/wait.h>
++#include <sys/ipc.h>
++#include <sys/shm.h>
++#include <sys/stat.h>
++#include <sys/time.h>
++#include <linux/futex.h>
++#include <unistd.h>
++#include <asm/unistd.h>
++#include <string.h>
++#include <stdlib.h>
++#include <fcntl.h>
++#include <sched.h>
++#include <time.h>
++#include <stdarg.h>
++#include <sched.h>
++#include <pthread.h>
++#include <signal.h>
++#include <sys/prctl.h>
++
++static inline void dcbf(volatile unsigned int *addr)
++{
++ __asm__ __volatile__ ("dcbf %y0; sync" : : "Z"(*(unsigned char *)addr) : "memory");
++}
++
++static void err_msg(char *msg)
++{
++
++ time_t now;
++ time(&now);
++ printf("=================================\n");
++ printf(" Error: %s\n", msg);
++ printf(" %s", ctime(&now));
++ printf("=================================\n");
++ exit(1);
++}
++
++static char *map1;
++static char *map2;
++static pid_t rim_process_pid;
++
++/*
++ * A "rim-sequence" is defined to be the sequence of the following
++ * operations performed on a memory word:
++ * 1) FLUSH the contents of that word.
++ * 2) LOAD the contents of that word.
++ * 3) COMPARE the contents of that word with the content that was
++ * previously stored at that word
++ * 4) STORE new content into that word.
++ *
++ * The threads in this test that perform the rim-sequence are termed
++ * as rim_threads.
++ */
++
++/*
++ * A "corruption" is defined to be the failed COMPARE operation in a
++ * rim-sequence.
++ *
++ * A rim_thread that detects a corruption informs about it to all the
++ * other rim_threads, and the mem_snapshot thread.
++ */
++static volatile unsigned int corruption_found;
++
++/*
++ * This defines the maximum number of rim_threads in this test.
++ *
++ * The THREAD_ID_BITS denote the number of bits required
++ * to represent the thread_ids [0..MAX_THREADS - 1].
++ * We are being a bit paranoid here and set it to 8 bits,
++ * though 6 bits suffice.
++ *
++ */
++#define MAX_THREADS 64
++#define THREAD_ID_BITS 8
++#define THREAD_ID_MASK ((1 << THREAD_ID_BITS) - 1)
++static unsigned int rim_thread_ids[MAX_THREADS];
++static pthread_t rim_threads[MAX_THREADS];
++
++
++/*
++ * Each rim_thread works on an exclusive "chunk" of size
++ * RIM_CHUNK_SIZE.
++ *
++ * The ith rim_thread works on the ith chunk.
++ *
++ * The ith chunk begins at
++ * map1 + (i * RIM_CHUNK_SIZE)
++ */
++#define RIM_CHUNK_SIZE 1024
++#define BITS_PER_BYTE 8
++#define WORD_SIZE (sizeof(unsigned int))
++#define WORD_BITS (WORD_SIZE * BITS_PER_BYTE)
++#define WORDS_PER_CHUNK (RIM_CHUNK_SIZE/WORD_SIZE)
++
++static inline char *compute_chunk_start_addr(unsigned int thread_id)
++{
++ char *chunk_start;
++
++ chunk_start = (char *)((unsigned long)map1 +
++ (thread_id * RIM_CHUNK_SIZE));
++
++ return chunk_start;
++}
++
++/*
++ * The "word-offset" of a word-aligned address inside a chunk, is
++ * defined to be the number of words that precede the address in that
++ * chunk.
++ *
++ * WORD_OFFSET_BITS denote the number of bits required to represent
++ * the word-offsets of all the word-aligned addresses of a chunk.
++ */
++#define WORD_OFFSET_BITS (__builtin_ctz(WORDS_PER_CHUNK))
++#define WORD_OFFSET_MASK ((1 << WORD_OFFSET_BITS) - 1)
++
++static inline unsigned int compute_word_offset(char *start, unsigned int *addr)
++{
++ unsigned int delta_bytes, ret;
++ delta_bytes = (unsigned long)addr - (unsigned long)start;
++
++ ret = delta_bytes/WORD_SIZE;
++
++ return ret;
++}
++
++/*
++ * A "sweep" is defined to be the sequential execution of the
++ * rim-sequence by a rim_thread on its chunk one word at a time,
++ * starting from the first word of its chunk and ending with the last
++ * word of its chunk.
++ *
++ * Each sweep of a rim_thread is uniquely identified by a sweep_id.
++ * SWEEP_ID_BITS denote the number of bits required to represent
++ * the sweep_ids of rim_threads.
++ *
++ * As to why SWEEP_ID_BITS are computed as a function of THREAD_ID_BITS,
++ * WORD_OFFSET_BITS, and WORD_BITS, see the "store-pattern" below.
++ */
++#define SWEEP_ID_BITS (WORD_BITS - (THREAD_ID_BITS + WORD_OFFSET_BITS))
++#define SWEEP_ID_MASK ((1 << SWEEP_ID_BITS) - 1)
++
++/*
++ * A "store-pattern" is the word-pattern that is stored into a word
++ * location in the 4)STORE step of the rim-sequence.
++ *
++ * In the store-pattern, we shall encode:
++ *
++ * - The thread-id of the rim_thread performing the store
++ * (The most significant THREAD_ID_BITS)
++ *
++ * - The word-offset of the address into which the store is being
++ * performed (The next WORD_OFFSET_BITS)
++ *
++ * - The sweep_id of the current sweep in which the store is
++ * being performed. (The lower SWEEP_ID_BITS)
++ *
++ * Store Pattern: 32 bits
++ * |------------------|--------------------|---------------------------------|
++ * | Thread id | Word offset | sweep_id |
++ * |------------------|--------------------|---------------------------------|
++ * THREAD_ID_BITS WORD_OFFSET_BITS SWEEP_ID_BITS
++ *
++ * In the store pattern, the (Thread-id + Word-offset) uniquely identify the
++ * address to which the store is being performed i.e,
++ * address == map1 +
++ * (Thread-id * RIM_CHUNK_SIZE) + (Word-offset * WORD_SIZE)
++ *
++ * And the sweep_id in the store pattern identifies the time when the
++ * store was performed by the rim_thread.
++ *
++ * We shall use this property in the 3)COMPARE step of the
++ * rim-sequence.
++ */
++#define SWEEP_ID_SHIFT 0
++#define WORD_OFFSET_SHIFT (SWEEP_ID_BITS)
++#define THREAD_ID_SHIFT (WORD_OFFSET_BITS + SWEEP_ID_BITS)
++
++/*
++ * Compute the store pattern for a given thread with id @tid, at
++ * location @addr in the sweep identified by @sweep_id
++ */
++static inline unsigned int compute_store_pattern(unsigned int tid,
++ unsigned int *addr,
++ unsigned int sweep_id)
++{
++ unsigned int ret = 0;
++ char *start = compute_chunk_start_addr(tid);
++ unsigned int word_offset = compute_word_offset(start, addr);
++
++ ret += (tid & THREAD_ID_MASK) << THREAD_ID_SHIFT;
++ ret += (word_offset & WORD_OFFSET_MASK) << WORD_OFFSET_SHIFT;
++ ret += (sweep_id & SWEEP_ID_MASK) << SWEEP_ID_SHIFT;
++ return ret;
++}
++
++/* Extract the thread-id from the given store-pattern */
++static inline unsigned int extract_tid(unsigned int pattern)
++{
++ unsigned int ret;
++
++ ret = (pattern >> THREAD_ID_SHIFT) & THREAD_ID_MASK;
++ return ret;
++}
++
++/* Extract the word-offset from the given store-pattern */
++static inline unsigned int extract_word_offset(unsigned int pattern)
++{
++ unsigned int ret;
++
++ ret = (pattern >> WORD_OFFSET_SHIFT) & WORD_OFFSET_MASK;
++
++ return ret;
++}
++
++/* Extract the sweep-id from the given store-pattern */
++static inline unsigned int extract_sweep_id(unsigned int pattern)
++
++{
++ unsigned int ret;
++
++ ret = (pattern >> SWEEP_ID_SHIFT) & SWEEP_ID_MASK;
++
++ return ret;
++}
++
++/************************************************************
++ * *
++ * Logging the output of the verification *
++ * *
++ ************************************************************/
++#define LOGDIR_NAME_SIZE 100
++static char logdir[LOGDIR_NAME_SIZE];
++
++static FILE *fp[MAX_THREADS];
++static const char logfilename[] ="Thread-%02d-Chunk";
++
++static inline void start_verification_log(unsigned int tid,
++ unsigned int *addr,
++ unsigned int cur_sweep_id,
++ unsigned int prev_sweep_id)
++{
++ FILE *f;
++ char logfile[30];
++ char path[LOGDIR_NAME_SIZE + 30];
++ char separator[2] = "/";
++ char *chunk_start = compute_chunk_start_addr(tid);
++ unsigned int size = RIM_CHUNK_SIZE;
++
++ sprintf(logfile, logfilename, tid);
++ strcpy(path, logdir);
++ strcat(path, separator);
++ strcat(path, logfile);
++ f = fopen(path, "w");
++
++ if (!f) {
++ err_msg("Unable to create logfile\n");
++ }
++
++ fp[tid] = f;
++
++ fprintf(f, "----------------------------------------------------------\n");
++ fprintf(f, "PID = %d\n", rim_process_pid);
++ fprintf(f, "Thread id = %02d\n", tid);
++ fprintf(f, "Chunk Start Addr = 0x%016lx\n", (unsigned long)chunk_start);
++ fprintf(f, "Chunk Size = %d\n", size);
++ fprintf(f, "Next Store Addr = 0x%016lx\n", (unsigned long)addr);
++ fprintf(f, "Current sweep-id = 0x%08x\n", cur_sweep_id);
++ fprintf(f, "Previous sweep-id = 0x%08x\n", prev_sweep_id);
++ fprintf(f, "----------------------------------------------------------\n");
++}
++
++static inline void log_anamoly(unsigned int tid, unsigned int *addr,
++ unsigned int expected, unsigned int observed)
++{
++ FILE *f = fp[tid];
++
++ fprintf(f, "Thread %02d: Addr 0x%lx: Expected 0x%x, Observed 0x%x\n",
++ tid, (unsigned long)addr, expected, observed);
++ fprintf(f, "Thread %02d: Expected Thread id = %02d\n", tid, extract_tid(expected));
++ fprintf(f, "Thread %02d: Observed Thread id = %02d\n", tid, extract_tid(observed));
++ fprintf(f, "Thread %02d: Expected Word offset = %03d\n", tid, extract_word_offset(expected));
++ fprintf(f, "Thread %02d: Observed Word offset = %03d\n", tid, extract_word_offset(observed));
++ fprintf(f, "Thread %02d: Expected sweep-id = 0x%x\n", tid, extract_sweep_id(expected));
++ fprintf(f, "Thread %02d: Observed sweep-id = 0x%x\n", tid, extract_sweep_id(observed));
++ fprintf(f, "----------------------------------------------------------\n");
++}
++
++static inline void end_verification_log(unsigned int tid, unsigned nr_anamolies)
++{
++ FILE *f = fp[tid];
++ char logfile[30];
++ char path[LOGDIR_NAME_SIZE + 30];
++ char separator[] = "/";
++
++ fclose(f);
++
++ if (nr_anamolies == 0) {
++ remove(path);
++ return;
++ }
++
++ sprintf(logfile, logfilename, tid);
++ strcpy(path, logdir);
++ strcat(path, separator);
++ strcat(path, logfile);
++
++ printf("Thread %02d chunk has %d corrupted words. For details check %s\n",
++ tid, nr_anamolies, path);
++}
++
++/*
++ * When a COMPARE step of a rim-sequence fails, the rim_thread informs
++ * everyone else via the shared_memory pointed to by
++ * corruption_found variable. On seeing this, every thread verifies the
++ * content of its chunk as follows.
++ *
++ * Suppose a thread identified with @tid was about to store (but not
++ * yet stored) to @next_store_addr in its current sweep identified
++ * @cur_sweep_id. Let @prev_sweep_id indicate the previous sweep_id.
++ *
++ * This implies that for all the addresses @addr < @next_store_addr,
++ * Thread @tid has already performed a store as part of its current
++ * sweep. Hence we expect the content of such @addr to be:
++ * |-------------------------------------------------|
++ * | tid | word_offset(addr) | cur_sweep_id |
++ * |-------------------------------------------------|
++ *
++ * Since Thread @tid is yet to perform stores on address
++ * @next_store_addr and above, we expect the content of such an
++ * address @addr to be:
++ * |-------------------------------------------------|
++ * | tid | word_offset(addr) | prev_sweep_id |
++ * |-------------------------------------------------|
++ *
++ * The verifier function @verify_chunk does this verification and logs
++ * any anamolies that it finds.
++ */
++static void verify_chunk(unsigned int tid, unsigned int *next_store_addr,
++ unsigned int cur_sweep_id,
++ unsigned int prev_sweep_id)
++{
++ unsigned int *iter_ptr;
++ unsigned int size = RIM_CHUNK_SIZE;
++ unsigned int expected;
++ unsigned int observed;
++ char *chunk_start = compute_chunk_start_addr(tid);
++
++ int nr_anamolies = 0;
++
++ start_verification_log(tid, next_store_addr,
++ cur_sweep_id, prev_sweep_id);
++
++ for (iter_ptr = (unsigned int *)chunk_start;
++ (unsigned long)iter_ptr < (unsigned long)chunk_start + size;
++ iter_ptr++) {
++ unsigned int expected_sweep_id;
++
++ if (iter_ptr < next_store_addr) {
++ expected_sweep_id = cur_sweep_id;
++ } else {
++ expected_sweep_id = prev_sweep_id;
++ }
++
++ expected = compute_store_pattern(tid, iter_ptr, expected_sweep_id);
++
++ dcbf((volatile unsigned int*)iter_ptr); //Flush before reading
++ observed = *iter_ptr;
++
++ if (observed != expected) {
++ nr_anamolies++;
++ log_anamoly(tid, iter_ptr, expected, observed);
++ }
++ }
++
++ end_verification_log(tid, nr_anamolies);
++}
++
++static void set_pthread_cpu(pthread_t th, int cpu)
++{
++ cpu_set_t run_cpu_mask;
++ struct sched_param param;
++
++ CPU_ZERO(&run_cpu_mask);
++ CPU_SET(cpu, &run_cpu_mask);
++ pthread_setaffinity_np(th, sizeof(cpu_set_t), &run_cpu_mask);
++
++ param.sched_priority = 1;
++ if (0 && sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
++ /* haven't reproduced with this setting, it kills random preemption which may be a factor */
++ fprintf(stderr, "could not set SCHED_FIFO, run as root?\n");
++ }
++}
++
++static void set_mycpu(int cpu)
++{
++ cpu_set_t run_cpu_mask;
++ struct sched_param param;
++
++ CPU_ZERO(&run_cpu_mask);
++ CPU_SET(cpu, &run_cpu_mask);
++ sched_setaffinity(0, sizeof(cpu_set_t), &run_cpu_mask);
++
++ param.sched_priority = 1;
++ if (0 && sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
++ fprintf(stderr, "could not set SCHED_FIFO, run as root?\n");
++ }
++}
++
++static volatile int segv_wait;
++
++static void segv_handler(int signo, siginfo_t *info, void *extra)
++{
++ while (segv_wait) {
++ sched_yield();
++ }
++
++}
++
++static void set_segv_handler(void)
++{
++ struct sigaction sa;
++
++ sa.sa_flags = SA_SIGINFO;
++ sa.sa_sigaction = segv_handler;
++
++ if (sigaction(SIGSEGV, &sa, NULL) == -1) {
++ perror("sigaction");
++ exit(EXIT_FAILURE);
++ }
++}
++
++int timeout = 0;
++/*
++ * This function is executed by every rim_thread.
++ *
++ * This function performs sweeps over the exclusive chunks of the
++ * rim_threads executing the rim-sequence one word at a time.
++ */
++static void *rim_fn(void *arg)
++{
++ unsigned int tid = *((unsigned int *)arg);
++
++ int size = RIM_CHUNK_SIZE;
++ char *chunk_start = compute_chunk_start_addr(tid);
++
++ unsigned int prev_sweep_id;
++ unsigned int cur_sweep_id = 0;
++
++ /* word access */
++ unsigned int pattern = cur_sweep_id;
++ unsigned int *pattern_ptr = &pattern;
++ unsigned int *w_ptr, read_data;
++
++ set_segv_handler();
++
++ /*
++ * Let us initialize the chunk:
++ *
++ * Each word-aligned address addr in the chunk,
++ * is initialized to :
++ * |-------------------------------------------------|
++ * | tid | word_offset(addr) | 0 |
++ * |-------------------------------------------------|
++ */
++ for (w_ptr = (unsigned int *)chunk_start;
++ (unsigned long)w_ptr < (unsigned long)(chunk_start) + size;
++ w_ptr++) {
++
++ *pattern_ptr = compute_store_pattern(tid, w_ptr, cur_sweep_id);
++ *w_ptr = *pattern_ptr;
++ }
++
++ while (!corruption_found && !timeout) {
++ prev_sweep_id = cur_sweep_id;
++ cur_sweep_id = cur_sweep_id + 1;
++
++ for (w_ptr = (unsigned int *)chunk_start;
++ (unsigned long)w_ptr < (unsigned long)(chunk_start) + size;
++ w_ptr++) {
++ unsigned int old_pattern;
++
++ /*
++ * Compute the pattern that we would have
++ * stored at this location in the previous
++ * sweep.
++ */
++ old_pattern = compute_store_pattern(tid, w_ptr, prev_sweep_id);
++
++ /*
++ * FLUSH:Ensure that we flush the contents of
++ * the cache before loading
++ */
++ dcbf((volatile unsigned int*)w_ptr); //Flush
++
++ /* LOAD: Read the value */
++ read_data = *w_ptr; //Load
++
++ /*
++ * COMPARE: Is it the same as what we had stored
++ * in the previous sweep ? It better be!
++ */
++ if (read_data != old_pattern) {
++ /* No it isn't! Tell everyone */
++ corruption_found = 1;
++ }
++
++ /*
++ * Before performing a store, let us check if
++ * any rim_thread has found a corruption.
++ */
++ if (corruption_found || timeout) {
++ /*
++ * Yes. Someone (including us!) has found
++ * a corruption :(
++ *
++ * Let us verify that our chunk is
++ * correct.
++ */
++ /* But first, let us allow the dust to settle down! */
++ verify_chunk(tid, w_ptr, cur_sweep_id, prev_sweep_id);
++
++ return 0;
++ }
++
++ /*
++ * Compute the new pattern that we are going
++ * to write to this location
++ */
++ *pattern_ptr = compute_store_pattern(tid, w_ptr, cur_sweep_id);
++
++ /*
++ * STORE: Now let us write this pattern into
++ * the location
++ */
++ *w_ptr = *pattern_ptr;
++ }
++ }
++
++ return NULL;
++}
++
++
++static unsigned long start_cpu = 0;
++static unsigned long nrthreads = 4;
++
++static pthread_t mem_snapshot_thread;
++
++static void *mem_snapshot_fn(void *arg)
++{
++ int page_size = getpagesize();
++ size_t size = page_size;
++ void *tmp = malloc(size);
++
++ while (!corruption_found && !timeout) {
++ /* Stop memory migration once corruption is found */
++ segv_wait = 1;
++
++ mprotect(map1, size, PROT_READ);
++
++ /*
++ * Load from the working alias (map1). Loading from map2
++ * also fails.
++ */
++ memcpy(tmp, map1, size);
++
++ /*
++ * Stores must go via map2 which has write permissions, but
++ * the corrupted data tends to be seen in the snapshot buffer,
++ * so corruption does not appear to be introduced at the
++ * copy-back via map2 alias here.
++ */
++ memcpy(map2, tmp, size);
++ /*
++ * Before releasing other threads, must ensure the copy
++ * back to
++ */
++ asm volatile("sync" ::: "memory");
++ mprotect(map1, size, PROT_READ|PROT_WRITE);
++ asm volatile("sync" ::: "memory");
++ segv_wait = 0;
++
++ usleep(1); /* This value makes a big difference */
++ }
++
++ return 0;
++}
++
++void alrm_sighandler(int sig)
++{
++ timeout = 1;
++}
++
++int main(int argc, char *argv[])
++{
++ int c;
++ int page_size = getpagesize();
++ time_t now;
++ int i, dir_error;
++ pthread_attr_t attr;
++ key_t shm_key = (key_t) getpid();
++ int shmid, run_time = 20 * 60;
++ struct sigaction sa_alrm;
++
++ snprintf(logdir, LOGDIR_NAME_SIZE,
++ "/tmp/logdir-%u", (unsigned int)getpid());
++ while ((c = getopt(argc, argv, "r:hn:l:t:")) != -1) {
++ switch(c) {
++ case 'r':
++ start_cpu = strtoul(optarg, NULL, 10);
++ break;
++ case 'h':
++ printf("%s [-r <start_cpu>] [-n <nrthreads>] [-l <logdir>] [-t <timeout>]\n", argv[0]);
++ exit(0);
++ break;
++ case 'n':
++ nrthreads = strtoul(optarg, NULL, 10);
++ break;
++ case 'l':
++ strncpy(logdir, optarg, LOGDIR_NAME_SIZE - 1);
++ break;
++ case 't':
++ run_time = strtoul(optarg, NULL, 10);
++ break;
++ default:
++ printf("invalid option\n");
++ exit(0);
++ break;
++ }
++ }
++
++ if (nrthreads > MAX_THREADS)
++ nrthreads = MAX_THREADS;
++
++ shmid = shmget(shm_key, page_size, IPC_CREAT|0666);
++ if (shmid < 0) {
++ err_msg("Failed shmget\n");
++ }
++
++ map1 = shmat(shmid, NULL, 0);
++ if (map1 == (void *) -1) {
++ err_msg("Failed shmat");
++ }
++
++ map2 = shmat(shmid, NULL, 0);
++ if (map2 == (void *) -1) {
++ err_msg("Failed shmat");
++ }
++
++ dir_error = mkdir(logdir, 0755);
++
++ if (dir_error) {
++ err_msg("Failed mkdir");
++ }
++
++ printf("start_cpu list:%lu\n", start_cpu);
++ printf("number of worker threads:%lu + 1 snapshot thread\n", nrthreads);
++ printf("Allocated address:0x%016lx + secondary map:0x%016lx\n", (unsigned long)map1, (unsigned long)map2);
++ printf("logdir at : %s\n", logdir);
++ printf("Timeout: %d seconds\n", run_time);
++
++ time(&now);
++ printf("=================================\n");
++ printf(" Starting Test\n");
++ printf(" %s", ctime(&now));
++ printf("=================================\n");
++
++ for (i = 0; i < nrthreads; i++) {
++ if (1 && !fork()) {
++ prctl(PR_SET_PDEATHSIG, SIGKILL);
++ set_mycpu(start_cpu + i);
++ for (;;)
++ sched_yield();
++ exit(0);
++ }
++ }
++
++
++ sa_alrm.sa_handler = &alrm_sighandler;
++ sigemptyset(&sa_alrm.sa_mask);
++ sa_alrm.sa_flags = 0;
++
++ if (sigaction(SIGALRM, &sa_alrm, 0) == -1) {
++ err_msg("Failed signal handler registration\n");
++ }
++
++ alarm(run_time);
++
++ pthread_attr_init(&attr);
++ for (i = 0; i < nrthreads; i++) {
++ rim_thread_ids[i] = i;
++ pthread_create(&rim_threads[i], &attr, rim_fn, &rim_thread_ids[i]);
++ set_pthread_cpu(rim_threads[i], start_cpu + i);
++ }
++
++ pthread_create(&mem_snapshot_thread, &attr, mem_snapshot_fn, map1);
++ set_pthread_cpu(mem_snapshot_thread, start_cpu + i);
++
++
++ pthread_join(mem_snapshot_thread, NULL);
++ for (i = 0; i < nrthreads; i++) {
++ pthread_join(rim_threads[i], NULL);
++ }
++
++ if (!timeout) {
++ time(&now);
++ printf("=================================\n");
++ printf(" Data Corruption Detected\n");
++ printf(" %s", ctime(&now));
++ printf(" See logfiles in %s\n", logdir);
++ printf("=================================\n");
++ return 1;
++ }
++ return 0;
++}