diff options
author | Mike Pagano <mpagano@gentoo.org> | 2024-09-04 09:52:56 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2024-09-04 09:52:56 -0400 |
commit | 1a4fca69465fa186ef137e1f68d6bd5eabe92e1f (patch) | |
tree | 08d8844734698e835123999f1f4fbba2d43e9445 | |
parent | Linux patch 5.15.165 (diff) | |
download | linux-patches-1a4fca69465fa186ef137e1f68d6bd5eabe92e1f.tar.gz linux-patches-1a4fca69465fa186ef137e1f68d6bd5eabe92e1f.tar.bz2 linux-patches-1a4fca69465fa186ef137e1f68d6bd5eabe92e1f.zip |
Linux patch 5.15.1665.15-176
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1165_linux-5.15.166.patch | 8503 |
2 files changed, 8507 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 2cbaab9c..d3f9745f 100644 --- a/0000_README +++ b/0000_README @@ -703,6 +703,10 @@ Patch: 1164_linux-5.15.165.patch From: https://www.kernel.org Desc: Linux 5.15.165 +Patch: 1165_linux-5.15.166.patch +From: https://www.kernel.org +Desc: Linux 5.15.166 + 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/1165_linux-5.15.166.patch b/1165_linux-5.15.166.patch new file mode 100644 index 00000000..fc1bc3bc --- /dev/null +++ b/1165_linux-5.15.166.patch @@ -0,0 +1,8503 @@ +diff --git a/Makefile b/Makefile +index 2105600c8d7c2..747bfa4f1a8b3 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 15 +-SUBLEVEL = 165 ++SUBLEVEL = 166 + EXTRAVERSION = + NAME = Trick or Treat + +diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c +index fdfecf0991ced..5d88ae2ae4906 100644 +--- a/arch/arm64/kernel/acpi_numa.c ++++ b/arch/arm64/kernel/acpi_numa.c +@@ -27,7 +27,7 @@ + + #include <asm/numa.h> + +-static int acpi_early_node_map[NR_CPUS] __initdata = { NUMA_NO_NODE }; ++static int acpi_early_node_map[NR_CPUS] __initdata = { [0 ... NR_CPUS - 1] = NUMA_NO_NODE }; + + int __init acpi_numa_get_nid(unsigned int cpu) + { +diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c +index be5f85b0a24de..6a9028bfd0434 100644 +--- a/arch/arm64/kernel/setup.c ++++ b/arch/arm64/kernel/setup.c +@@ -364,9 +364,6 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p) + smp_init_cpus(); + smp_build_mpidr_hash(); + +- /* Init percpu seeds for random tags after cpus are set up. */ +- kasan_init_sw_tags(); +- + #ifdef CONFIG_ARM64_SW_TTBR0_PAN + /* + * Make sure init_thread_info.ttbr0 always generates translation +diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c +index bc29cc044a4d7..47684a03c42f8 100644 +--- a/arch/arm64/kernel/smp.c ++++ b/arch/arm64/kernel/smp.c +@@ -464,6 +464,8 @@ void __init smp_prepare_boot_cpu(void) + init_gic_priority_masking(); + + kasan_init_hw_tags(); ++ /* Init percpu seeds for random tags after cpus are set up. */ ++ kasan_init_sw_tags(); + } + + static u64 __init of_get_cpu_mpidr(struct device_node *dn) +diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c +index d00170d7ddf5e..1732a804069cb 100644 +--- a/arch/arm64/kvm/sys_regs.c ++++ b/arch/arm64/kvm/sys_regs.c +@@ -30,6 +30,7 @@ + #include <trace/events/kvm.h> + + #include "sys_regs.h" ++#include "vgic/vgic.h" + + #include "trace.h" + +@@ -203,6 +204,11 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu, + { + bool g1; + ++ if (!kvm_has_gicv3(vcpu->kvm)) { ++ kvm_inject_undefined(vcpu); ++ return false; ++ } ++ + if (!p->is_write) + return read_from_write_only(vcpu, p, r); + +diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h +index 640249950acfa..2be4b0759f5bd 100644 +--- a/arch/arm64/kvm/vgic/vgic.h ++++ b/arch/arm64/kvm/vgic/vgic.h +@@ -324,4 +324,11 @@ void vgic_v4_configure_vsgis(struct kvm *kvm); + void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val); + int vgic_v4_request_vpe_irq(struct kvm_vcpu *vcpu, int irq); + ++static inline bool kvm_has_gicv3(struct kvm *kvm) ++{ ++ return (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) && ++ irqchip_in_kernel(kvm) && ++ kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3); ++} ++ + #endif +diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c +index 8ebcc298bf759..f258c5f15f903 100644 +--- a/arch/mips/kernel/cpu-probe.c ++++ b/arch/mips/kernel/cpu-probe.c +@@ -1782,12 +1782,16 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) + c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM | + MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2); + c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is incomplete */ ++ change_c0_config6(LOONGSON_CONF6_EXTIMER | LOONGSON_CONF6_INTIMER, ++ LOONGSON_CONF6_INTIMER); + break; + case PRID_IMP_LOONGSON_64G: + __cpu_name[cpu] = "ICT Loongson-3"; + set_elf_platform(cpu, "loongson3a"); + set_isa(c, MIPS_CPU_ISA_M64R2); + decode_cpucfg(c); ++ change_c0_config6(LOONGSON_CONF6_EXTIMER | LOONGSON_CONF6_INTIMER, ++ LOONGSON_CONF6_INTIMER); + break; + default: + panic("Unknown Loongson Processor ID!"); +diff --git a/arch/mips/loongson64/reset.c b/arch/mips/loongson64/reset.c +index 2a8e4cd72605d..e420800043b08 100644 +--- a/arch/mips/loongson64/reset.c ++++ b/arch/mips/loongson64/reset.c +@@ -11,7 +11,6 @@ + #include <linux/init.h> + #include <linux/kexec.h> + #include <linux/pm.h> +-#include <linux/reboot.h> + #include <linux/slab.h> + + #include <asm/bootinfo.h> +@@ -22,21 +21,36 @@ + #include <loongson.h> + #include <boot_param.h> + +-static int firmware_restart(struct sys_off_data *unusedd) ++static void loongson_restart(char *command) + { + + void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr; + + fw_restart(); +- return NOTIFY_DONE; ++ while (1) { ++ if (cpu_wait) ++ cpu_wait(); ++ } + } + +-static int firmware_poweroff(struct sys_off_data *unused) ++static void loongson_poweroff(void) + { + void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr; + + fw_poweroff(); +- return NOTIFY_DONE; ++ while (1) { ++ if (cpu_wait) ++ cpu_wait(); ++ } ++} ++ ++static void loongson_halt(void) ++{ ++ pr_notice("\n\n** You can safely turn off the power now **\n\n"); ++ while (1) { ++ if (cpu_wait) ++ cpu_wait(); ++ } + } + + #ifdef CONFIG_KEXEC +@@ -140,17 +154,9 @@ static void loongson_crash_shutdown(struct pt_regs *regs) + + static int __init mips_reboot_setup(void) + { +- if (loongson_sysconf.restart_addr) { +- register_sys_off_handler(SYS_OFF_MODE_RESTART, +- SYS_OFF_PRIO_FIRMWARE, +- firmware_restart, NULL); +- } +- +- if (loongson_sysconf.poweroff_addr) { +- register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, +- SYS_OFF_PRIO_FIRMWARE, +- firmware_poweroff, NULL); +- } ++ _machine_restart = loongson_restart; ++ _machine_halt = loongson_halt; ++ pm_power_off = loongson_poweroff; + + #ifdef CONFIG_KEXEC + kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL); +diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c +index 0cd04d936a7a1..f2fe45d3094df 100644 +--- a/arch/openrisc/kernel/setup.c ++++ b/arch/openrisc/kernel/setup.c +@@ -270,6 +270,9 @@ void calibrate_delay(void) + + void __init setup_arch(char **cmdline_p) + { ++ /* setup memblock allocator */ ++ setup_memory(); ++ + unflatten_and_copy_device_tree(); + + setup_cpuinfo(); +@@ -293,9 +296,6 @@ void __init setup_arch(char **cmdline_p) + } + #endif + +- /* setup memblock allocator */ +- setup_memory(); +- + /* paging_init() sets up the MMU and marks all pages as reserved */ + paging_init(); + +diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c +index 5d9044e65a1a6..04127377b7be8 100644 +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -518,7 +518,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) + + old_regs = set_irq_regs(regs); + local_irq_disable(); +- irq_enter(); ++ irq_enter_rcu(); + + eirr_val = mfctl(23) & cpu_eiem & per_cpu(local_ack_eiem, cpu); + if (!eirr_val) +@@ -553,7 +553,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) + #endif /* CONFIG_IRQSTACKS */ + + out: +- irq_exit(); ++ irq_exit_rcu(); + set_irq_regs(old_regs); + return; + +diff --git a/arch/powerpc/boot/simple_alloc.c b/arch/powerpc/boot/simple_alloc.c +index 65ec135d01579..bc99f75b8582d 100644 +--- a/arch/powerpc/boot/simple_alloc.c ++++ b/arch/powerpc/boot/simple_alloc.c +@@ -114,8 +114,11 @@ static void *simple_realloc(void *ptr, unsigned long size) + return ptr; + + new = simple_malloc(size); +- memcpy(new, ptr, p->size); +- simple_free(ptr); ++ if (new) { ++ memcpy(new, ptr, p->size); ++ simple_free(ptr); ++ } ++ + return new; + } + +diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c +index 7d13d2ef5a905..66de291b27d08 100644 +--- a/arch/powerpc/sysdev/xics/icp-native.c ++++ b/arch/powerpc/sysdev/xics/icp-native.c +@@ -235,6 +235,8 @@ static int __init icp_native_map_one_cpu(int hw_id, unsigned long addr, + rname = kasprintf(GFP_KERNEL, "CPU %d [0x%x] Interrupt Presentation", + cpu, hw_id); + ++ if (!rname) ++ return -ENOMEM; + if (!request_mem_region(addr, size, rname)) { + pr_warn("icp_native: Could not reserve ICP MMIO for CPU %d, interrupt server #0x%x\n", + cpu, hw_id); +diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h +index fe92a4caf5ec8..56df0bc01e3a8 100644 +--- a/arch/s390/include/asm/uv.h ++++ b/arch/s390/include/asm/uv.h +@@ -312,7 +312,10 @@ static inline int share(unsigned long addr, u16 cmd) + + if (!uv_call(0, (u64)&uvcb)) + return 0; +- return -EINVAL; ++ pr_err("%s UVC failed (rc: 0x%x, rrc: 0x%x), possible hypervisor bug.\n", ++ uvcb.header.cmd == UVC_CMD_SET_SHARED_ACCESS ? "Share" : "Unshare", ++ uvcb.header.rc, uvcb.header.rrc); ++ panic("System security cannot be guaranteed unless the system panics now.\n"); + } + + /* +diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c +index 9857cb0467268..9898582f44da8 100644 +--- a/arch/s390/kernel/early.c ++++ b/arch/s390/kernel/early.c +@@ -250,15 +250,9 @@ static inline void save_vector_registers(void) + #endif + } + +-static inline void setup_control_registers(void) ++static inline void setup_low_address_protection(void) + { +- unsigned long reg; +- +- __ctl_store(reg, 0, 0); +- reg |= CR0_LOW_ADDRESS_PROTECTION; +- reg |= CR0_EMERGENCY_SIGNAL_SUBMASK; +- reg |= CR0_EXTERNAL_CALL_SUBMASK; +- __ctl_load(reg, 0, 0); ++ __ctl_set_bit(0, 28); + } + + static inline void setup_access_registers(void) +@@ -311,7 +305,7 @@ void __init startup_init(void) + save_vector_registers(); + setup_topology(); + sclp_early_detect(); +- setup_control_registers(); ++ setup_low_address_protection(); + setup_access_registers(); + lockdep_on(); + } +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 35af70ed58fc7..48f67a69d119b 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -1003,12 +1003,12 @@ void __init smp_fill_possible_mask(void) + + void __init smp_prepare_cpus(unsigned int max_cpus) + { +- /* request the 0x1201 emergency signal external interrupt */ + if (register_external_irq(EXT_IRQ_EMERGENCY_SIG, do_ext_call_interrupt)) + panic("Couldn't request external interrupt 0x1201"); +- /* request the 0x1202 external call external interrupt */ ++ ctl_set_bit(0, 14); + if (register_external_irq(EXT_IRQ_EXTERNAL_CALL, do_ext_call_interrupt)) + panic("Couldn't request external interrupt 0x1202"); ++ ctl_set_bit(0, 13); + } + + void __init smp_prepare_boot_cpu(void) +diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c +index e6b28c689e9a9..720d99520316a 100644 +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -937,7 +937,10 @@ unsigned long arch_align_stack(unsigned long sp) + + unsigned long arch_randomize_brk(struct mm_struct *mm) + { +- return randomize_page(mm->brk, 0x02000000); ++ if (mmap_is_ia32()) ++ return randomize_page(mm->brk, SZ_32M); ++ ++ return randomize_page(mm->brk, SZ_1G); + } + + /* +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 31a0818b44406..8c85d22508990 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -5391,6 +5391,9 @@ static void ata_host_release(struct kref *kref) + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + ++ if (!ap) ++ continue; ++ + kfree(ap->pmp_link); + kfree(ap->slave_link); + kfree(ap); +diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c +index 2daf50d4cd47a..7810f974b2ca9 100644 +--- a/drivers/atm/idt77252.c ++++ b/drivers/atm/idt77252.c +@@ -1118,8 +1118,8 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) + rpp->len += skb->len; + + if (stat & SAR_RSQE_EPDU) { ++ unsigned int len, truesize; + unsigned char *l1l2; +- unsigned int len; + + l1l2 = (unsigned char *) ((unsigned long) skb->data + skb->len - 6); + +@@ -1189,14 +1189,15 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) + ATM_SKB(skb)->vcc = vcc; + __net_timestamp(skb); + ++ truesize = skb->truesize; + vcc->push(vcc, skb); + atomic_inc(&vcc->stats->rx); + +- if (skb->truesize > SAR_FB_SIZE_3) ++ if (truesize > SAR_FB_SIZE_3) + add_rx_skb(card, 3, SAR_FB_SIZE_3, 1); +- else if (skb->truesize > SAR_FB_SIZE_2) ++ else if (truesize > SAR_FB_SIZE_2) + add_rx_skb(card, 2, SAR_FB_SIZE_2, 1); +- else if (skb->truesize > SAR_FB_SIZE_1) ++ else if (truesize > SAR_FB_SIZE_1) + add_rx_skb(card, 1, SAR_FB_SIZE_1, 1); + else + add_rx_skb(card, 0, SAR_FB_SIZE_0, 1); +diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c +index 2d960a5e36793..be51528afed9d 100644 +--- a/drivers/bluetooth/hci_ldisc.c ++++ b/drivers/bluetooth/hci_ldisc.c +@@ -768,7 +768,8 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file *file, + break; + + case HCIUARTGETPROTO: +- if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) ++ if (test_bit(HCI_UART_PROTO_SET, &hu->flags) && ++ test_bit(HCI_UART_PROTO_READY, &hu->flags)) + err = hu->proto->id; + else + err = -EUNATCH; +diff --git a/drivers/char/xillybus/xillyusb.c b/drivers/char/xillybus/xillyusb.c +index 39bcbfd908b46..3a2a0fb3d928a 100644 +--- a/drivers/char/xillybus/xillyusb.c ++++ b/drivers/char/xillybus/xillyusb.c +@@ -50,6 +50,7 @@ MODULE_LICENSE("GPL v2"); + static const char xillyname[] = "xillyusb"; + + static unsigned int fifo_buf_order; ++static struct workqueue_struct *wakeup_wq; + + #define USB_VENDOR_ID_XILINX 0x03fd + #define USB_VENDOR_ID_ALTERA 0x09fb +@@ -561,10 +562,6 @@ static void cleanup_dev(struct kref *kref) + * errors if executed. The mechanism relies on that xdev->error is assigned + * a non-zero value by report_io_error() prior to queueing wakeup_all(), + * which prevents bulk_in_work() from calling process_bulk_in(). +- * +- * The fact that wakeup_all() and bulk_in_work() are queued on the same +- * workqueue makes their concurrent execution very unlikely, however the +- * kernel's API doesn't seem to ensure this strictly. + */ + + static void wakeup_all(struct work_struct *work) +@@ -619,7 +616,7 @@ static void report_io_error(struct xillyusb_dev *xdev, + + if (do_once) { + kref_get(&xdev->kref); /* xdev is used by work item */ +- queue_work(xdev->workq, &xdev->wakeup_workitem); ++ queue_work(wakeup_wq, &xdev->wakeup_workitem); + } + } + +@@ -1892,6 +1889,13 @@ static const struct file_operations xillyusb_fops = { + + static int xillyusb_setup_base_eps(struct xillyusb_dev *xdev) + { ++ struct usb_device *udev = xdev->udev; ++ ++ /* Verify that device has the two fundamental bulk in/out endpoints */ ++ if (usb_pipe_type_check(udev, usb_sndbulkpipe(udev, MSG_EP_NUM)) || ++ usb_pipe_type_check(udev, usb_rcvbulkpipe(udev, IN_EP_NUM))) ++ return -ENODEV; ++ + xdev->msg_ep = endpoint_alloc(xdev, MSG_EP_NUM | USB_DIR_OUT, + bulk_out_work, 1, 2); + if (!xdev->msg_ep) +@@ -1921,14 +1925,15 @@ static int setup_channels(struct xillyusb_dev *xdev, + __le16 *chandesc, + int num_channels) + { +- struct xillyusb_channel *chan; ++ struct usb_device *udev = xdev->udev; ++ struct xillyusb_channel *chan, *new_channels; + int i; + + chan = kcalloc(num_channels, sizeof(*chan), GFP_KERNEL); + if (!chan) + return -ENOMEM; + +- xdev->channels = chan; ++ new_channels = chan; + + for (i = 0; i < num_channels; i++, chan++) { + unsigned int in_desc = le16_to_cpu(*chandesc++); +@@ -1957,6 +1962,15 @@ static int setup_channels(struct xillyusb_dev *xdev, + */ + + if ((out_desc & 0x80) && i < 14) { /* Entry is valid */ ++ if (usb_pipe_type_check(udev, ++ usb_sndbulkpipe(udev, i + 2))) { ++ dev_err(xdev->dev, ++ "Missing BULK OUT endpoint %d\n", ++ i + 2); ++ kfree(new_channels); ++ return -ENODEV; ++ } ++ + chan->writable = 1; + chan->out_synchronous = !!(out_desc & 0x40); + chan->out_seekable = !!(out_desc & 0x20); +@@ -1966,6 +1980,7 @@ static int setup_channels(struct xillyusb_dev *xdev, + } + } + ++ xdev->channels = new_channels; + return 0; + } + +@@ -2082,9 +2097,11 @@ static int xillyusb_discovery(struct usb_interface *interface) + * just after responding with the IDT, there is no reason for any + * work item to be running now. To be sure that xdev->channels + * is updated on anything that might run in parallel, flush the +- * workqueue, which rarely does anything. ++ * device's workqueue and the wakeup work item. This rarely ++ * does anything. + */ + flush_workqueue(xdev->workq); ++ flush_work(&xdev->wakeup_workitem); + + xdev->num_channels = num_channels; + +@@ -2242,6 +2259,10 @@ static int __init xillyusb_init(void) + { + int rc = 0; + ++ wakeup_wq = alloc_workqueue(xillyname, 0, 0); ++ if (!wakeup_wq) ++ return -ENOMEM; ++ + if (LOG2_INITIAL_FIFO_BUF_SIZE > PAGE_SHIFT) + fifo_buf_order = LOG2_INITIAL_FIFO_BUF_SIZE - PAGE_SHIFT; + else +@@ -2249,12 +2270,17 @@ static int __init xillyusb_init(void) + + rc = usb_register(&xillyusb_driver); + ++ if (rc) ++ destroy_workqueue(wakeup_wq); ++ + return rc; + } + + static void __exit xillyusb_exit(void) + { + usb_deregister(&xillyusb_driver); ++ ++ destroy_workqueue(wakeup_wq); + } + + module_init(xillyusb_init); +diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c +index e1c773bb55359..22a58d35a41fa 100644 +--- a/drivers/clocksource/arm_global_timer.c ++++ b/drivers/clocksource/arm_global_timer.c +@@ -290,18 +290,17 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb, + switch (event) { + case PRE_RATE_CHANGE: + { +- int psv; ++ unsigned long psv; + +- psv = DIV_ROUND_CLOSEST(ndata->new_rate, +- gt_target_rate); +- +- if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR) ++ psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate); ++ if (!psv || ++ abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR) + return NOTIFY_BAD; + + psv--; + + /* prescaler within legal range? */ +- if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX) ++ if (psv > GT_CONTROL_PRESCALER_MAX) + return NOTIFY_BAD; + + /* +diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c +index 7ab83fe601ede..0beafcee72673 100644 +--- a/drivers/dma/dw/core.c ++++ b/drivers/dma/dw/core.c +@@ -16,6 +16,7 @@ + #include <linux/init.h> + #include <linux/interrupt.h> + #include <linux/io.h> ++#include <linux/log2.h> + #include <linux/mm.h> + #include <linux/module.h> + #include <linux/slab.h> +@@ -624,12 +625,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + struct dw_desc *prev; + struct dw_desc *first; + u32 ctllo, ctlhi; +- u8 m_master = dwc->dws.m_master; +- u8 lms = DWC_LLP_LMS(m_master); ++ u8 lms = DWC_LLP_LMS(dwc->dws.m_master); + dma_addr_t reg; + unsigned int reg_width; + unsigned int mem_width; +- unsigned int data_width = dw->pdata->data_width[m_master]; + unsigned int i; + struct scatterlist *sg; + size_t total_len = 0; +@@ -663,7 +662,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + mem = sg_dma_address(sg); + len = sg_dma_len(sg); + +- mem_width = __ffs(data_width | mem | len); ++ mem_width = __ffs(sconfig->src_addr_width | mem | len); + + slave_sg_todev_fill_desc: + desc = dwc_desc_get(dwc); +@@ -723,7 +722,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + lli_write(desc, sar, reg); + lli_write(desc, dar, mem); + lli_write(desc, ctlhi, ctlhi); +- mem_width = __ffs(data_width | mem); ++ mem_width = __ffs(sconfig->dst_addr_width | mem); + lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width)); + desc->len = dlen; + +@@ -783,17 +782,93 @@ bool dw_dma_filter(struct dma_chan *chan, void *param) + } + EXPORT_SYMBOL_GPL(dw_dma_filter); + ++static int dwc_verify_p_buswidth(struct dma_chan *chan) ++{ ++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan); ++ struct dw_dma *dw = to_dw_dma(chan->device); ++ u32 reg_width, max_width; ++ ++ if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) ++ reg_width = dwc->dma_sconfig.dst_addr_width; ++ else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) ++ reg_width = dwc->dma_sconfig.src_addr_width; ++ else /* DMA_MEM_TO_MEM */ ++ return 0; ++ ++ max_width = dw->pdata->data_width[dwc->dws.p_master]; ++ ++ /* Fall-back to 1-byte transfer width if undefined */ ++ if (reg_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) ++ reg_width = DMA_SLAVE_BUSWIDTH_1_BYTE; ++ else if (!is_power_of_2(reg_width) || reg_width > max_width) ++ return -EINVAL; ++ else /* bus width is valid */ ++ return 0; ++ ++ /* Update undefined addr width value */ ++ if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) ++ dwc->dma_sconfig.dst_addr_width = reg_width; ++ else /* DMA_DEV_TO_MEM */ ++ dwc->dma_sconfig.src_addr_width = reg_width; ++ ++ return 0; ++} ++ ++static int dwc_verify_m_buswidth(struct dma_chan *chan) ++{ ++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan); ++ struct dw_dma *dw = to_dw_dma(chan->device); ++ u32 reg_width, reg_burst, mem_width; ++ ++ mem_width = dw->pdata->data_width[dwc->dws.m_master]; ++ ++ /* ++ * It's possible to have a data portion locked in the DMA FIFO in case ++ * of the channel suspension. Subsequent channel disabling will cause ++ * that data silent loss. In order to prevent that maintain the src and ++ * dst transfer widths coherency by means of the relation: ++ * (CTLx.SRC_TR_WIDTH * CTLx.SRC_MSIZE >= CTLx.DST_TR_WIDTH) ++ * Look for the details in the commit message that brings this change. ++ * ++ * Note the DMA configs utilized in the calculations below must have ++ * been verified to have correct values by this method call. ++ */ ++ if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) { ++ reg_width = dwc->dma_sconfig.dst_addr_width; ++ if (mem_width < reg_width) ++ return -EINVAL; ++ ++ dwc->dma_sconfig.src_addr_width = mem_width; ++ } else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) { ++ reg_width = dwc->dma_sconfig.src_addr_width; ++ reg_burst = rounddown_pow_of_two(dwc->dma_sconfig.src_maxburst); ++ ++ dwc->dma_sconfig.dst_addr_width = min(mem_width, reg_width * reg_burst); ++ } ++ ++ return 0; ++} ++ + static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig) + { + struct dw_dma_chan *dwc = to_dw_dma_chan(chan); + struct dw_dma *dw = to_dw_dma(chan->device); ++ int ret; + + memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig)); + + dwc->dma_sconfig.src_maxburst = +- clamp(dwc->dma_sconfig.src_maxburst, 0U, dwc->max_burst); ++ clamp(dwc->dma_sconfig.src_maxburst, 1U, dwc->max_burst); + dwc->dma_sconfig.dst_maxburst = +- clamp(dwc->dma_sconfig.dst_maxburst, 0U, dwc->max_burst); ++ clamp(dwc->dma_sconfig.dst_maxburst, 1U, dwc->max_burst); ++ ++ ret = dwc_verify_p_buswidth(chan); ++ if (ret) ++ return ret; ++ ++ ret = dwc_verify_m_buswidth(chan); ++ if (ret) ++ return ret; + + dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst); + dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +index e7a010b7ca1f8..347e97b4b51b8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +@@ -413,16 +413,24 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, + + switch (args->in.op) { + case AMDGPU_CTX_OP_ALLOC_CTX: ++ if (args->in.flags) ++ return -EINVAL; + r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id); + args->out.alloc.ctx_id = id; + break; + case AMDGPU_CTX_OP_FREE_CTX: ++ if (args->in.flags) ++ return -EINVAL; + r = amdgpu_ctx_free(fpriv, id); + break; + case AMDGPU_CTX_OP_QUERY_STATE: ++ if (args->in.flags) ++ return -EINVAL; + r = amdgpu_ctx_query(adev, fpriv, id, &args->out); + break; + case AMDGPU_CTX_OP_QUERY_STATE2: ++ if (args->in.flags) ++ return -EINVAL; + r = amdgpu_ctx_query2(adev, fpriv, id, &args->out); + break; + default: +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +index 8e8dee9fac9f6..9f7450a8d004d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +@@ -733,7 +733,8 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx) + uint32_t created = 0; + uint32_t allocated = 0; + uint32_t tmp, handle = 0; +- uint32_t *size = &tmp; ++ uint32_t dummy = 0xffffffff; ++ uint32_t *size = &dummy; + unsigned idx; + int i, r = 0; + +diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c +index 85967a5570cb4..df52190b7e8bc 100644 +--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c +@@ -557,11 +557,11 @@ void jpeg_v2_0_dec_ring_emit_ib(struct amdgpu_ring *ring, + + amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET, + 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, (vmid | (vmid << 4))); ++ amdgpu_ring_write(ring, (vmid | (vmid << 4) | (vmid << 8))); + + amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET, + 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, (vmid | (vmid << 4))); ++ amdgpu_ring_write(ring, (vmid | (vmid << 4) | (vmid << 8))); + + amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET, + 0, 0, PACKETJ_TYPE0)); +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +index 88f9e1aa51f8f..34c466e8eee98 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +@@ -1290,7 +1290,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, + goto err_unlock; + } + offset = amdgpu_amdkfd_get_mmio_remap_phys_addr(dev->kgd); +- if (!offset) { ++ if (!offset || (PAGE_SIZE > 4096)) { + err = -ENOMEM; + goto err_unlock; + } +@@ -2029,6 +2029,9 @@ static int kfd_mmio_mmap(struct kfd_dev *dev, struct kfd_process *process, + if (vma->vm_end - vma->vm_start != PAGE_SIZE) + return -EINVAL; + ++ if (PAGE_SIZE > 4096) ++ return -EINVAL; ++ + address = amdgpu_amdkfd_get_mmio_remap_phys_addr(dev->kgd); + + vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE | +diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c +index ca3842f719842..82071835ec9ed 100644 +--- a/drivers/gpu/drm/lima/lima_gp.c ++++ b/drivers/gpu/drm/lima/lima_gp.c +@@ -166,6 +166,11 @@ static void lima_gp_task_run(struct lima_sched_pipe *pipe, + gp_write(LIMA_GP_CMD, cmd); + } + ++static int lima_gp_bus_stop_poll(struct lima_ip *ip) ++{ ++ return !!(gp_read(LIMA_GP_STATUS) & LIMA_GP_STATUS_BUS_STOPPED); ++} ++ + static int lima_gp_hard_reset_poll(struct lima_ip *ip) + { + gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0xC01A0000); +@@ -179,6 +184,13 @@ static int lima_gp_hard_reset(struct lima_ip *ip) + + gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0xC0FFE000); + gp_write(LIMA_GP_INT_MASK, 0); ++ ++ gp_write(LIMA_GP_CMD, LIMA_GP_CMD_STOP_BUS); ++ ret = lima_poll_timeout(ip, lima_gp_bus_stop_poll, 10, 100); ++ if (ret) { ++ dev_err(dev->dev, "%s bus stop timeout\n", lima_ip_name(ip)); ++ return ret; ++ } + gp_write(LIMA_GP_CMD, LIMA_GP_CMD_RESET); + ret = lima_poll_timeout(ip, lima_gp_hard_reset_poll, 10, 100); + if (ret) { +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +index 170b3e9dd4b00..73aef80a8556a 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +@@ -32,24 +32,14 @@ + * @fmt: Pointer to format string + */ + #define DPU_DEBUG(fmt, ...) \ +- do { \ +- if (drm_debug_enabled(DRM_UT_KMS)) \ +- DRM_DEBUG(fmt, ##__VA_ARGS__); \ +- else \ +- pr_debug(fmt, ##__VA_ARGS__); \ +- } while (0) ++ DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__) + + /** + * DPU_DEBUG_DRIVER - macro for hardware driver logging + * @fmt: Pointer to format string + */ + #define DPU_DEBUG_DRIVER(fmt, ...) \ +- do { \ +- if (drm_debug_enabled(DRM_UT_DRIVER)) \ +- DRM_ERROR(fmt, ##__VA_ARGS__); \ +- else \ +- pr_debug(fmt, ##__VA_ARGS__); \ +- } while (0) ++ DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__) + + #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) + #define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__) +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +index 9c30ab106b0a1..3ee9a92ffed57 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +@@ -906,6 +906,9 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, + new_state->fb, &layout); + if (ret) { + DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret); ++ if (pstate->aspace) ++ msm_framebuffer_cleanup(new_state->fb, pstate->aspace, ++ pstate->needs_dirtyfb); + return ret; + } + +diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c +index 854173df67018..85f86afc55052 100644 +--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c ++++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c +@@ -1237,6 +1237,8 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl, + link_info.rate = ctrl->link->link_params.rate; + link_info.capabilities = DP_LINK_CAP_ENHANCED_FRAMING; + ++ dp_link_reset_phy_params_vx_px(ctrl->link); ++ + dp_aux_link_configure(ctrl->aux, &link_info); + drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET, + &encoding, 1); +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 0504bdd465013..5988d9c67a305 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -894,7 +894,15 @@ + #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 + #define USB_DEVICE_ID_MS_POWER_COVER 0x07da + #define USB_DEVICE_ID_MS_SURFACE3_COVER 0x07de +-#define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd ++/* ++ * For a description of the Xbox controller models, refer to: ++ * https://en.wikipedia.org/wiki/Xbox_Wireless_Controller#Summary ++ */ ++#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708 0x02fd ++#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708_BLE 0x0b20 ++#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1914 0x0b13 ++#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797 0x0b05 ++#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797_BLE 0x0b22 + #define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb + #define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0 + #define USB_DEVICE_ID_MS_MOUSE_0783 0x0783 +diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c +index 071fd093a5f4e..9345e2bfd56ed 100644 +--- a/drivers/hid/hid-microsoft.c ++++ b/drivers/hid/hid-microsoft.c +@@ -446,7 +446,16 @@ static const struct hid_device_id ms_devices[] = { + .driver_data = MS_PRESENTER }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, 0x091B), + .driver_data = MS_SURFACE_DIAL }, +- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER), ++ ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708), ++ .driver_data = MS_QUIRK_FF }, ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708_BLE), ++ .driver_data = MS_QUIRK_FF }, ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1914), ++ .driver_data = MS_QUIRK_FF }, ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797), ++ .driver_data = MS_QUIRK_FF }, ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797_BLE), + .driver_data = MS_QUIRK_FF }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS), + .driver_data = MS_QUIRK_FF }, +diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c +index 11d15c83f5021..438c9f6d21d90 100644 +--- a/drivers/hid/wacom_wac.c ++++ b/drivers/hid/wacom_wac.c +@@ -1924,12 +1924,14 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage, + int fmax = field->logical_maximum; + unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); + int resolution_code = code; +- int resolution = hidinput_calc_abs_res(field, resolution_code); ++ int resolution; + + if (equivalent_usage == HID_DG_TWIST) { + resolution_code = ABS_RZ; + } + ++ resolution = hidinput_calc_abs_res(field, resolution_code); ++ + if (equivalent_usage == HID_GD_X) { + fmin += features->offset_left; + fmax -= features->offset_right; +diff --git a/drivers/hwmon/ltc2992.c b/drivers/hwmon/ltc2992.c +index 009a0a5af9236..838b679a12d4f 100644 +--- a/drivers/hwmon/ltc2992.c ++++ b/drivers/hwmon/ltc2992.c +@@ -912,8 +912,14 @@ static int ltc2992_parse_dt(struct ltc2992_state *st) + } + + ret = fwnode_property_read_u32(child, "shunt-resistor-micro-ohms", &val); +- if (!ret) ++ if (!ret) { ++ if (!val) { ++ fwnode_handle_put(child); ++ return dev_err_probe(&st->client->dev, -EINVAL, ++ "shunt resistor value cannot be zero\n"); ++ } + st->r_sense_uohm[addr] = val; ++ } + } + + return 0; +diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c +index 78b84445ee6ab..1d3dbc1bfc259 100644 +--- a/drivers/i2c/busses/i2c-riic.c ++++ b/drivers/i2c/busses/i2c-riic.c +@@ -319,7 +319,7 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t) + * frequency with only 62 clock ticks max (31 high, 31 low). + * Aim for a duty of 60% LOW, 40% HIGH. + */ +- total_ticks = DIV_ROUND_UP(rate, t->bus_freq_hz); ++ total_ticks = DIV_ROUND_UP(rate, t->bus_freq_hz ?: 1); + + for (cks = 0; cks < 7; cks++) { + /* +diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c +index dd2dc00399600..5e3f0ee1cfd0e 100644 +--- a/drivers/i3c/master/mipi-i3c-hci/dma.c ++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c +@@ -345,6 +345,8 @@ static void hci_dma_unmap_xfer(struct i3c_hci *hci, + + for (i = 0; i < n; i++) { + xfer = xfer_list + i; ++ if (!xfer->data) ++ continue; + dma_unmap_single(&hci->master.dev, + xfer->data_dma, xfer->data_len, + xfer->rnw ? DMA_FROM_DEVICE : DMA_TO_DEVICE); +@@ -450,10 +452,9 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci, + /* + * We're deep in it if ever this condition is ever met. + * Hardware might still be writing to memory, etc. +- * Better suspend the world than risking silent corruption. + */ + dev_crit(&hci->master.dev, "unable to abort the ring\n"); +- BUG(); ++ WARN_ON(1); + } + + for (i = 0; i < n; i++) { +diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c +index b69dd618146ef..c6d9a828050df 100644 +--- a/drivers/infiniband/hw/hfi1/chip.c ++++ b/drivers/infiniband/hw/hfi1/chip.c +@@ -13182,15 +13182,16 @@ static void read_mod_write(struct hfi1_devdata *dd, u16 src, u64 bits, + { + u64 reg; + u16 idx = src / BITS_PER_REGISTER; ++ unsigned long flags; + +- spin_lock(&dd->irq_src_lock); ++ spin_lock_irqsave(&dd->irq_src_lock, flags); + reg = read_csr(dd, CCE_INT_MASK + (8 * idx)); + if (set) + reg |= bits; + else + reg &= ~bits; + write_csr(dd, CCE_INT_MASK + (8 * idx), reg); +- spin_unlock(&dd->irq_src_lock); ++ spin_unlock_irqrestore(&dd->irq_src_lock, flags); + } + + /** +diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c +index 4745f33d7104a..7f0f3ce8f1151 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs.c +@@ -255,7 +255,7 @@ static int create_cq(struct rtrs_con *con, int cq_vector, int nr_cqe, + static int create_qp(struct rtrs_con *con, struct ib_pd *pd, + u32 max_send_wr, u32 max_recv_wr, u32 max_sge) + { +- struct ib_qp_init_attr init_attr = {NULL}; ++ struct ib_qp_init_attr init_attr = {}; + struct rdma_cm_id *cm_id = con->cm_id; + int ret; + +diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c +index 44fe6f2f063ce..d0f8c31d7cc04 100644 +--- a/drivers/input/input-mt.c ++++ b/drivers/input/input-mt.c +@@ -45,6 +45,9 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, + return 0; + if (mt) + return mt->num_slots != num_slots ? -EINVAL : 0; ++ /* Arbitrary limit for avoiding too large memory allocation. */ ++ if (num_slots > 1024) ++ return -EINVAL; + + mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL); + if (!mt) +diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c +index fa89e590c1333..3fa6c71843261 100644 +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -4491,8 +4491,6 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq + struct page *vprop_page; + int base, nr_ids, i, err = 0; + +- BUG_ON(!vm); +- + bitmap = its_lpi_alloc(roundup_pow_of_two(nr_irqs), &base, &nr_ids); + if (!bitmap) + return -ENOMEM; +diff --git a/drivers/md/dm-clone-metadata.c b/drivers/md/dm-clone-metadata.c +index c43d55672bce0..47c1fa7aad8b5 100644 +--- a/drivers/md/dm-clone-metadata.c ++++ b/drivers/md/dm-clone-metadata.c +@@ -465,11 +465,6 @@ static void __destroy_persistent_data_structures(struct dm_clone_metadata *cmd) + + /*---------------------------------------------------------------------------*/ + +-static size_t bitmap_size(unsigned long nr_bits) +-{ +- return BITS_TO_LONGS(nr_bits) * sizeof(long); +-} +- + static int __dirty_map_init(struct dirty_map *dmap, unsigned long nr_words, + unsigned long nr_regions) + { +diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c +index c1bcc857c1b60..fb0987e716116 100644 +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -1151,8 +1151,26 @@ static int do_resume(struct dm_ioctl *param) + suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG; + if (param->flags & DM_NOFLUSH_FLAG) + suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; +- if (!dm_suspended_md(md)) +- dm_suspend(md, suspend_flags); ++ if (!dm_suspended_md(md)) { ++ r = dm_suspend(md, suspend_flags); ++ if (r) { ++ down_write(&_hash_lock); ++ hc = dm_get_mdptr(md); ++ if (hc && !hc->new_map) { ++ hc->new_map = new_map; ++ new_map = NULL; ++ } else { ++ r = -ENXIO; ++ } ++ up_write(&_hash_lock); ++ if (new_map) { ++ dm_sync_table(md); ++ dm_table_destroy(new_map); ++ } ++ dm_put(md); ++ return r; ++ } ++ } + + old_size = dm_get_size(md); + old_map = dm_swap_table(md, new_map); +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index fd9bb8b53219a..8199166ca8620 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -2255,7 +2255,7 @@ static int dm_wait_for_bios_completion(struct mapped_device *md, unsigned int ta + break; + + if (signal_pending_state(task_state, current)) { +- r = -EINTR; ++ r = -ERESTARTSYS; + break; + } + +@@ -2280,7 +2280,7 @@ static int dm_wait_for_completion(struct mapped_device *md, unsigned int task_st + break; + + if (signal_pending_state(task_state, current)) { +- r = -EINTR; ++ r = -ERESTARTSYS; + break; + } + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 5b6c366587d54..332458ad96637 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -7589,11 +7589,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, + + mddev = bdev->bd_disk->private_data; + +- if (!mddev) { +- BUG(); +- goto out; +- } +- + /* Some actions do not requires the mutex */ + switch (cmd) { + case GET_ARRAY_INFO: +diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c +index 392ae26134a4e..c8451ffd23a35 100644 +--- a/drivers/md/persistent-data/dm-space-map-metadata.c ++++ b/drivers/md/persistent-data/dm-space-map-metadata.c +@@ -274,7 +274,7 @@ static void sm_metadata_destroy(struct dm_space_map *sm) + { + struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); + +- kfree(smm); ++ kvfree(smm); + } + + static int sm_metadata_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count) +@@ -768,7 +768,7 @@ struct dm_space_map *dm_sm_metadata_init(void) + { + struct sm_metadata *smm; + +- smm = kmalloc(sizeof(*smm), GFP_KERNEL); ++ smm = kvmalloc(sizeof(*smm), GFP_KERNEL); + if (!smm) + return ERR_PTR(-ENOMEM); + +diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c +index fea62bce97468..d76ac3ec93c2f 100644 +--- a/drivers/media/dvb-core/dvb_frontend.c ++++ b/drivers/media/dvb-core/dvb_frontend.c +@@ -2160,7 +2160,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd, + if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) + return -EINVAL; + +- tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp)); ++ tvp = memdup_array_user(compat_ptr(tvps->props), ++ tvps->num, sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + +@@ -2191,7 +2192,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd, + if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) + return -EINVAL; + +- tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp)); ++ tvp = memdup_array_user(compat_ptr(tvps->props), ++ tvps->num, sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + +@@ -2368,7 +2370,8 @@ static int dvb_get_property(struct dvb_frontend *fe, struct file *file, + if (!tvps->num || tvps->num > DTV_IOCTL_MAX_MSGS) + return -EINVAL; + +- tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp)); ++ tvp = memdup_array_user((void __user *)tvps->props, ++ tvps->num, sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + +@@ -2446,7 +2449,8 @@ static int dvb_frontend_handle_ioctl(struct file *file, + if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) + return -EINVAL; + +- tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp)); ++ tvp = memdup_array_user((void __user *)tvps->props, ++ tvps->num, sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + +diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c +index 6851e01da1c5b..7a696aea52f10 100644 +--- a/drivers/media/pci/cx23885/cx23885-video.c ++++ b/drivers/media/pci/cx23885/cx23885-video.c +@@ -1354,6 +1354,10 @@ int cx23885_video_register(struct cx23885_dev *dev) + /* register Video device */ + dev->video_dev = cx23885_vdev_init(dev, dev->pci, + &cx23885_video_template, "video"); ++ if (!dev->video_dev) { ++ err = -ENOMEM; ++ goto fail_unreg; ++ } + dev->video_dev->queue = &dev->vb2_vidq; + dev->video_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | + V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE; +@@ -1382,6 +1386,10 @@ int cx23885_video_register(struct cx23885_dev *dev) + /* register VBI device */ + dev->vbi_dev = cx23885_vdev_init(dev, dev->pci, + &cx23885_vbi_template, "vbi"); ++ if (!dev->vbi_dev) { ++ err = -ENOMEM; ++ goto fail_unreg; ++ } + dev->vbi_dev->queue = &dev->vb2_vbiq; + dev->vbi_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | + V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE; +diff --git a/drivers/media/pci/solo6x10/solo6x10-offsets.h b/drivers/media/pci/solo6x10/solo6x10-offsets.h +index f414ee1316f29..fdbb817e63601 100644 +--- a/drivers/media/pci/solo6x10/solo6x10-offsets.h ++++ b/drivers/media/pci/solo6x10/solo6x10-offsets.h +@@ -57,16 +57,16 @@ + #define SOLO_MP4E_EXT_ADDR(__solo) \ + (SOLO_EREF_EXT_ADDR(__solo) + SOLO_EREF_EXT_AREA(__solo)) + #define SOLO_MP4E_EXT_SIZE(__solo) \ +- max((__solo->nr_chans * 0x00080000), \ +- min(((__solo->sdram_size - SOLO_MP4E_EXT_ADDR(__solo)) - \ +- __SOLO_JPEG_MIN_SIZE(__solo)), 0x00ff0000)) ++ clamp(__solo->sdram_size - SOLO_MP4E_EXT_ADDR(__solo) - \ ++ __SOLO_JPEG_MIN_SIZE(__solo), \ ++ __solo->nr_chans * 0x00080000, 0x00ff0000) + + #define __SOLO_JPEG_MIN_SIZE(__solo) (__solo->nr_chans * 0x00080000) + #define SOLO_JPEG_EXT_ADDR(__solo) \ + (SOLO_MP4E_EXT_ADDR(__solo) + SOLO_MP4E_EXT_SIZE(__solo)) + #define SOLO_JPEG_EXT_SIZE(__solo) \ +- max(__SOLO_JPEG_MIN_SIZE(__solo), \ +- min((__solo->sdram_size - SOLO_JPEG_EXT_ADDR(__solo)), 0x00ff0000)) ++ clamp(__solo->sdram_size - SOLO_JPEG_EXT_ADDR(__solo), \ ++ __SOLO_JPEG_MIN_SIZE(__solo), 0x00ff0000) + + #define SOLO_SDRAM_END(__solo) \ + (SOLO_JPEG_EXT_ADDR(__solo) + SOLO_JPEG_EXT_SIZE(__solo)) +diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c +index 055513a7301f1..656c17986c1c3 100644 +--- a/drivers/media/platform/qcom/venus/pm_helpers.c ++++ b/drivers/media/platform/qcom/venus/pm_helpers.c +@@ -870,7 +870,7 @@ static int vcodec_domains_get(struct venus_core *core) + pd = dev_pm_domain_attach_by_name(dev, + res->vcodec_pmdomains[i]); + if (IS_ERR_OR_NULL(pd)) +- return PTR_ERR(pd) ? : -ENODATA; ++ return pd ? PTR_ERR(pd) : -ENODATA; + core->pmdomains[i] = pd; + } + +diff --git a/drivers/media/radio/radio-isa.c b/drivers/media/radio/radio-isa.c +index c591c0851fa28..ad49151f5ff09 100644 +--- a/drivers/media/radio/radio-isa.c ++++ b/drivers/media/radio/radio-isa.c +@@ -36,7 +36,7 @@ static int radio_isa_querycap(struct file *file, void *priv, + + strscpy(v->driver, isa->drv->driver.driver.name, sizeof(v->driver)); + strscpy(v->card, isa->drv->card, sizeof(v->card)); +- snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name); ++ snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", dev_name(isa->v4l2_dev.dev)); + return 0; + } + +diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c +index ffec26a99313b..5c387d32c078f 100644 +--- a/drivers/memory/stm32-fmc2-ebi.c ++++ b/drivers/memory/stm32-fmc2-ebi.c +@@ -179,8 +179,11 @@ static int stm32_fmc2_ebi_check_mux(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr; ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + + if (bcr & FMC2_BCR_MTYP) + return 0; +@@ -193,8 +196,11 @@ static int stm32_fmc2_ebi_check_waitcfg(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + + if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN) + return 0; +@@ -207,8 +213,11 @@ static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr; ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + + if (bcr & FMC2_BCR_BURSTEN) + return 0; +@@ -221,8 +230,11 @@ static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr; ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + + if (!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) + return 0; +@@ -235,8 +247,11 @@ static int stm32_fmc2_ebi_check_cpsize(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + + if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN) + return 0; +@@ -249,12 +264,18 @@ static int stm32_fmc2_ebi_check_address_hold(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr, bxtr, val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); ++ int ret; ++ ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (prop->reg_type == FMC2_REG_BWTR) +- regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); ++ ret = regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); + else +- regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); ++ ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); ++ if (ret) ++ return ret; + + if ((!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) && + ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN)) +@@ -268,12 +289,19 @@ static int stm32_fmc2_ebi_check_clk_period(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr, bcr1; ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); +- if (cs) +- regmap_read(ebi->regmap, FMC2_BCR1, &bcr1); +- else ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; ++ ++ if (cs) { ++ ret = regmap_read(ebi->regmap, FMC2_BCR1, &bcr1); ++ if (ret) ++ return ret; ++ } else { + bcr1 = bcr; ++ } + + if (bcr & FMC2_BCR_BURSTEN && (!cs || !(bcr1 & FMC2_BCR1_CCLKEN))) + return 0; +@@ -305,12 +333,18 @@ static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm32_fmc2_ebi *ebi, + { + u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup); + u32 bcr, btr, clk_period; ++ int ret; ++ ++ ret = regmap_read(ebi->regmap, FMC2_BCR1, &bcr); ++ if (ret) ++ return ret; + +- regmap_read(ebi->regmap, FMC2_BCR1, &bcr); + if (bcr & FMC2_BCR1_CCLKEN || !cs) +- regmap_read(ebi->regmap, FMC2_BTR1, &btr); ++ ret = regmap_read(ebi->regmap, FMC2_BTR1, &btr); + else +- regmap_read(ebi->regmap, FMC2_BTR(cs), &btr); ++ ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &btr); ++ if (ret) ++ return ret; + + clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1; + +@@ -569,11 +603,16 @@ static int stm32_fmc2_ebi_set_address_setup(struct stm32_fmc2_ebi *ebi, + if (ret) + return ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; ++ + if (prop->reg_type == FMC2_REG_BWTR) +- regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); ++ ret = regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); + else +- regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); ++ ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); ++ if (ret) ++ return ret; + + if ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN) + val = clamp_val(setup, 1, FMC2_BXTR_ADDSET_MAX); +@@ -691,11 +730,14 @@ static int stm32_fmc2_ebi_set_max_low_pulse(struct stm32_fmc2_ebi *ebi, + int cs, u32 setup) + { + u32 old_val, new_val, pcscntr; ++ int ret; + + if (setup < 1) + return 0; + +- regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr); ++ ret = regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr); ++ if (ret) ++ return ret; + + /* Enable counter for the bank */ + regmap_update_bits(ebi->regmap, FMC2_PCSCNTR, +@@ -942,17 +984,20 @@ static void stm32_fmc2_ebi_disable_bank(struct stm32_fmc2_ebi *ebi, int cs) + regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_MBKEN, 0); + } + +-static void stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi) ++static int stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi) + { + unsigned int cs; ++ int ret; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { +- regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]); +- regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]); +- regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]); ++ ret |= regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]); ++ ret |= regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]); ++ if (ret) ++ return ret; + } + +- regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr); ++ return regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr); + } + + static void stm32_fmc2_ebi_set_setup(struct stm32_fmc2_ebi *ebi) +@@ -981,22 +1026,29 @@ static void stm32_fmc2_ebi_disable_banks(struct stm32_fmc2_ebi *ebi) + } + + /* NWAIT signal can not be connected to EBI controller and NAND controller */ +-static bool stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi) ++static int stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi) + { ++ struct device *dev = ebi->dev; + unsigned int cs; + u32 bcr; ++ int ret; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { + if (!(ebi->bank_assigned & BIT(cs))) + continue; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; ++ + if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) && +- ebi->bank_assigned & BIT(FMC2_NAND)) +- return true; ++ ebi->bank_assigned & BIT(FMC2_NAND)) { ++ dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n"); ++ return -EINVAL; ++ } + } + +- return false; ++ return 0; + } + + static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi) +@@ -1083,10 +1135,9 @@ static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi) + return -ENODEV; + } + +- if (stm32_fmc2_ebi_nwait_used_by_ctrls(ebi)) { +- dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n"); +- return -EINVAL; +- } ++ ret = stm32_fmc2_ebi_nwait_used_by_ctrls(ebi); ++ if (ret) ++ return ret; + + stm32_fmc2_ebi_enable(ebi); + +@@ -1131,7 +1182,10 @@ static int stm32_fmc2_ebi_probe(struct platform_device *pdev) + if (ret) + goto err_release; + +- stm32_fmc2_ebi_save_setup(ebi); ++ ret = stm32_fmc2_ebi_save_setup(ebi); ++ if (ret) ++ goto err_release; ++ + platform_set_drvdata(pdev, ebi); + + return 0; +diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c +index 4bed0e54fd456..2ff586c6b1021 100644 +--- a/drivers/memory/tegra/tegra186.c ++++ b/drivers/memory/tegra/tegra186.c +@@ -43,6 +43,9 @@ static void tegra186_mc_client_sid_override(struct tegra_mc *mc, + { + u32 value, old; + ++ if (client->regs.sid.security == 0 && client->regs.sid.override == 0) ++ return; ++ + value = readl(mc->regs + client->regs.sid.security); + if ((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0) { + /* +diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c +index 4052f828f75e7..e03d4405cda36 100644 +--- a/drivers/mmc/core/mmc_test.c ++++ b/drivers/mmc/core/mmc_test.c +@@ -3111,13 +3111,13 @@ static ssize_t mtf_test_write(struct file *file, const char __user *buf, + test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); + #ifdef CONFIG_HIGHMEM + test->highmem = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, BUFFER_ORDER); ++ if (!test->highmem) { ++ count = -ENOMEM; ++ goto free_test_buffer; ++ } + #endif + +-#ifdef CONFIG_HIGHMEM +- if (test->buffer && test->highmem) { +-#else + if (test->buffer) { +-#endif + mutex_lock(&mmc_test_lock); + mmc_test_run(test, testcase); + mutex_unlock(&mmc_test_lock); +@@ -3125,6 +3125,7 @@ static ssize_t mtf_test_write(struct file *file, const char __user *buf, + + #ifdef CONFIG_HIGHMEM + __free_pages(test->highmem, BUFFER_ORDER); ++free_test_buffer: + #endif + kfree(test->buffer); + kfree(test); +diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c +index 1e8f1bb3cad7c..32927e66b60ca 100644 +--- a/drivers/mmc/host/dw_mmc.c ++++ b/drivers/mmc/host/dw_mmc.c +@@ -3246,6 +3246,10 @@ int dw_mci_probe(struct dw_mci *host) + host->biu_clk = devm_clk_get(host->dev, "biu"); + if (IS_ERR(host->biu_clk)) { + dev_dbg(host->dev, "biu clock not available\n"); ++ ret = PTR_ERR(host->biu_clk); ++ if (ret == -EPROBE_DEFER) ++ return ret; ++ + } else { + ret = clk_prepare_enable(host->biu_clk); + if (ret) { +@@ -3257,6 +3261,10 @@ int dw_mci_probe(struct dw_mci *host) + host->ciu_clk = devm_clk_get(host->dev, "ciu"); + if (IS_ERR(host->ciu_clk)) { + dev_dbg(host->dev, "ciu clock not available\n"); ++ ret = PTR_ERR(host->ciu_clk); ++ if (ret == -EPROBE_DEFER) ++ goto err_clk_biu; ++ + host->bus_hz = host->pdata->bus_hz; + } else { + ret = clk_prepare_enable(host->ciu_clk); +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 6a91229b0e05b..fd0667e1d10ab 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -575,7 +575,6 @@ static void bond_ipsec_del_sa_all(struct bonding *bond) + } else { + slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs); + } +- ipsec->xs->xso.real_dev = NULL; + } + spin_unlock_bh(&bond->ipsec_lock); + rcu_read_unlock(); +@@ -592,34 +591,30 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs) + struct net_device *real_dev; + struct slave *curr_active; + struct bonding *bond; +- int err; ++ bool ok = false; + + bond = netdev_priv(bond_dev); + rcu_read_lock(); + curr_active = rcu_dereference(bond->curr_active_slave); ++ if (!curr_active) ++ goto out; + real_dev = curr_active->dev; + +- if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) { +- err = false; ++ if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) + goto out; +- } + +- if (!xs->xso.real_dev) { +- err = false; ++ if (!xs->xso.real_dev) + goto out; +- } + + if (!real_dev->xfrmdev_ops || + !real_dev->xfrmdev_ops->xdo_dev_offload_ok || +- netif_is_bond_master(real_dev)) { +- err = false; ++ netif_is_bond_master(real_dev)) + goto out; +- } + +- err = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs); ++ ok = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs); + out: + rcu_read_unlock(); +- return err; ++ return ok; + } + + static const struct xfrmdev_ops bond_xfrmdev_ops = { +diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c +index 1f8f7537e8ebf..5da4599377e1e 100644 +--- a/drivers/net/bonding/bond_options.c ++++ b/drivers/net/bonding/bond_options.c +@@ -893,7 +893,7 @@ static int bond_option_active_slave_set(struct bonding *bond, + /* check to see if we are clearing active */ + if (!slave_dev) { + netdev_dbg(bond->dev, "Clearing current active slave\n"); +- RCU_INIT_POINTER(bond->curr_active_slave, NULL); ++ bond_change_active_slave(bond, NULL); + bond_select_active_slave(bond); + } else { + struct slave *old_active = rtnl_dereference(bond->curr_active_slave); +diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile +index c8eca2b6f9594..49bf358b9c4fa 100644 +--- a/drivers/net/dsa/mv88e6xxx/Makefile ++++ b/drivers/net/dsa/mv88e6xxx/Makefile +@@ -15,3 +15,7 @@ mv88e6xxx-objs += port_hidden.o + mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o + mv88e6xxx-objs += serdes.o + mv88e6xxx-objs += smi.o ++mv88e6xxx-objs += trace.o ++ ++# for tracing framework to find trace.h ++CFLAGS_trace.o := -I$(src) +diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c +index 40bd67a5c8e93..17fd62616ce6d 100644 +--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c ++++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c +@@ -12,6 +12,7 @@ + + #include "chip.h" + #include "global1.h" ++#include "trace.h" + + /* Offset 0x01: ATU FID Register */ + +@@ -114,6 +115,19 @@ static int mv88e6xxx_g1_atu_op_wait(struct mv88e6xxx_chip *chip) + return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_ATU_OP, bit, 0); + } + ++static int mv88e6xxx_g1_read_atu_violation(struct mv88e6xxx_chip *chip) ++{ ++ int err; ++ ++ err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_ATU_OP, ++ MV88E6XXX_G1_ATU_OP_BUSY | ++ MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION); ++ if (err) ++ return err; ++ ++ return mv88e6xxx_g1_atu_op_wait(chip); ++} ++ + static int mv88e6xxx_g1_atu_op(struct mv88e6xxx_chip *chip, u16 fid, u16 op) + { + u16 val; +@@ -159,6 +173,41 @@ int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid) + return mv88e6xxx_g1_atu_op(chip, fid, MV88E6XXX_G1_ATU_OP_GET_NEXT_DB); + } + ++static int mv88e6xxx_g1_atu_fid_read(struct mv88e6xxx_chip *chip, u16 *fid) ++{ ++ u16 val = 0, upper = 0, op = 0; ++ int err = -EOPNOTSUPP; ++ ++ if (mv88e6xxx_num_databases(chip) > 256) { ++ err = mv88e6xxx_g1_read(chip, MV88E6352_G1_ATU_FID, &val); ++ val &= 0xfff; ++ if (err) ++ return err; ++ } else { ++ err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_OP, &op); ++ if (err) ++ return err; ++ if (mv88e6xxx_num_databases(chip) > 64) { ++ /* ATU DBNum[7:4] are located in ATU Control 15:12 */ ++ err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_CTL, ++ &upper); ++ if (err) ++ return err; ++ ++ upper = (upper >> 8) & 0x00f0; ++ } else if (mv88e6xxx_num_databases(chip) > 16) { ++ /* ATU DBNum[5:4] are located in ATU Operation 9:8 */ ++ upper = (op >> 4) & 0x30; ++ } ++ ++ /* ATU DBNum[3:0] are located in ATU Operation 3:0 */ ++ val = (op & 0xf) | upper; ++ } ++ *fid = val; ++ ++ return err; ++} ++ + /* Offset 0x0C: ATU Data Register */ + + static int mv88e6xxx_g1_atu_data_read(struct mv88e6xxx_chip *chip, +@@ -353,14 +402,12 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id) + { + struct mv88e6xxx_chip *chip = dev_id; + struct mv88e6xxx_atu_entry entry; +- int spid; +- int err; +- u16 val; ++ int err, spid; ++ u16 val, fid; + + mv88e6xxx_reg_lock(chip); + +- err = mv88e6xxx_g1_atu_op(chip, 0, +- MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION); ++ err = mv88e6xxx_g1_read_atu_violation(chip); + if (err) + goto out; + +@@ -368,6 +415,10 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id) + if (err) + goto out; + ++ err = mv88e6xxx_g1_atu_fid_read(chip, &fid); ++ if (err) ++ goto out; ++ + err = mv88e6xxx_g1_atu_data_read(chip, &entry); + if (err) + goto out; +@@ -385,24 +436,25 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id) + } + + if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) { +- dev_err_ratelimited(chip->dev, +- "ATU member violation for %pM portvec %x spid %d\n", +- entry.mac, entry.portvec, spid); ++ trace_mv88e6xxx_atu_member_violation(chip->dev, spid, ++ entry.portvec, entry.mac, ++ fid); + chip->ports[spid].atu_member_violation++; + } + + if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) { +- dev_err_ratelimited(chip->dev, +- "ATU miss violation for %pM portvec %x spid %d\n", +- entry.mac, entry.portvec, spid); ++ trace_mv88e6xxx_atu_miss_violation(chip->dev, spid, ++ entry.portvec, entry.mac, ++ fid); + chip->ports[spid].atu_miss_violation++; + } + + if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) { +- dev_err_ratelimited(chip->dev, +- "ATU full violation for %pM portvec %x spid %d\n", +- entry.mac, entry.portvec, spid); +- chip->ports[spid].atu_full_violation++; ++ trace_mv88e6xxx_atu_full_violation(chip->dev, spid, ++ entry.portvec, entry.mac, ++ fid); ++ if (spid < ARRAY_SIZE(chip->ports)) ++ chip->ports[spid].atu_full_violation++; + } + mv88e6xxx_reg_unlock(chip); + +diff --git a/drivers/net/dsa/mv88e6xxx/trace.c b/drivers/net/dsa/mv88e6xxx/trace.c +new file mode 100644 +index 0000000000000..7833cb50ca5d7 +--- /dev/null ++++ b/drivers/net/dsa/mv88e6xxx/trace.c +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* Copyright 2022 NXP ++ */ ++ ++#define CREATE_TRACE_POINTS ++#include "trace.h" +diff --git a/drivers/net/dsa/mv88e6xxx/trace.h b/drivers/net/dsa/mv88e6xxx/trace.h +new file mode 100644 +index 0000000000000..d9ab5c8dee55d +--- /dev/null ++++ b/drivers/net/dsa/mv88e6xxx/trace.h +@@ -0,0 +1,66 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* Copyright 2022 NXP ++ */ ++ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM mv88e6xxx ++ ++#if !defined(_MV88E6XXX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _MV88E6XXX_TRACE_H ++ ++#include <linux/device.h> ++#include <linux/if_ether.h> ++#include <linux/tracepoint.h> ++ ++DECLARE_EVENT_CLASS(mv88e6xxx_atu_violation, ++ ++ TP_PROTO(const struct device *dev, int spid, u16 portvec, ++ const unsigned char *addr, u16 fid), ++ ++ TP_ARGS(dev, spid, portvec, addr, fid), ++ ++ TP_STRUCT__entry( ++ __string(name, dev_name(dev)) ++ __field(int, spid) ++ __field(u16, portvec) ++ __array(unsigned char, addr, ETH_ALEN) ++ __field(u16, fid) ++ ), ++ ++ TP_fast_assign( ++ __assign_str(name, dev_name(dev)); ++ __entry->spid = spid; ++ __entry->portvec = portvec; ++ memcpy(__entry->addr, addr, ETH_ALEN); ++ __entry->fid = fid; ++ ), ++ ++ TP_printk("dev %s spid %d portvec 0x%x addr %pM fid %u", ++ __get_str(name), __entry->spid, __entry->portvec, ++ __entry->addr, __entry->fid) ++); ++ ++DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_member_violation, ++ TP_PROTO(const struct device *dev, int spid, u16 portvec, ++ const unsigned char *addr, u16 fid), ++ TP_ARGS(dev, spid, portvec, addr, fid)); ++ ++DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_miss_violation, ++ TP_PROTO(const struct device *dev, int spid, u16 portvec, ++ const unsigned char *addr, u16 fid), ++ TP_ARGS(dev, spid, portvec, addr, fid)); ++ ++DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_full_violation, ++ TP_PROTO(const struct device *dev, int spid, u16 portvec, ++ const unsigned char *addr, u16 fid), ++ TP_ARGS(dev, spid, portvec, addr, fid)); ++ ++#endif /* _MV88E6XXX_TRACE_H */ ++ ++/* We don't want to use include/trace/events */ ++#undef TRACE_INCLUDE_PATH ++#define TRACE_INCLUDE_PATH . ++#undef TRACE_INCLUDE_FILE ++#define TRACE_INCLUDE_FILE trace ++/* This part must be outside protection */ ++#include <trace/define_trace.h> +diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c +index 6b6470ef2ae93..592527f069446 100644 +--- a/drivers/net/dsa/vitesse-vsc73xx-core.c ++++ b/drivers/net/dsa/vitesse-vsc73xx-core.c +@@ -17,6 +17,7 @@ + #include <linux/kernel.h> + #include <linux/module.h> + #include <linux/device.h> ++#include <linux/iopoll.h> + #include <linux/of.h> + #include <linux/of_device.h> + #include <linux/of_mdio.h> +@@ -38,6 +39,10 @@ + #define VSC73XX_BLOCK_ARBITER 0x5 /* Only subblock 0 */ + #define VSC73XX_BLOCK_SYSTEM 0x7 /* Only subblock 0 */ + ++/* MII Block subblock */ ++#define VSC73XX_BLOCK_MII_INTERNAL 0x0 /* Internal MDIO subblock */ ++#define VSC73XX_BLOCK_MII_EXTERNAL 0x1 /* External MDIO subblock */ ++ + #define CPU_PORT 6 /* CPU port */ + + /* MAC Block registers */ +@@ -196,6 +201,8 @@ + #define VSC73XX_MII_CMD 0x1 + #define VSC73XX_MII_DATA 0x2 + ++#define VSC73XX_MII_STAT_BUSY BIT(3) ++ + /* Arbiter block 5 registers */ + #define VSC73XX_ARBEMPTY 0x0c + #define VSC73XX_ARBDISC 0x0e +@@ -269,6 +276,10 @@ + #define IS_7398(a) ((a)->chipid == VSC73XX_CHIPID_ID_7398) + #define IS_739X(a) (IS_7395(a) || IS_7398(a)) + ++#define VSC73XX_POLL_SLEEP_US 1000 ++#define VSC73XX_MDIO_POLL_SLEEP_US 5 ++#define VSC73XX_POLL_TIMEOUT_US 10000 ++ + struct vsc73xx_counter { + u8 counter; + const char *name; +@@ -484,6 +495,22 @@ static int vsc73xx_detect(struct vsc73xx *vsc) + return 0; + } + ++static int vsc73xx_mdio_busy_check(struct vsc73xx *vsc) ++{ ++ int ret, err; ++ u32 val; ++ ++ ret = read_poll_timeout(vsc73xx_read, err, ++ err < 0 || !(val & VSC73XX_MII_STAT_BUSY), ++ VSC73XX_MDIO_POLL_SLEEP_US, ++ VSC73XX_POLL_TIMEOUT_US, false, vsc, ++ VSC73XX_BLOCK_MII, VSC73XX_BLOCK_MII_INTERNAL, ++ VSC73XX_MII_STAT, &val); ++ if (ret) ++ return ret; ++ return err; ++} ++ + static int vsc73xx_phy_read(struct dsa_switch *ds, int phy, int regnum) + { + struct vsc73xx *vsc = ds->priv; +@@ -491,12 +518,20 @@ static int vsc73xx_phy_read(struct dsa_switch *ds, int phy, int regnum) + u32 val; + int ret; + ++ ret = vsc73xx_mdio_busy_check(vsc); ++ if (ret) ++ return ret; ++ + /* Setting bit 26 means "read" */ + cmd = BIT(26) | (phy << 21) | (regnum << 16); + ret = vsc73xx_write(vsc, VSC73XX_BLOCK_MII, 0, 1, cmd); + if (ret) + return ret; +- msleep(2); ++ ++ ret = vsc73xx_mdio_busy_check(vsc); ++ if (ret) ++ return ret; ++ + ret = vsc73xx_read(vsc, VSC73XX_BLOCK_MII, 0, 2, &val); + if (ret) + return ret; +@@ -520,6 +555,10 @@ static int vsc73xx_phy_write(struct dsa_switch *ds, int phy, int regnum, + u32 cmd; + int ret; + ++ ret = vsc73xx_mdio_busy_check(vsc); ++ if (ret) ++ return ret; ++ + /* It was found through tedious experiments that this router + * chip really hates to have it's PHYs reset. They + * never recover if that happens: autonegotiation stops +@@ -531,7 +570,7 @@ static int vsc73xx_phy_write(struct dsa_switch *ds, int phy, int regnum, + return 0; + } + +- cmd = (phy << 21) | (regnum << 16); ++ cmd = (phy << 21) | (regnum << 16) | val; + ret = vsc73xx_write(vsc, VSC73XX_BLOCK_MII, 0, 1, cmd); + if (ret) + return ret; +@@ -780,7 +819,7 @@ static void vsc73xx_adjust_link(struct dsa_switch *ds, int port, + * after a PHY or the CPU port comes up or down. + */ + if (!phydev->link) { +- int maxloop = 10; ++ int ret, err; + + dev_dbg(vsc->dev, "port %d: went down\n", + port); +@@ -795,19 +834,17 @@ static void vsc73xx_adjust_link(struct dsa_switch *ds, int port, + VSC73XX_ARBDISC, BIT(port), BIT(port)); + + /* Wait until queue is empty */ +- vsc73xx_read(vsc, VSC73XX_BLOCK_ARBITER, 0, +- VSC73XX_ARBEMPTY, &val); +- while (!(val & BIT(port))) { +- msleep(1); +- vsc73xx_read(vsc, VSC73XX_BLOCK_ARBITER, 0, +- VSC73XX_ARBEMPTY, &val); +- if (--maxloop == 0) { +- dev_err(vsc->dev, +- "timeout waiting for block arbiter\n"); +- /* Continue anyway */ +- break; +- } +- } ++ ret = read_poll_timeout(vsc73xx_read, err, ++ err < 0 || (val & BIT(port)), ++ VSC73XX_POLL_SLEEP_US, ++ VSC73XX_POLL_TIMEOUT_US, false, ++ vsc, VSC73XX_BLOCK_ARBITER, 0, ++ VSC73XX_ARBEMPTY, &val); ++ if (ret) ++ dev_err(vsc->dev, ++ "timeout waiting for block arbiter\n"); ++ else if (err < 0) ++ dev_err(vsc->dev, "error reading arbiter\n"); + + /* Put this port into reset */ + vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG, +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c +index 786ceae344887..dd9e68465e697 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c +@@ -1244,7 +1244,8 @@ static u64 hash_filter_ntuple(struct ch_filter_specification *fs, + * in the Compressed Filter Tuple. + */ + if (tp->vlan_shift >= 0 && fs->mask.ivlan) +- ntuple |= (FT_VLAN_VLD_F | fs->val.ivlan) << tp->vlan_shift; ++ ntuple |= (u64)(FT_VLAN_VLD_F | ++ fs->val.ivlan) << tp->vlan_shift; + + if (tp->port_shift >= 0 && fs->mask.iport) + ntuple |= (u64)fs->val.iport << tp->port_shift; +diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +index 175f15c46842e..2b6a6a997d75e 100644 +--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c ++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +@@ -2585,13 +2585,14 @@ static int dpaa2_switch_refill_bp(struct ethsw_core *ethsw) + + static int dpaa2_switch_seed_bp(struct ethsw_core *ethsw) + { +- int *count, i; ++ int *count, ret, i; + + for (i = 0; i < DPAA2_ETHSW_NUM_BUFS; i += BUFS_PER_CMD) { ++ ret = dpaa2_switch_add_bufs(ethsw, ethsw->bpid); + count = ðsw->buf_count; +- *count += dpaa2_switch_add_bufs(ethsw, ethsw->bpid); ++ *count += ret; + +- if (unlikely(*count < BUFS_PER_CMD)) ++ if (unlikely(ret < BUFS_PER_CMD)) + return -ENOMEM; + } + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index e48d33927c176..d6bdcd9f285b0 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -5504,6 +5504,9 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle) + struct net_device *netdev = handle->kinfo.netdev; + struct hns3_nic_priv *priv = netdev_priv(netdev); + ++ if (!test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) ++ hns3_nic_net_stop(netdev); ++ + if (!test_and_clear_bit(HNS3_NIC_STATE_INITED, &priv->state)) { + netdev_warn(netdev, "already uninitialized\n"); + return 0; +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index c3690e49c3d95..eb902e80a8158 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -11636,8 +11636,8 @@ static void hclge_reset_done(struct hnae3_ae_dev *ae_dev) + dev_err(&hdev->pdev->dev, "fail to rebuild, ret=%d\n", ret); + + hdev->reset_type = HNAE3_NONE_RESET; +- clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); +- up(&hdev->reset_sem); ++ if (test_and_clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) ++ up(&hdev->reset_sem); + } + + static void hclge_clear_resetting_state(struct hclge_dev *hdev) +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +index 77c432ab7856c..e2fe41d3972fb 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +@@ -1066,10 +1066,11 @@ void hclge_mbx_handler(struct hclge_dev *hdev) + req = (struct hclge_mbx_vf_to_pf_cmd *)desc->data; + + flag = le16_to_cpu(crq->desc[crq->next_to_use].flag); +- if (unlikely(!hnae3_get_bit(flag, HCLGE_CMDQ_RX_OUTVLD_B))) { ++ if (unlikely(!hnae3_get_bit(flag, HCLGE_CMDQ_RX_OUTVLD_B) || ++ req->mbx_src_vfid > hdev->num_req_vfs)) { + dev_warn(&hdev->pdev->dev, +- "dropped invalid mailbox message, code = %u\n", +- req->msg.code); ++ "dropped invalid mailbox message, code = %u, vfid = %u\n", ++ req->msg.code, req->mbx_src_vfid); + + /* dropping/not processing this invalid message */ + crq->desc[crq->next_to_use].flag = 0; +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index a41e04796b0b6..5b861a2a3e73e 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -2217,8 +2217,8 @@ static void hclgevf_reset_done(struct hnae3_ae_dev *ae_dev) + ret); + + hdev->reset_type = HNAE3_NONE_RESET; +- clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); +- up(&hdev->reset_sem); ++ if (test_and_clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) ++ up(&hdev->reset_sem); + } + + static u32 hclgevf_get_fw_version(struct hnae3_handle *handle) +diff --git a/drivers/net/ethernet/i825xx/sun3_82586.c b/drivers/net/ethernet/i825xx/sun3_82586.c +index 18d32302c3c7a..6c89aa7eaa222 100644 +--- a/drivers/net/ethernet/i825xx/sun3_82586.c ++++ b/drivers/net/ethernet/i825xx/sun3_82586.c +@@ -987,7 +987,7 @@ static void sun3_82586_timeout(struct net_device *dev, unsigned int txqueue) + { + #ifdef DEBUG + printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus); +- printk("%s: command-stats: %04x %04x\n",dev->name,swab16(p->xmit_cmds[0]->cmd_status),swab16(p->xmit_cmds[1]->cmd_status)); ++ printk("%s: command-stats: %04x\n", dev->name, swab16(p->xmit_cmds[0]->cmd_status)); + printk("%s: check, whether you set the right interrupt number!\n",dev->name); + #endif + sun3_82586_close(dev); +diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c +index 6ee8e0032d52c..b09d89cdb001f 100644 +--- a/drivers/net/ethernet/intel/ice/ice_txrx.c ++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c +@@ -765,7 +765,7 @@ ice_can_reuse_rx_page(struct ice_rx_buf *rx_buf, int rx_buf_pgcnt) + return false; + #else + #define ICE_LAST_OFFSET \ +- (SKB_WITH_OVERHEAD(PAGE_SIZE) - ICE_RXBUF_2048) ++ (SKB_WITH_OVERHEAD(PAGE_SIZE) - ICE_RXBUF_3072) + if (rx_buf->page_offset > ICE_LAST_OFFSET) + return false; + #endif /* PAGE_SIZE < 8192) */ +diff --git a/drivers/net/ethernet/intel/igc/igc_base.c b/drivers/net/ethernet/intel/igc/igc_base.c +index 84f142f5e472e..be095c6531b68 100644 +--- a/drivers/net/ethernet/intel/igc/igc_base.c ++++ b/drivers/net/ethernet/intel/igc/igc_base.c +@@ -402,6 +402,35 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw) + rd32(IGC_MPC); + } + ++bool igc_is_device_id_i225(struct igc_hw *hw) ++{ ++ switch (hw->device_id) { ++ case IGC_DEV_ID_I225_LM: ++ case IGC_DEV_ID_I225_V: ++ case IGC_DEV_ID_I225_I: ++ case IGC_DEV_ID_I225_K: ++ case IGC_DEV_ID_I225_K2: ++ case IGC_DEV_ID_I225_LMVP: ++ case IGC_DEV_ID_I225_IT: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++bool igc_is_device_id_i226(struct igc_hw *hw) ++{ ++ switch (hw->device_id) { ++ case IGC_DEV_ID_I226_LM: ++ case IGC_DEV_ID_I226_V: ++ case IGC_DEV_ID_I226_K: ++ case IGC_DEV_ID_I226_IT: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static struct igc_mac_operations igc_mac_ops_base = { + .init_hw = igc_init_hw_base, + .check_for_link = igc_check_for_copper_link, +diff --git a/drivers/net/ethernet/intel/igc/igc_base.h b/drivers/net/ethernet/intel/igc/igc_base.h +index 52849f5e8048d..9f3827eda157c 100644 +--- a/drivers/net/ethernet/intel/igc/igc_base.h ++++ b/drivers/net/ethernet/intel/igc/igc_base.h +@@ -7,6 +7,8 @@ + /* forward declaration */ + void igc_rx_fifo_flush_base(struct igc_hw *hw); + void igc_power_down_phy_copper_base(struct igc_hw *hw); ++bool igc_is_device_id_i225(struct igc_hw *hw); ++bool igc_is_device_id_i226(struct igc_hw *hw); + + /* Transmit Descriptor - Advanced */ + union igc_adv_tx_desc { +diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h +index 703b62c5f79b5..d5acee27894e5 100644 +--- a/drivers/net/ethernet/intel/igc/igc_defines.h ++++ b/drivers/net/ethernet/intel/igc/igc_defines.h +@@ -405,6 +405,21 @@ + #define IGC_DTXMXPKTSZ_TSN 0x19 /* 1600 bytes of max TX DMA packet size */ + #define IGC_DTXMXPKTSZ_DEFAULT 0x98 /* 9728-byte Jumbo frames */ + ++/* Retry Buffer Control */ ++#define IGC_RETX_CTL 0x041C ++#define IGC_RETX_CTL_WATERMARK_MASK 0xF ++#define IGC_RETX_CTL_QBVFULLTH_SHIFT 8 /* QBV Retry Buffer Full Threshold */ ++#define IGC_RETX_CTL_QBVFULLEN 0x1000 /* Enable QBV Retry Buffer Full Threshold */ ++ ++/* Transmit Scheduling Latency */ ++/* Latency between transmission scheduling (LaunchTime) and the time ++ * the packet is transmitted to the network in nanosecond. ++ */ ++#define IGC_TXOFFSET_SPEED_10 0x000034BC ++#define IGC_TXOFFSET_SPEED_100 0x00000578 ++#define IGC_TXOFFSET_SPEED_1000 0x0000012C ++#define IGC_TXOFFSET_SPEED_2500 0x00000578 ++ + /* Time Sync Interrupt Causes */ + #define IGC_TSICR_SYS_WRAP BIT(0) /* SYSTIM Wrap around. */ + #define IGC_TSICR_TXTS BIT(1) /* Transmit Timestamp. */ +@@ -518,6 +533,7 @@ + /* Transmit Scheduling */ + #define IGC_TQAVCTRL_TRANSMIT_MODE_TSN 0x00000001 + #define IGC_TQAVCTRL_ENHANCED_QAV 0x00000008 ++#define IGC_TQAVCTRL_FUTSCDDIS 0x00000080 + + #define IGC_TXQCTL_QUEUE_MODE_LAUNCHT 0x00000001 + #define IGC_TXQCTL_STRICT_CYCLE 0x00000002 +diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c +index 6185566fbb98c..7605115e6a1b2 100644 +--- a/drivers/net/ethernet/intel/igc/igc_main.c ++++ b/drivers/net/ethernet/intel/igc/igc_main.c +@@ -5532,6 +5532,13 @@ static void igc_watchdog_task(struct work_struct *work) + break; + } + ++ /* Once the launch time has been set on the wire, there ++ * is a delay before the link speed can be determined ++ * based on link-up activity. Write into the register ++ * as soon as we know the correct link speed. ++ */ ++ igc_tsn_adjust_txtime_offset(adapter); ++ + if (adapter->link_speed != SPEED_1000) + goto no_wait; + +@@ -5984,6 +5991,7 @@ static bool validate_schedule(struct igc_adapter *adapter, + const struct tc_taprio_qopt_offload *qopt) + { + int queue_uses[IGC_MAX_TX_QUEUES] = { }; ++ struct igc_hw *hw = &adapter->hw; + struct timespec64 now; + size_t n; + +@@ -5996,8 +6004,10 @@ static bool validate_schedule(struct igc_adapter *adapter, + * in the future, it will hold all the packets until that + * time, causing a lot of TX Hangs, so to avoid that, we + * reject schedules that would start in the future. ++ * Note: Limitation above is no longer in i226. + */ +- if (!is_base_time_past(qopt->base_time, &now)) ++ if (!is_base_time_past(qopt->base_time, &now) && ++ igc_is_device_id_i225(hw)) + return false; + + for (n = 0; n < qopt->num_entries; n++) { +diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h +index 026c3b65fc37a..0e9c1298f36fe 100644 +--- a/drivers/net/ethernet/intel/igc/igc_regs.h ++++ b/drivers/net/ethernet/intel/igc/igc_regs.h +@@ -227,6 +227,7 @@ + /* Transmit Scheduling Registers */ + #define IGC_TQAVCTRL 0x3570 + #define IGC_TXQCTL(_n) (0x3344 + 0x4 * (_n)) ++#define IGC_GTXOFFSET 0x3310 + #define IGC_BASET_L 0x3314 + #define IGC_BASET_H 0x3318 + #define IGC_QBVCYCLET 0x331C +diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c +index 2330b1ff915e7..27ce2f7dfeed2 100644 +--- a/drivers/net/ethernet/intel/igc/igc_tsn.c ++++ b/drivers/net/ethernet/intel/igc/igc_tsn.c +@@ -2,6 +2,7 @@ + /* Copyright (c) 2019 Intel Corporation */ + + #include "igc.h" ++#include "igc_hw.h" + #include "igc_tsn.h" + + static bool is_any_launchtime(struct igc_adapter *adapter) +@@ -48,6 +49,51 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter) + return new_flags; + } + ++static bool igc_tsn_is_tx_mode_in_tsn(struct igc_adapter *adapter) ++{ ++ struct igc_hw *hw = &adapter->hw; ++ ++ return !!(rd32(IGC_TQAVCTRL) & IGC_TQAVCTRL_TRANSMIT_MODE_TSN); ++} ++ ++void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter) ++{ ++ struct igc_hw *hw = &adapter->hw; ++ u16 txoffset; ++ ++ if (!igc_tsn_is_tx_mode_in_tsn(adapter)) ++ return; ++ ++ switch (adapter->link_speed) { ++ case SPEED_10: ++ txoffset = IGC_TXOFFSET_SPEED_10; ++ break; ++ case SPEED_100: ++ txoffset = IGC_TXOFFSET_SPEED_100; ++ break; ++ case SPEED_1000: ++ txoffset = IGC_TXOFFSET_SPEED_1000; ++ break; ++ case SPEED_2500: ++ txoffset = IGC_TXOFFSET_SPEED_2500; ++ break; ++ default: ++ txoffset = 0; ++ break; ++ } ++ ++ wr32(IGC_GTXOFFSET, txoffset); ++} ++ ++static void igc_tsn_restore_retx_default(struct igc_adapter *adapter) ++{ ++ struct igc_hw *hw = &adapter->hw; ++ u32 retxctl; ++ ++ retxctl = rd32(IGC_RETX_CTL) & IGC_RETX_CTL_WATERMARK_MASK; ++ wr32(IGC_RETX_CTL, retxctl); ++} ++ + /* Returns the TSN specific registers to their default values after + * the adapter is reset. + */ +@@ -57,12 +103,17 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter) + u32 tqavctrl; + int i; + ++ wr32(IGC_GTXOFFSET, 0); + wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT); + wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT); + ++ if (igc_is_device_id_i226(hw)) ++ igc_tsn_restore_retx_default(adapter); ++ + tqavctrl = rd32(IGC_TQAVCTRL); + tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN | +- IGC_TQAVCTRL_ENHANCED_QAV); ++ IGC_TQAVCTRL_ENHANCED_QAV | IGC_TQAVCTRL_FUTSCDDIS); ++ + wr32(IGC_TQAVCTRL, tqavctrl); + + for (i = 0; i < adapter->num_tx_queues; i++) { +@@ -79,6 +130,25 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter) + return 0; + } + ++/* To partially fix i226 HW errata, reduce MAC internal buffering from 192 Bytes ++ * to 88 Bytes by setting RETX_CTL register using the recommendation from: ++ * a) Ethernet Controller I225/I226 Specification Update Rev 2.1 ++ * Item 9: TSN: Packet Transmission Might Cross the Qbv Window ++ * b) I225/6 SW User Manual Rev 1.2.4: Section 8.11.5 Retry Buffer Control ++ */ ++static void igc_tsn_set_retx_qbvfullthreshold(struct igc_adapter *adapter) ++{ ++ struct igc_hw *hw = &adapter->hw; ++ u32 retxctl, watermark; ++ ++ retxctl = rd32(IGC_RETX_CTL); ++ watermark = retxctl & IGC_RETX_CTL_WATERMARK_MASK; ++ /* Set QBVFULLTH value using watermark and set QBVFULLEN */ ++ retxctl |= (watermark << IGC_RETX_CTL_QBVFULLTH_SHIFT) | ++ IGC_RETX_CTL_QBVFULLEN; ++ wr32(IGC_RETX_CTL, retxctl); ++} ++ + static int igc_tsn_enable_offload(struct igc_adapter *adapter) + { + struct igc_hw *hw = &adapter->hw; +@@ -87,19 +157,12 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter) + ktime_t base_time, systim; + int i; + +- cycle = adapter->cycle_time; +- base_time = adapter->base_time; +- + wr32(IGC_TSAUXC, 0); + wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN); + wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN); + +- tqavctrl = rd32(IGC_TQAVCTRL); +- tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV; +- wr32(IGC_TQAVCTRL, tqavctrl); +- +- wr32(IGC_QBVCYCLET_S, cycle); +- wr32(IGC_QBVCYCLET, cycle); ++ if (igc_is_device_id_i226(hw)) ++ igc_tsn_set_retx_qbvfullthreshold(adapter); + + for (i = 0; i < adapter->num_tx_queues; i++) { + struct igc_ring *ring = adapter->tx_ring[i]; +@@ -203,21 +266,43 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter) + wr32(IGC_TXQCTL(i), txqctl); + } + ++ tqavctrl = rd32(IGC_TQAVCTRL); ++ tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV; ++ ++ cycle = adapter->cycle_time; ++ base_time = adapter->base_time; ++ + nsec = rd32(IGC_SYSTIML); + sec = rd32(IGC_SYSTIMH); + + systim = ktime_set(sec, nsec); +- + if (ktime_compare(systim, base_time) > 0) { +- s64 n; ++ s64 n = div64_s64(ktime_sub_ns(systim, base_time), cycle); + +- n = div64_s64(ktime_sub_ns(systim, base_time), cycle); + base_time = ktime_add_ns(base_time, (n + 1) * cycle); ++ } else { ++ /* According to datasheet section 7.5.2.9.3.3, FutScdDis bit ++ * has to be configured before the cycle time and base time. ++ */ ++ if (igc_is_device_id_i226(hw)) ++ tqavctrl |= IGC_TQAVCTRL_FUTSCDDIS; + } + +- baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l); ++ wr32(IGC_TQAVCTRL, tqavctrl); + ++ wr32(IGC_QBVCYCLET_S, cycle); ++ wr32(IGC_QBVCYCLET, cycle); ++ ++ baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l); + wr32(IGC_BASET_H, baset_h); ++ ++ /* In i226, Future base time is only supported when FutScdDis bit ++ * is enabled and only active for re-configuration. ++ * In this case, initialize the base time with zero to create ++ * "re-configuration" scenario then only set the desired base time. ++ */ ++ if (tqavctrl & IGC_TQAVCTRL_FUTSCDDIS) ++ wr32(IGC_BASET_L, 0); + wr32(IGC_BASET_L, baset_l); + + return 0; +diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.h b/drivers/net/ethernet/intel/igc/igc_tsn.h +index 1512307f5a528..b53e6af560b73 100644 +--- a/drivers/net/ethernet/intel/igc/igc_tsn.h ++++ b/drivers/net/ethernet/intel/igc/igc_tsn.h +@@ -6,5 +6,6 @@ + + int igc_tsn_offload_apply(struct igc_adapter *adapter); + int igc_tsn_reset(struct igc_adapter *adapter); ++void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter); + + #endif /* _IGC_BASE_H */ +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c +index d32b70c62c949..32212bc41df30 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c +@@ -727,7 +727,7 @@ mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv, + if (num_tuples <= 0) { + netdev_warn(priv->netdev, "%s: flow is not valid %d\n", + __func__, num_tuples); +- return num_tuples; ++ return num_tuples < 0 ? num_tuples : -EINVAL; + } + + eth_ft = get_flow_table(priv, fs, num_tuples); +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h +index 0fdf2c8ca480d..0e4ece5ab7976 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h +@@ -39,6 +39,7 @@ + */ + #define MLXBF_GIGE_BCAST_MAC_FILTER_IDX 0 + #define MLXBF_GIGE_LOCAL_MAC_FILTER_IDX 1 ++#define MLXBF_GIGE_MAX_FILTER_IDX 3 + + /* Define for broadcast MAC literal */ + #define BCAST_MAC_ADDR 0xFFFFFFFFFFFF +@@ -151,9 +152,13 @@ enum mlxbf_gige_res { + int mlxbf_gige_mdio_probe(struct platform_device *pdev, + struct mlxbf_gige *priv); + void mlxbf_gige_mdio_remove(struct mlxbf_gige *priv); +-irqreturn_t mlxbf_gige_mdio_handle_phy_interrupt(int irq, void *dev_id); +-void mlxbf_gige_mdio_enable_phy_int(struct mlxbf_gige *priv); + ++void mlxbf_gige_enable_multicast_rx(struct mlxbf_gige *priv); ++void mlxbf_gige_disable_multicast_rx(struct mlxbf_gige *priv); ++void mlxbf_gige_enable_mac_rx_filter(struct mlxbf_gige *priv, ++ unsigned int index); ++void mlxbf_gige_disable_mac_rx_filter(struct mlxbf_gige *priv, ++ unsigned int index); + void mlxbf_gige_set_mac_rx_filter(struct mlxbf_gige *priv, + unsigned int index, u64 dmac); + void mlxbf_gige_get_mac_rx_filter(struct mlxbf_gige *priv, +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +index c644ee78e0b40..60cea337fe8ec 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +@@ -170,6 +170,10 @@ static int mlxbf_gige_open(struct net_device *netdev) + if (err) + goto napi_deinit; + ++ mlxbf_gige_enable_mac_rx_filter(priv, MLXBF_GIGE_BCAST_MAC_FILTER_IDX); ++ mlxbf_gige_enable_mac_rx_filter(priv, MLXBF_GIGE_LOCAL_MAC_FILTER_IDX); ++ mlxbf_gige_enable_multicast_rx(priv); ++ + /* Set bits in INT_EN that we care about */ + int_en = MLXBF_GIGE_INT_EN_HW_ACCESS_ERROR | + MLXBF_GIGE_INT_EN_TX_CHECKSUM_INPUTS | +@@ -295,6 +299,7 @@ static int mlxbf_gige_probe(struct platform_device *pdev) + void __iomem *plu_base; + void __iomem *base; + int addr, phy_irq; ++ unsigned int i; + int err; + + base = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_MAC); +@@ -337,6 +342,11 @@ static int mlxbf_gige_probe(struct platform_device *pdev) + priv->rx_q_entries = MLXBF_GIGE_DEFAULT_RXQ_SZ; + priv->tx_q_entries = MLXBF_GIGE_DEFAULT_TXQ_SZ; + ++ for (i = 0; i <= MLXBF_GIGE_MAX_FILTER_IDX; i++) ++ mlxbf_gige_disable_mac_rx_filter(priv, i); ++ mlxbf_gige_disable_multicast_rx(priv); ++ mlxbf_gige_disable_promisc(priv); ++ + /* Write initial MAC address to hardware */ + mlxbf_gige_initial_mac(priv); + +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h +index 7be3a793984d5..d27535a1fb86f 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h +@@ -59,6 +59,8 @@ + #define MLXBF_GIGE_TX_STATUS_DATA_FIFO_FULL BIT(1) + #define MLXBF_GIGE_RX_MAC_FILTER_DMAC_RANGE_START 0x0520 + #define MLXBF_GIGE_RX_MAC_FILTER_DMAC_RANGE_END 0x0528 ++#define MLXBF_GIGE_RX_MAC_FILTER_GENERAL 0x0530 ++#define MLXBF_GIGE_RX_MAC_FILTER_EN_MULTICAST BIT(1) + #define MLXBF_GIGE_RX_MAC_FILTER_COUNT_DISC 0x0540 + #define MLXBF_GIGE_RX_MAC_FILTER_COUNT_DISC_EN BIT(0) + #define MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS 0x0548 +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c +index 6999843584934..eb62620b63c7f 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c +@@ -11,15 +11,31 @@ + #include "mlxbf_gige.h" + #include "mlxbf_gige_regs.h" + +-void mlxbf_gige_set_mac_rx_filter(struct mlxbf_gige *priv, +- unsigned int index, u64 dmac) ++void mlxbf_gige_enable_multicast_rx(struct mlxbf_gige *priv) + { + void __iomem *base = priv->base; +- u64 control; ++ u64 data; + +- /* Write destination MAC to specified MAC RX filter */ +- writeq(dmac, base + MLXBF_GIGE_RX_MAC_FILTER + +- (index * MLXBF_GIGE_RX_MAC_FILTER_STRIDE)); ++ data = readq(base + MLXBF_GIGE_RX_MAC_FILTER_GENERAL); ++ data |= MLXBF_GIGE_RX_MAC_FILTER_EN_MULTICAST; ++ writeq(data, base + MLXBF_GIGE_RX_MAC_FILTER_GENERAL); ++} ++ ++void mlxbf_gige_disable_multicast_rx(struct mlxbf_gige *priv) ++{ ++ void __iomem *base = priv->base; ++ u64 data; ++ ++ data = readq(base + MLXBF_GIGE_RX_MAC_FILTER_GENERAL); ++ data &= ~MLXBF_GIGE_RX_MAC_FILTER_EN_MULTICAST; ++ writeq(data, base + MLXBF_GIGE_RX_MAC_FILTER_GENERAL); ++} ++ ++void mlxbf_gige_enable_mac_rx_filter(struct mlxbf_gige *priv, ++ unsigned int index) ++{ ++ void __iomem *base = priv->base; ++ u64 control; + + /* Enable MAC receive filter mask for specified index */ + control = readq(base + MLXBF_GIGE_CONTROL); +@@ -27,6 +43,28 @@ void mlxbf_gige_set_mac_rx_filter(struct mlxbf_gige *priv, + writeq(control, base + MLXBF_GIGE_CONTROL); + } + ++void mlxbf_gige_disable_mac_rx_filter(struct mlxbf_gige *priv, ++ unsigned int index) ++{ ++ void __iomem *base = priv->base; ++ u64 control; ++ ++ /* Disable MAC receive filter mask for specified index */ ++ control = readq(base + MLXBF_GIGE_CONTROL); ++ control &= ~(MLXBF_GIGE_CONTROL_EN_SPECIFIC_MAC << index); ++ writeq(control, base + MLXBF_GIGE_CONTROL); ++} ++ ++void mlxbf_gige_set_mac_rx_filter(struct mlxbf_gige *priv, ++ unsigned int index, u64 dmac) ++{ ++ void __iomem *base = priv->base; ++ ++ /* Write destination MAC to specified MAC RX filter */ ++ writeq(dmac, base + MLXBF_GIGE_RX_MAC_FILTER + ++ (index * MLXBF_GIGE_RX_MAC_FILTER_STRIDE)); ++} ++ + void mlxbf_gige_get_mac_rx_filter(struct mlxbf_gige *priv, + unsigned int index, u64 *dmac) + { +diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c +index d5c485a6d2845..508f83c29f325 100644 +--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c ++++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c +@@ -51,9 +51,33 @@ static int mana_hwc_verify_resp_msg(const struct hwc_caller_ctx *caller_ctx, + return 0; + } + ++static int mana_hwc_post_rx_wqe(const struct hwc_wq *hwc_rxq, ++ struct hwc_work_request *req) ++{ ++ struct device *dev = hwc_rxq->hwc->dev; ++ struct gdma_sge *sge; ++ int err; ++ ++ sge = &req->sge; ++ sge->address = (u64)req->buf_sge_addr; ++ sge->mem_key = hwc_rxq->msg_buf->gpa_mkey; ++ sge->size = req->buf_len; ++ ++ memset(&req->wqe_req, 0, sizeof(struct gdma_wqe_request)); ++ req->wqe_req.sgl = sge; ++ req->wqe_req.num_sge = 1; ++ req->wqe_req.client_data_unit = 0; ++ ++ err = mana_gd_post_and_ring(hwc_rxq->gdma_wq, &req->wqe_req, NULL); ++ if (err) ++ dev_err(dev, "Failed to post WQE on HWC RQ: %d\n", err); ++ return err; ++} ++ + static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len, +- const struct gdma_resp_hdr *resp_msg) ++ struct hwc_work_request *rx_req) + { ++ const struct gdma_resp_hdr *resp_msg = rx_req->buf_va; + struct hwc_caller_ctx *ctx; + int err; + +@@ -61,6 +85,7 @@ static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len, + hwc->inflight_msg_res.map)) { + dev_err(hwc->dev, "hwc_rx: invalid msg_id = %u\n", + resp_msg->response.hwc_msg_id); ++ mana_hwc_post_rx_wqe(hwc->rxq, rx_req); + return; + } + +@@ -74,30 +99,13 @@ static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len, + memcpy(ctx->output_buf, resp_msg, resp_len); + out: + ctx->error = err; +- complete(&ctx->comp_event); +-} +- +-static int mana_hwc_post_rx_wqe(const struct hwc_wq *hwc_rxq, +- struct hwc_work_request *req) +-{ +- struct device *dev = hwc_rxq->hwc->dev; +- struct gdma_sge *sge; +- int err; +- +- sge = &req->sge; +- sge->address = (u64)req->buf_sge_addr; +- sge->mem_key = hwc_rxq->msg_buf->gpa_mkey; +- sge->size = req->buf_len; + +- memset(&req->wqe_req, 0, sizeof(struct gdma_wqe_request)); +- req->wqe_req.sgl = sge; +- req->wqe_req.num_sge = 1; +- req->wqe_req.client_data_unit = 0; ++ /* Must post rx wqe before complete(), otherwise the next rx may ++ * hit no_wqe error. ++ */ ++ mana_hwc_post_rx_wqe(hwc->rxq, rx_req); + +- err = mana_gd_post_and_ring(hwc_rxq->gdma_wq, &req->wqe_req, NULL); +- if (err) +- dev_err(dev, "Failed to post WQE on HWC RQ: %d\n", err); +- return err; ++ complete(&ctx->comp_event); + } + + static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self, +@@ -208,14 +216,12 @@ static void mana_hwc_rx_event_handler(void *ctx, u32 gdma_rxq_id, + return; + } + +- mana_hwc_handle_resp(hwc, rx_oob->tx_oob_data_size, resp); ++ mana_hwc_handle_resp(hwc, rx_oob->tx_oob_data_size, rx_req); + +- /* Do no longer use 'resp', because the buffer is posted to the HW +- * in the below mana_hwc_post_rx_wqe(). ++ /* Can no longer use 'resp', because the buffer is posted to the HW ++ * in mana_hwc_handle_resp() above. + */ + resp = NULL; +- +- mana_hwc_post_rx_wqe(hwc_rxq, rx_req); + } + + static void mana_hwc_tx_event_handler(void *ctx, u32 gdma_txq_id, +diff --git a/drivers/net/ethernet/microsoft/mana/mana.h b/drivers/net/ethernet/microsoft/mana/mana.h +index fc98a5ba5ed07..35e937a7079c0 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana.h ++++ b/drivers/net/ethernet/microsoft/mana/mana.h +@@ -252,6 +252,7 @@ struct mana_cq { + /* NAPI data */ + struct napi_struct napi; + int work_done; ++ int work_done_since_doorbell; + int budget; + }; + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 6224b7c21e0af..b0963fda4d9fd 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -1074,7 +1074,6 @@ static void mana_poll_rx_cq(struct mana_cq *cq) + static int mana_cq_handler(void *context, struct gdma_queue *gdma_queue) + { + struct mana_cq *cq = context; +- u8 arm_bit; + int w; + + WARN_ON_ONCE(cq->gdma_cq != gdma_queue); +@@ -1085,16 +1084,23 @@ static int mana_cq_handler(void *context, struct gdma_queue *gdma_queue) + mana_poll_tx_cq(cq); + + w = cq->work_done; +- +- if (w < cq->budget && +- napi_complete_done(&cq->napi, w)) { +- arm_bit = SET_ARM_BIT; +- } else { +- arm_bit = 0; ++ cq->work_done_since_doorbell += w; ++ ++ if (w < cq->budget) { ++ mana_gd_ring_cq(gdma_queue, SET_ARM_BIT); ++ cq->work_done_since_doorbell = 0; ++ napi_complete_done(&cq->napi, w); ++ } else if (cq->work_done_since_doorbell > ++ cq->gdma_cq->queue_size / COMP_ENTRY_SIZE * 4) { ++ /* MANA hardware requires at least one doorbell ring every 8 ++ * wraparounds of CQ even if there is no need to arm the CQ. ++ * This driver rings the doorbell as soon as we have exceeded ++ * 4 wraparounds. ++ */ ++ mana_gd_ring_cq(gdma_queue, 0); ++ cq->work_done_since_doorbell = 0; + } + +- mana_gd_ring_cq(gdma_queue, arm_bit); +- + return w; + } + +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h +index 5b4d153b1492c..bdda836115095 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h +@@ -159,16 +159,17 @@ + #define XAE_RCW1_OFFSET 0x00000404 /* Rx Configuration Word 1 */ + #define XAE_TC_OFFSET 0x00000408 /* Tx Configuration */ + #define XAE_FCC_OFFSET 0x0000040C /* Flow Control Configuration */ +-#define XAE_EMMC_OFFSET 0x00000410 /* EMAC mode configuration */ +-#define XAE_PHYC_OFFSET 0x00000414 /* RGMII/SGMII configuration */ ++#define XAE_EMMC_OFFSET 0x00000410 /* MAC speed configuration */ ++#define XAE_PHYC_OFFSET 0x00000414 /* RX Max Frame Configuration */ + #define XAE_ID_OFFSET 0x000004F8 /* Identification register */ +-#define XAE_MDIO_MC_OFFSET 0x00000500 /* MII Management Config */ +-#define XAE_MDIO_MCR_OFFSET 0x00000504 /* MII Management Control */ +-#define XAE_MDIO_MWD_OFFSET 0x00000508 /* MII Management Write Data */ +-#define XAE_MDIO_MRD_OFFSET 0x0000050C /* MII Management Read Data */ ++#define XAE_MDIO_MC_OFFSET 0x00000500 /* MDIO Setup */ ++#define XAE_MDIO_MCR_OFFSET 0x00000504 /* MDIO Control */ ++#define XAE_MDIO_MWD_OFFSET 0x00000508 /* MDIO Write Data */ ++#define XAE_MDIO_MRD_OFFSET 0x0000050C /* MDIO Read Data */ + #define XAE_UAW0_OFFSET 0x00000700 /* Unicast address word 0 */ + #define XAE_UAW1_OFFSET 0x00000704 /* Unicast address word 1 */ +-#define XAE_FMI_OFFSET 0x00000708 /* Filter Mask Index */ ++#define XAE_FMI_OFFSET 0x00000708 /* Frame Filter Control */ ++#define XAE_FFE_OFFSET 0x0000070C /* Frame Filter Enable */ + #define XAE_AF0_OFFSET 0x00000710 /* Address Filter 0 */ + #define XAE_AF1_OFFSET 0x00000714 /* Address Filter 1 */ + +@@ -307,7 +308,7 @@ + */ + #define XAE_UAW1_UNICASTADDR_MASK 0x0000FFFF + +-/* Bit masks for Axi Ethernet FMI register */ ++/* Bit masks for Axi Ethernet FMC register */ + #define XAE_FMI_PM_MASK 0x80000000 /* Promis. mode enable */ + #define XAE_FMI_IND_MASK 0x00000003 /* Index Mask */ + +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +index 63f33126d02fe..0ca350faa4848 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -409,7 +409,7 @@ static int netdev_set_mac_address(struct net_device *ndev, void *p) + */ + static void axienet_set_multicast_list(struct net_device *ndev) + { +- int i; ++ int i = 0; + u32 reg, af0reg, af1reg; + struct axienet_local *lp = netdev_priv(ndev); + +@@ -427,7 +427,10 @@ static void axienet_set_multicast_list(struct net_device *ndev) + } else if (!netdev_mc_empty(ndev)) { + struct netdev_hw_addr *ha; + +- i = 0; ++ reg = axienet_ior(lp, XAE_FMI_OFFSET); ++ reg &= ~XAE_FMI_PM_MASK; ++ axienet_iow(lp, XAE_FMI_OFFSET, reg); ++ + netdev_for_each_mc_addr(ha, ndev) { + if (i >= XAE_MULTICAST_CAM_TABLE_NUM) + break; +@@ -446,6 +449,7 @@ static void axienet_set_multicast_list(struct net_device *ndev) + axienet_iow(lp, XAE_FMI_OFFSET, reg); + axienet_iow(lp, XAE_AF0_OFFSET, af0reg); + axienet_iow(lp, XAE_AF1_OFFSET, af1reg); ++ axienet_iow(lp, XAE_FFE_OFFSET, 1); + i++; + } + } else { +@@ -453,18 +457,15 @@ static void axienet_set_multicast_list(struct net_device *ndev) + reg &= ~XAE_FMI_PM_MASK; + + axienet_iow(lp, XAE_FMI_OFFSET, reg); +- +- for (i = 0; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) { +- reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00; +- reg |= i; +- +- axienet_iow(lp, XAE_FMI_OFFSET, reg); +- axienet_iow(lp, XAE_AF0_OFFSET, 0); +- axienet_iow(lp, XAE_AF1_OFFSET, 0); +- } +- + dev_info(&ndev->dev, "Promiscuous mode disabled.\n"); + } ++ ++ for (; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) { ++ reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00; ++ reg |= i; ++ axienet_iow(lp, XAE_FMI_OFFSET, reg); ++ axienet_iow(lp, XAE_FFE_OFFSET, 0); ++ } + } + + /** +diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c +index 3271428e64b8c..40c94df382e54 100644 +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -572,6 +572,9 @@ static netdev_tx_t gtp_dev_xmit(struct sk_buff *skb, struct net_device *dev) + if (skb_cow_head(skb, dev->needed_headroom)) + goto tx_err; + ++ if (!pskb_inet_may_pull(skb)) ++ goto tx_err; ++ + skb_reset_inner_headers(skb); + + /* PDP context lookups in gtp_build_skb_*() need rcu read-side lock. */ +@@ -814,7 +817,7 @@ static struct sock *gtp_encap_enable_socket(int fd, int type, + sock = sockfd_lookup(fd, &err); + if (!sock) { + pr_debug("gtp socket fd=%d not found\n", fd); +- return NULL; ++ return ERR_PTR(err); + } + + sk = sock->sk; +diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +index e372f935f6983..6419fbfec5aca 100644 +--- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c ++++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +@@ -163,7 +163,11 @@ static int iwl_dbgfs_enabled_severities_write(struct iwl_fw_runtime *fwrt, + + event_cfg.enabled_severities = cpu_to_le32(enabled_severities); + +- ret = iwl_trans_send_cmd(fwrt->trans, &hcmd); ++ if (fwrt->ops && fwrt->ops->send_hcmd) ++ ret = fwrt->ops->send_hcmd(fwrt->ops_ctx, &hcmd); ++ else ++ ret = -EPERM; ++ + IWL_INFO(fwrt, + "sent host event cfg with enabled_severities: %u, ret: %d\n", + enabled_severities, ret); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +index 8179a7395bcaf..4bab14ceef5f5 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +@@ -3068,7 +3068,7 @@ int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify) + if (!(mvm->scan_status & type)) + return 0; + +- if (iwl_mvm_is_radio_killed(mvm)) { ++ if (!test_bit(STATUS_DEVICE_ENABLED, &mvm->trans->status)) { + ret = 0; + goto out; + } +diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +index 4257b4ca7d6e9..0273d3e5e0b5c 100644 +--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +@@ -4328,11 +4328,27 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) + if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info)) + wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); + +- wiphy->bands[NL80211_BAND_2GHZ] = &mwifiex_band_2ghz; +- if (adapter->config_bands & BAND_A) +- wiphy->bands[NL80211_BAND_5GHZ] = &mwifiex_band_5ghz; +- else ++ wiphy->bands[NL80211_BAND_2GHZ] = devm_kmemdup(adapter->dev, ++ &mwifiex_band_2ghz, ++ sizeof(mwifiex_band_2ghz), ++ GFP_KERNEL); ++ if (!wiphy->bands[NL80211_BAND_2GHZ]) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ if (adapter->config_bands & BAND_A) { ++ wiphy->bands[NL80211_BAND_5GHZ] = devm_kmemdup(adapter->dev, ++ &mwifiex_band_5ghz, ++ sizeof(mwifiex_band_5ghz), ++ GFP_KERNEL); ++ if (!wiphy->bands[NL80211_BAND_5GHZ]) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ } else { + wiphy->bands[NL80211_BAND_5GHZ] = NULL; ++ } + + if (adapter->drcs_enabled && ISSUPP_DRCS_ENABLED(adapter->fw_cap_info)) + wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta_drcs; +@@ -4425,8 +4441,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) + if (ret < 0) { + mwifiex_dbg(adapter, ERROR, + "%s: wiphy_register failed: %d\n", __func__, ret); +- wiphy_free(wiphy); +- return ret; ++ goto err; + } + + if (!adapter->regd) { +@@ -4468,4 +4483,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) + + adapter->wiphy = wiphy; + return ret; ++ ++err: ++ wiphy_free(wiphy); ++ ++ return ret; + } +diff --git a/drivers/net/wireless/st/cw1200/txrx.c b/drivers/net/wireless/st/cw1200/txrx.c +index 7de666b90ff50..9c998f4ac4a9a 100644 +--- a/drivers/net/wireless/st/cw1200/txrx.c ++++ b/drivers/net/wireless/st/cw1200/txrx.c +@@ -1170,7 +1170,7 @@ void cw1200_rx_cb(struct cw1200_common *priv, + size_t ies_len = skb->len - (ies - (u8 *)(skb->data)); + + tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len); +- if (tim_ie) { ++ if (tim_ie && tim_ie[1] >= sizeof(struct ieee80211_tim_ie)) { + struct ieee80211_tim_ie *tim = + (struct ieee80211_tim_ie *)&tim_ie[2]; + +diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c +index 939d27652a4c9..fceae9c127602 100644 +--- a/drivers/nfc/pn533/pn533.c ++++ b/drivers/nfc/pn533/pn533.c +@@ -1725,6 +1725,11 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev, + } + + pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); ++ if (!dev->poll_mod_count) { ++ nfc_err(dev->dev, ++ "Poll mod list is empty\n"); ++ return -EINVAL; ++ } + + /* Do not always start polling from the same modulation */ + get_random_bytes(&rand_mod, sizeof(rand_mod)); +diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c +index 18e082091c821..9561ba3d43138 100644 +--- a/drivers/nvme/target/rdma.c ++++ b/drivers/nvme/target/rdma.c +@@ -472,12 +472,8 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue) + return 0; + + out_free: +- while (--i >= 0) { +- struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; +- +- list_del(&rsp->free_list); +- nvmet_rdma_free_rsp(ndev, rsp); +- } ++ while (--i >= 0) ++ nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); + kfree(queue->rsps); + out: + return ret; +@@ -488,12 +484,8 @@ static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue) + struct nvmet_rdma_device *ndev = queue->dev; + int i, nr_rsps = queue->recv_queue_size * 2; + +- for (i = 0; i < nr_rsps; i++) { +- struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; +- +- list_del(&rsp->free_list); +- nvmet_rdma_free_rsp(ndev, rsp); +- } ++ for (i = 0; i < nr_rsps; i++) ++ nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); + kfree(queue->rsps); + } + +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index 8468a41322f25..df044a79a7348 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -858,6 +858,7 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue) + pr_err("bad nvme-tcp pdu length (%d)\n", + le32_to_cpu(icreq->hdr.plen)); + nvmet_tcp_fatal_error(queue); ++ return -EPROTO; + } + + if (icreq->pfv != NVME_TCP_PFV_1_0) { +diff --git a/drivers/nvme/target/trace.c b/drivers/nvme/target/trace.c +index bff454d46255b..6ee1f3db81d04 100644 +--- a/drivers/nvme/target/trace.c ++++ b/drivers/nvme/target/trace.c +@@ -211,7 +211,7 @@ const char *nvmet_trace_disk_name(struct trace_seq *p, char *name) + return ret; + } + +-const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl) ++const char *nvmet_trace_ctrl_id(struct trace_seq *p, u16 ctrl_id) + { + const char *ret = trace_seq_buffer_ptr(p); + +@@ -224,8 +224,8 @@ const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl) + * If we can know the extra data of the connect command in this stage, + * we can update this print statement later. + */ +- if (ctrl) +- trace_seq_printf(p, "%d", ctrl->cntlid); ++ if (ctrl_id) ++ trace_seq_printf(p, "%d", ctrl_id); + else + trace_seq_printf(p, "_"); + trace_seq_putc(p, 0); +diff --git a/drivers/nvme/target/trace.h b/drivers/nvme/target/trace.h +index 155334ddc13f3..89020018a0e35 100644 +--- a/drivers/nvme/target/trace.h ++++ b/drivers/nvme/target/trace.h +@@ -32,18 +32,24 @@ const char *nvmet_trace_parse_fabrics_cmd(struct trace_seq *p, u8 fctype, + nvmet_trace_parse_nvm_cmd(p, opcode, cdw10) : \ + nvmet_trace_parse_admin_cmd(p, opcode, cdw10))) + +-const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl); +-#define __print_ctrl_name(ctrl) \ +- nvmet_trace_ctrl_name(p, ctrl) ++const char *nvmet_trace_ctrl_id(struct trace_seq *p, u16 ctrl_id); ++#define __print_ctrl_id(ctrl_id) \ ++ nvmet_trace_ctrl_id(p, ctrl_id) + + const char *nvmet_trace_disk_name(struct trace_seq *p, char *name); + #define __print_disk_name(name) \ + nvmet_trace_disk_name(p, name) + + #ifndef TRACE_HEADER_MULTI_READ +-static inline struct nvmet_ctrl *nvmet_req_to_ctrl(struct nvmet_req *req) ++static inline u16 nvmet_req_to_ctrl_id(struct nvmet_req *req) + { +- return req->sq->ctrl; ++ /* ++ * The queue and controller pointers are not valid until an association ++ * has been established. ++ */ ++ if (!req->sq || !req->sq->ctrl) ++ return 0; ++ return req->sq->ctrl->cntlid; + } + + static inline void __assign_req_name(char *name, struct nvmet_req *req) +@@ -62,7 +68,7 @@ TRACE_EVENT(nvmet_req_init, + TP_ARGS(req, cmd), + TP_STRUCT__entry( + __field(struct nvme_command *, cmd) +- __field(struct nvmet_ctrl *, ctrl) ++ __field(u16, ctrl_id) + __array(char, disk, DISK_NAME_LEN) + __field(int, qid) + __field(u16, cid) +@@ -75,7 +81,7 @@ TRACE_EVENT(nvmet_req_init, + ), + TP_fast_assign( + __entry->cmd = cmd; +- __entry->ctrl = nvmet_req_to_ctrl(req); ++ __entry->ctrl_id = nvmet_req_to_ctrl_id(req); + __assign_req_name(__entry->disk, req); + __entry->qid = req->sq->qid; + __entry->cid = cmd->common.command_id; +@@ -89,7 +95,7 @@ TRACE_EVENT(nvmet_req_init, + ), + TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, " + "meta=%#llx, cmd=(%s, %s)", +- __print_ctrl_name(__entry->ctrl), ++ __print_ctrl_id(__entry->ctrl_id), + __print_disk_name(__entry->disk), + __entry->qid, __entry->cid, __entry->nsid, + __entry->flags, __entry->metadata, +@@ -103,7 +109,7 @@ TRACE_EVENT(nvmet_req_complete, + TP_PROTO(struct nvmet_req *req), + TP_ARGS(req), + TP_STRUCT__entry( +- __field(struct nvmet_ctrl *, ctrl) ++ __field(u16, ctrl_id) + __array(char, disk, DISK_NAME_LEN) + __field(int, qid) + __field(int, cid) +@@ -111,7 +117,7 @@ TRACE_EVENT(nvmet_req_complete, + __field(u16, status) + ), + TP_fast_assign( +- __entry->ctrl = nvmet_req_to_ctrl(req); ++ __entry->ctrl_id = nvmet_req_to_ctrl_id(req); + __entry->qid = req->cq->qid; + __entry->cid = req->cqe->command_id; + __entry->result = le64_to_cpu(req->cqe->result.u64); +@@ -119,7 +125,7 @@ TRACE_EVENT(nvmet_req_complete, + __assign_req_name(__entry->disk, req); + ), + TP_printk("nvmet%s: %sqid=%d, cmdid=%u, res=%#llx, status=%#x", +- __print_ctrl_name(__entry->ctrl), ++ __print_ctrl_id(__entry->ctrl_id), + __print_disk_name(__entry->disk), + __entry->qid, __entry->cid, __entry->result, __entry->status) + +diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c +index 9be9535ad7ab7..ac9a9124a36de 100644 +--- a/drivers/phy/xilinx/phy-zynqmp.c ++++ b/drivers/phy/xilinx/phy-zynqmp.c +@@ -21,6 +21,7 @@ + #include <linux/of.h> + #include <linux/phy/phy.h> + #include <linux/platform_device.h> ++#include <linux/pm_runtime.h> + #include <linux/slab.h> + + #include <dt-bindings/phy/phy.h> +@@ -80,7 +81,8 @@ + + /* Reference clock selection parameters */ + #define L0_Ln_REF_CLK_SEL(n) (0x2860 + (n) * 4) +-#define L0_REF_CLK_SEL_MASK 0x8f ++#define L0_REF_CLK_LCL_SEL BIT(7) ++#define L0_REF_CLK_SEL_MASK 0x9f + + /* Calibration digital logic parameters */ + #define L3_TM_CALIB_DIG19 0xec4c +@@ -165,6 +167,24 @@ + /* Timeout values */ + #define TIMEOUT_US 1000 + ++/* Lane 0/1/2/3 offset */ ++#define DIG_8(n) ((0x4000 * (n)) + 0x1074) ++#define ILL13(n) ((0x4000 * (n)) + 0x1994) ++#define DIG_10(n) ((0x4000 * (n)) + 0x107c) ++#define RST_DLY(n) ((0x4000 * (n)) + 0x19a4) ++#define BYP_15(n) ((0x4000 * (n)) + 0x1038) ++#define BYP_12(n) ((0x4000 * (n)) + 0x102c) ++#define MISC3(n) ((0x4000 * (n)) + 0x19ac) ++#define EQ11(n) ((0x4000 * (n)) + 0x1978) ++ ++static u32 save_reg_address[] = { ++ /* Lane 0/1/2/3 Register */ ++ DIG_8(0), ILL13(0), DIG_10(0), RST_DLY(0), BYP_15(0), BYP_12(0), MISC3(0), EQ11(0), ++ DIG_8(1), ILL13(1), DIG_10(1), RST_DLY(1), BYP_15(1), BYP_12(1), MISC3(1), EQ11(1), ++ DIG_8(2), ILL13(2), DIG_10(2), RST_DLY(2), BYP_15(2), BYP_12(2), MISC3(2), EQ11(2), ++ DIG_8(3), ILL13(3), DIG_10(3), RST_DLY(3), BYP_15(3), BYP_12(3), MISC3(3), EQ11(3), ++}; ++ + struct xpsgtr_dev; + + /** +@@ -213,6 +233,7 @@ struct xpsgtr_phy { + * @tx_term_fix: fix for GT issue + * @saved_icm_cfg0: stored value of ICM CFG0 register + * @saved_icm_cfg1: stored value of ICM CFG1 register ++ * @saved_regs: registers to be saved/restored during suspend/resume + */ + struct xpsgtr_dev { + struct device *dev; +@@ -225,6 +246,7 @@ struct xpsgtr_dev { + bool tx_term_fix; + unsigned int saved_icm_cfg0; + unsigned int saved_icm_cfg1; ++ u32 *saved_regs; + }; + + /* +@@ -298,6 +320,32 @@ static inline void xpsgtr_clr_set_phy(struct xpsgtr_phy *gtr_phy, + writel((readl(addr) & ~clr) | set, addr); + } + ++/** ++ * xpsgtr_save_lane_regs - Saves registers on suspend ++ * @gtr_dev: pointer to phy controller context structure ++ */ ++static void xpsgtr_save_lane_regs(struct xpsgtr_dev *gtr_dev) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(save_reg_address); i++) ++ gtr_dev->saved_regs[i] = xpsgtr_read(gtr_dev, ++ save_reg_address[i]); ++} ++ ++/** ++ * xpsgtr_restore_lane_regs - Restores registers on resume ++ * @gtr_dev: pointer to phy controller context structure ++ */ ++static void xpsgtr_restore_lane_regs(struct xpsgtr_dev *gtr_dev) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(save_reg_address); i++) ++ xpsgtr_write(gtr_dev, save_reg_address[i], ++ gtr_dev->saved_regs[i]); ++} ++ + /* + * Hardware Configuration + */ +@@ -349,11 +397,12 @@ static void xpsgtr_configure_pll(struct xpsgtr_phy *gtr_phy) + PLL_FREQ_MASK, ssc->pll_ref_clk); + + /* Enable lane clock sharing, if required */ +- if (gtr_phy->refclk != gtr_phy->lane) { +- /* Lane3 Ref Clock Selection Register */ ++ if (gtr_phy->refclk == gtr_phy->lane) ++ xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane), ++ L0_REF_CLK_SEL_MASK, L0_REF_CLK_LCL_SEL); ++ else + xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane), + L0_REF_CLK_SEL_MASK, 1 << gtr_phy->refclk); +- } + + /* SSC step size [7:0] */ + xpsgtr_clr_set_phy(gtr_phy, L0_PLL_SS_STEP_SIZE_0_LSB, +@@ -572,6 +621,10 @@ static int xpsgtr_phy_init(struct phy *phy) + + mutex_lock(>r_dev->gtr_mutex); + ++ /* Configure and enable the clock when peripheral phy_init call */ ++ if (clk_prepare_enable(gtr_dev->clk[gtr_phy->refclk])) ++ goto out; ++ + /* Skip initialization if not required. */ + if (!xpsgtr_phy_init_required(gtr_phy)) + goto out; +@@ -616,9 +669,13 @@ static int xpsgtr_phy_init(struct phy *phy) + static int xpsgtr_phy_exit(struct phy *phy) + { + struct xpsgtr_phy *gtr_phy = phy_get_drvdata(phy); ++ struct xpsgtr_dev *gtr_dev = gtr_phy->dev; + + gtr_phy->skip_phy_init = false; + ++ /* Ensure that disable clock only, which configure for lane */ ++ clk_disable_unprepare(gtr_dev->clk[gtr_phy->refclk]); ++ + return 0; + } + +@@ -821,34 +878,27 @@ static struct phy *xpsgtr_xlate(struct device *dev, + * Power Management + */ + +-static int __maybe_unused xpsgtr_suspend(struct device *dev) ++static int xpsgtr_runtime_suspend(struct device *dev) + { + struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev); +- unsigned int i; + + /* Save the snapshot ICM_CFG registers. */ + gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); + gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); + +- for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) +- clk_disable_unprepare(gtr_dev->clk[i]); ++ xpsgtr_save_lane_regs(gtr_dev); + + return 0; + } + +-static int __maybe_unused xpsgtr_resume(struct device *dev) ++static int xpsgtr_runtime_resume(struct device *dev) + { + struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev); + unsigned int icm_cfg0, icm_cfg1; + unsigned int i; + bool skip_phy_init; +- int err; + +- for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) { +- err = clk_prepare_enable(gtr_dev->clk[i]); +- if (err) +- goto err_clk_put; +- } ++ xpsgtr_restore_lane_regs(gtr_dev); + + icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); + icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); +@@ -869,18 +919,10 @@ static int __maybe_unused xpsgtr_resume(struct device *dev) + gtr_dev->phys[i].skip_phy_init = skip_phy_init; + + return 0; +- +-err_clk_put: +- while (i--) +- clk_disable_unprepare(gtr_dev->clk[i]); +- +- return err; + } + +-static const struct dev_pm_ops xpsgtr_pm_ops = { +- SET_SYSTEM_SLEEP_PM_OPS(xpsgtr_suspend, xpsgtr_resume) +-}; +- ++static DEFINE_RUNTIME_DEV_PM_OPS(xpsgtr_pm_ops, xpsgtr_runtime_suspend, ++ xpsgtr_runtime_resume, NULL); + /* + * Probe & Platform Driver + */ +@@ -888,7 +930,6 @@ static const struct dev_pm_ops xpsgtr_pm_ops = { + static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) + { + unsigned int refclk; +- int ret; + + for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) { + unsigned long rate; +@@ -899,19 +940,14 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) + snprintf(name, sizeof(name), "ref%u", refclk); + clk = devm_clk_get_optional(gtr_dev->dev, name); + if (IS_ERR(clk)) { +- ret = dev_err_probe(gtr_dev->dev, PTR_ERR(clk), +- "Failed to get reference clock %u\n", +- refclk); +- goto err_clk_put; ++ return dev_err_probe(gtr_dev->dev, PTR_ERR(clk), ++ "Failed to get ref clock %u\n", ++ refclk); + } + + if (!clk) + continue; + +- ret = clk_prepare_enable(clk); +- if (ret) +- goto err_clk_put; +- + gtr_dev->clk[refclk] = clk; + + /* +@@ -931,18 +967,11 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) + dev_err(gtr_dev->dev, + "Invalid rate %lu for reference clock %u\n", + rate, refclk); +- ret = -EINVAL; +- goto err_clk_put; ++ return -EINVAL; + } + } + + return 0; +- +-err_clk_put: +- while (refclk--) +- clk_disable_unprepare(gtr_dev->clk[refclk]); +- +- return ret; + } + + static int xpsgtr_probe(struct platform_device *pdev) +@@ -951,7 +980,6 @@ static int xpsgtr_probe(struct platform_device *pdev) + struct xpsgtr_dev *gtr_dev; + struct phy_provider *provider; + unsigned int port; +- unsigned int i; + int ret; + + gtr_dev = devm_kzalloc(&pdev->dev, sizeof(*gtr_dev), GFP_KERNEL); +@@ -991,8 +1019,7 @@ static int xpsgtr_probe(struct platform_device *pdev) + phy = devm_phy_create(&pdev->dev, np, &xpsgtr_phyops); + if (IS_ERR(phy)) { + dev_err(&pdev->dev, "failed to create PHY\n"); +- ret = PTR_ERR(phy); +- goto err_clk_put; ++ return PTR_ERR(phy); + } + + gtr_phy->phy = phy; +@@ -1003,16 +1030,36 @@ static int xpsgtr_probe(struct platform_device *pdev) + provider = devm_of_phy_provider_register(&pdev->dev, xpsgtr_xlate); + if (IS_ERR(provider)) { + dev_err(&pdev->dev, "registering provider failed\n"); +- ret = PTR_ERR(provider); +- goto err_clk_put; ++ return PTR_ERR(provider); + } ++ ++ pm_runtime_set_active(gtr_dev->dev); ++ pm_runtime_enable(gtr_dev->dev); ++ ++ ret = pm_runtime_resume_and_get(gtr_dev->dev); ++ if (ret < 0) { ++ pm_runtime_disable(gtr_dev->dev); ++ return ret; ++ } ++ ++ gtr_dev->saved_regs = devm_kmalloc(gtr_dev->dev, ++ sizeof(save_reg_address), ++ GFP_KERNEL); ++ if (!gtr_dev->saved_regs) ++ return -ENOMEM; ++ + return 0; ++} + +-err_clk_put: +- for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) +- clk_disable_unprepare(gtr_dev->clk[i]); ++static int xpsgtr_remove(struct platform_device *pdev) ++{ ++ struct xpsgtr_dev *gtr_dev = platform_get_drvdata(pdev); + +- return ret; ++ pm_runtime_disable(gtr_dev->dev); ++ pm_runtime_put_noidle(gtr_dev->dev); ++ pm_runtime_set_suspended(gtr_dev->dev); ++ ++ return 0; + } + + static const struct of_device_id xpsgtr_of_match[] = { +@@ -1024,10 +1071,11 @@ MODULE_DEVICE_TABLE(of, xpsgtr_of_match); + + static struct platform_driver xpsgtr_driver = { + .probe = xpsgtr_probe, ++ .remove = xpsgtr_remove, + .driver = { + .name = "xilinx-psgtr", + .of_match_table = xpsgtr_of_match, +- .pm = &xpsgtr_pm_ops, ++ .pm = pm_ptr(&xpsgtr_pm_ops), + }, + }; + +diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c +index 790467dcde4f5..f473585d93d28 100644 +--- a/drivers/pinctrl/pinctrl-rockchip.c ++++ b/drivers/pinctrl/pinctrl-rockchip.c +@@ -3218,7 +3218,7 @@ static struct rockchip_pin_bank rk3328_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, +- 0, ++ IOMUX_WIDTH_2BIT, + IOMUX_WIDTH_3BIT, + 0), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index cd23479f352a2..d32d5c5e99bcd 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -350,6 +350,8 @@ static int pcs_get_function(struct pinctrl_dev *pctldev, unsigned pin, + return -ENOTSUPP; + fselector = setting->func; + function = pinmux_generic_get_function(pctldev, fselector); ++ if (!function) ++ return -EINVAL; + *func = function->data; + if (!(*func)) { + dev_err(pcs->dev, "%s could not find function%i\n", +diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c +index 5542b768890c9..cc78687d6874c 100644 +--- a/drivers/platform/surface/aggregator/controller.c ++++ b/drivers/platform/surface/aggregator/controller.c +@@ -1354,7 +1354,8 @@ void ssam_controller_destroy(struct ssam_controller *ctrl) + if (ctrl->state == SSAM_CONTROLLER_UNINITIALIZED) + return; + +- WARN_ON(ctrl->state != SSAM_CONTROLLER_STOPPED); ++ WARN_ON(ctrl->state != SSAM_CONTROLLER_STOPPED && ++ ctrl->state != SSAM_CONTROLLER_INITIALIZED); + + /* + * Note: New events could still have been received after the previous +diff --git a/drivers/platform/x86/lg-laptop.c b/drivers/platform/x86/lg-laptop.c +index 5f9fbea8fc3c2..b374b0c7c62f6 100644 +--- a/drivers/platform/x86/lg-laptop.c ++++ b/drivers/platform/x86/lg-laptop.c +@@ -665,7 +665,7 @@ static int acpi_add(struct acpi_device *device) + default: + year = 2019; + } +- pr_info("product: %s year: %d\n", product, year); ++ pr_info("product: %s year: %d\n", product ?: "unknown", year); + + if (year >= 2019) + battery_limit_use_wmbb = 1; +diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c +index fc33474271115..f5e7929d1dc2d 100644 +--- a/drivers/s390/block/dasd.c ++++ b/drivers/s390/block/dasd.c +@@ -1622,9 +1622,15 @@ static int dasd_ese_needs_format(struct dasd_block *block, struct irb *irb) + if (!sense) + return 0; + +- return !!(sense[1] & SNS1_NO_REC_FOUND) || +- !!(sense[1] & SNS1_FILE_PROTECTED) || +- scsw_cstat(&irb->scsw) == SCHN_STAT_INCORR_LEN; ++ if (sense[1] & SNS1_NO_REC_FOUND) ++ return 1; ++ ++ if ((sense[1] & SNS1_INV_TRACK_FORMAT) && ++ scsw_is_tm(&irb->scsw) && ++ !(sense[2] & SNS2_ENV_DATA_PRESENT)) ++ return 1; ++ ++ return 0; + } + + static int dasd_ese_oos_cond(u8 *sense) +@@ -1645,7 +1651,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, + struct dasd_device *device; + unsigned long now; + int nrf_suppressed = 0; +- int fp_suppressed = 0; ++ int it_suppressed = 0; + struct request *req; + u8 *sense = NULL; + int expires; +@@ -1700,8 +1706,9 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, + */ + sense = dasd_get_sense(irb); + if (sense) { +- fp_suppressed = (sense[1] & SNS1_FILE_PROTECTED) && +- test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags); ++ it_suppressed = (sense[1] & SNS1_INV_TRACK_FORMAT) && ++ !(sense[2] & SNS2_ENV_DATA_PRESENT) && ++ test_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags); + nrf_suppressed = (sense[1] & SNS1_NO_REC_FOUND) && + test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); + +@@ -1716,7 +1723,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, + return; + } + } +- if (!(fp_suppressed || nrf_suppressed)) ++ if (!(it_suppressed || nrf_suppressed)) + device->discipline->dump_sense_dbf(device, irb, "int"); + + if (device->features & DASD_FEATURE_ERPLOG) +@@ -2474,14 +2481,17 @@ static int _dasd_sleep_on_queue(struct list_head *ccw_queue, int interruptible) + rc = 0; + list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) { + /* +- * In some cases the 'File Protected' or 'Incorrect Length' +- * error might be expected and error recovery would be +- * unnecessary in these cases. Check if the according suppress +- * bit is set. ++ * In some cases certain errors might be expected and ++ * error recovery would be unnecessary in these cases. ++ * Check if the according suppress bit is set. + */ + sense = dasd_get_sense(&cqr->irb); +- if (sense && sense[1] & SNS1_FILE_PROTECTED && +- test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags)) ++ if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) && ++ !(sense[2] & SNS2_ENV_DATA_PRESENT) && ++ test_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags)) ++ continue; ++ if (sense && (sense[1] & SNS1_NO_REC_FOUND) && ++ test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags)) + continue; + if (scsw_cstat(&cqr->irb.scsw) == 0x40 && + test_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags)) +diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c +index c2d4ea74e0d00..845f088ce97b1 100644 +--- a/drivers/s390/block/dasd_3990_erp.c ++++ b/drivers/s390/block/dasd_3990_erp.c +@@ -1401,14 +1401,8 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp) + + struct dasd_device *device = erp->startdev; + +- /* +- * In some cases the 'File Protected' error might be expected and +- * log messages shouldn't be written then. +- * Check if the according suppress bit is set. +- */ +- if (!test_bit(DASD_CQR_SUPPRESS_FP, &erp->flags)) +- dev_err(&device->cdev->dev, +- "Accessing the DASD failed because of a hardware error\n"); ++ dev_err(&device->cdev->dev, ++ "Accessing the DASD failed because of a hardware error\n"); + + return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED); + +diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c +index 59b11950fb60c..f643f455c3f3b 100644 +--- a/drivers/s390/block/dasd_eckd.c ++++ b/drivers/s390/block/dasd_eckd.c +@@ -2301,6 +2301,7 @@ dasd_eckd_analysis_ccw(struct dasd_device *device) + cqr->status = DASD_CQR_FILLED; + /* Set flags to suppress output for expected errors */ + set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); ++ set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags); + + return cqr; + } +@@ -2582,7 +2583,6 @@ dasd_eckd_build_check_tcw(struct dasd_device *base, struct format_data_t *fdata, + cqr->buildclk = get_tod_clock(); + cqr->status = DASD_CQR_FILLED; + /* Set flags to suppress output for expected errors */ +- set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags); + set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags); + + return cqr; +@@ -4131,8 +4131,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single( + + /* Set flags to suppress output for expected errors */ + if (dasd_eckd_is_ese(basedev)) { +- set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags); +- set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags); + set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); + } + +@@ -4634,9 +4632,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( + + /* Set flags to suppress output for expected errors */ + if (dasd_eckd_is_ese(basedev)) { +- set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags); +- set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags); + set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); ++ set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags); + } + + return cqr; +@@ -5806,36 +5803,32 @@ static void dasd_eckd_dump_sense(struct dasd_device *device, + { + u8 *sense = dasd_get_sense(irb); + +- if (scsw_is_tm(&irb->scsw)) { +- /* +- * In some cases the 'File Protected' or 'Incorrect Length' +- * error might be expected and log messages shouldn't be written +- * then. Check if the according suppress bit is set. +- */ +- if (sense && (sense[1] & SNS1_FILE_PROTECTED) && +- test_bit(DASD_CQR_SUPPRESS_FP, &req->flags)) +- return; +- if (scsw_cstat(&irb->scsw) == 0x40 && +- test_bit(DASD_CQR_SUPPRESS_IL, &req->flags)) +- return; ++ /* ++ * In some cases certain errors might be expected and ++ * log messages shouldn't be written then. ++ * Check if the according suppress bit is set. ++ */ ++ if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) && ++ !(sense[2] & SNS2_ENV_DATA_PRESENT) && ++ test_bit(DASD_CQR_SUPPRESS_IT, &req->flags)) ++ return; + +- dasd_eckd_dump_sense_tcw(device, req, irb); +- } else { +- /* +- * In some cases the 'Command Reject' or 'No Record Found' +- * error might be expected and log messages shouldn't be +- * written then. Check if the according suppress bit is set. +- */ +- if (sense && sense[0] & SNS0_CMD_REJECT && +- test_bit(DASD_CQR_SUPPRESS_CR, &req->flags)) +- return; ++ if (sense && sense[0] & SNS0_CMD_REJECT && ++ test_bit(DASD_CQR_SUPPRESS_CR, &req->flags)) ++ return; + +- if (sense && sense[1] & SNS1_NO_REC_FOUND && +- test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags)) +- return; ++ if (sense && sense[1] & SNS1_NO_REC_FOUND && ++ test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags)) ++ return; + ++ if (scsw_cstat(&irb->scsw) == 0x40 && ++ test_bit(DASD_CQR_SUPPRESS_IL, &req->flags)) ++ return; ++ ++ if (scsw_is_tm(&irb->scsw)) ++ dasd_eckd_dump_sense_tcw(device, req, irb); ++ else + dasd_eckd_dump_sense_ccw(device, req, irb); +- } + } + + static int dasd_eckd_reload_device(struct dasd_device *device) +diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h +index 744e14a81cc48..c71e44d49b1dd 100644 +--- a/drivers/s390/block/dasd_int.h ++++ b/drivers/s390/block/dasd_int.h +@@ -226,7 +226,7 @@ struct dasd_ccw_req { + * The following flags are used to suppress output of certain errors. + */ + #define DASD_CQR_SUPPRESS_NRF 4 /* Suppress 'No Record Found' error */ +-#define DASD_CQR_SUPPRESS_FP 5 /* Suppress 'File Protected' error*/ ++#define DASD_CQR_SUPPRESS_IT 5 /* Suppress 'Invalid Track' error*/ + #define DASD_CQR_SUPPRESS_IL 6 /* Suppress 'Incorrect Length' error */ + #define DASD_CQR_SUPPRESS_CR 7 /* Suppress 'Command Reject' error */ + +diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c +index 45f9c0736be4f..e5f28370a9039 100644 +--- a/drivers/s390/cio/idset.c ++++ b/drivers/s390/cio/idset.c +@@ -16,20 +16,21 @@ struct idset { + unsigned long bitmap[]; + }; + +-static inline unsigned long bitmap_size(int num_ssid, int num_id) ++static inline unsigned long idset_bitmap_size(int num_ssid, int num_id) + { +- return BITS_TO_LONGS(num_ssid * num_id) * sizeof(unsigned long); ++ return bitmap_size(size_mul(num_ssid, num_id)); + } + + static struct idset *idset_new(int num_ssid, int num_id) + { + struct idset *set; + +- set = vmalloc(sizeof(struct idset) + bitmap_size(num_ssid, num_id)); ++ set = vmalloc(sizeof(struct idset) + ++ idset_bitmap_size(num_ssid, num_id)); + if (set) { + set->num_ssid = num_ssid; + set->num_id = num_id; +- memset(set->bitmap, 0, bitmap_size(num_ssid, num_id)); ++ memset(set->bitmap, 0, idset_bitmap_size(num_ssid, num_id)); + } + return set; + } +@@ -41,7 +42,8 @@ void idset_free(struct idset *set) + + void idset_fill(struct idset *set) + { +- memset(set->bitmap, 0xff, bitmap_size(set->num_ssid, set->num_id)); ++ memset(set->bitmap, 0xff, ++ idset_bitmap_size(set->num_ssid, set->num_id)); + } + + static inline void idset_add(struct idset *set, int ssid, int id) +diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c +index 355b16f0b1456..34e45c87cae03 100644 +--- a/drivers/scsi/aacraid/comminit.c ++++ b/drivers/scsi/aacraid/comminit.c +@@ -642,6 +642,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) + + if (aac_comm_init(dev)<0){ + kfree(dev->queues); ++ dev->queues = NULL; + return NULL; + } + /* +@@ -649,6 +650,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) + */ + if (aac_fib_setup(dev) < 0) { + kfree(dev->queues); ++ dev->queues = NULL; + return NULL; + } + +diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c +index 30bc72324f068..68b015bb6d157 100644 +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -7490,7 +7490,7 @@ lpfc_sli4_repost_sgl_list(struct lpfc_hba *phba, + struct lpfc_sglq *sglq_entry = NULL; + struct lpfc_sglq *sglq_entry_next = NULL; + struct lpfc_sglq *sglq_entry_first = NULL; +- int status, total_cnt; ++ int status = 0, total_cnt; + int post_cnt = 0, num_posted = 0, block_cnt = 0; + int last_xritag = NO_XRI; + LIST_HEAD(prep_sgl_list); +diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c +index bd72c38d7bfc4..5c43d0ec95a77 100644 +--- a/drivers/scsi/scsi_transport_spi.c ++++ b/drivers/scsi/scsi_transport_spi.c +@@ -677,10 +677,10 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer, + for (r = 0; r < retries; r++) { + result = spi_execute(sdev, spi_write_buffer, DMA_TO_DEVICE, + buffer, len, &sshdr); +- if(result || !scsi_device_online(sdev)) { ++ if (result || !scsi_device_online(sdev)) { + + scsi_device_set_state(sdev, SDEV_QUIESCE); +- if (scsi_sense_valid(&sshdr) ++ if (result > 0 && scsi_sense_valid(&sshdr) + && sshdr.sense_key == ILLEGAL_REQUEST + /* INVALID FIELD IN CDB */ + && sshdr.asc == 0x24 && sshdr.ascq == 0x00) +diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c +index b4803f2fde5ea..6cb5e3956fc52 100644 +--- a/drivers/soc/qcom/cmd-db.c ++++ b/drivers/soc/qcom/cmd-db.c +@@ -350,7 +350,7 @@ static int cmd_db_dev_probe(struct platform_device *pdev) + return -EINVAL; + } + +- cmd_db_header = memremap(rmem->base, rmem->size, MEMREMAP_WB); ++ cmd_db_header = memremap(rmem->base, rmem->size, MEMREMAP_WC); + if (!cmd_db_header) { + ret = -ENOMEM; + cmd_db_header = NULL; +diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c +index 8f9f4ee7860c7..558725e50121a 100644 +--- a/drivers/soundwire/stream.c ++++ b/drivers/soundwire/stream.c +@@ -1445,18 +1445,18 @@ struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave, + unsigned int port_num) + { + struct sdw_dpn_prop *dpn_prop; +- u8 num_ports; ++ unsigned long mask; + int i; + + if (direction == SDW_DATA_DIR_TX) { +- num_ports = hweight32(slave->prop.source_ports); ++ mask = slave->prop.source_ports; + dpn_prop = slave->prop.src_dpn_prop; + } else { +- num_ports = hweight32(slave->prop.sink_ports); ++ mask = slave->prop.sink_ports; + dpn_prop = slave->prop.sink_dpn_prop; + } + +- for (i = 0; i < num_ports; i++) { ++ for_each_set_bit(i, &mask, 32) { + if (dpn_prop[i].num == port_num) + return &dpn_prop[i]; + } +diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c +index 8a93c83cb6f80..d52e91258e989 100644 +--- a/drivers/ssb/main.c ++++ b/drivers/ssb/main.c +@@ -837,7 +837,7 @@ static u32 clkfactor_f6_resolve(u32 v) + case SSB_CHIPCO_CLK_F6_7: + return 7; + } +- return 0; ++ return 1; + } + + /* Calculate the speed the backplane would run at a given set of clockcontrol values */ +diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c +index a19cfb2998c93..f19bb5c796cf7 100644 +--- a/drivers/staging/iio/resolver/ad2s1210.c ++++ b/drivers/staging/iio/resolver/ad2s1210.c +@@ -658,9 +658,6 @@ static int ad2s1210_probe(struct spi_device *spi) + if (!indio_dev) + return -ENOMEM; + st = iio_priv(indio_dev); +- ret = ad2s1210_setup_gpios(st); +- if (ret < 0) +- return ret; + + spi_set_drvdata(spi, indio_dev); + +@@ -671,6 +668,10 @@ static int ad2s1210_probe(struct spi_device *spi) + st->resolution = 12; + st->fexcit = AD2S1210_DEF_EXCIT; + ++ ret = ad2s1210_setup_gpios(st); ++ if (ret < 0) ++ return ret; ++ + indio_dev->info = &ad2s1210_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad2s1210_channels; +diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c +index 98d759e7cc957..a4f3a7a79422b 100644 +--- a/drivers/staging/ks7010/ks7010_sdio.c ++++ b/drivers/staging/ks7010/ks7010_sdio.c +@@ -395,9 +395,9 @@ int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p, unsigned long size, + priv->hostt.buff[priv->hostt.qtail] = le16_to_cpu(hdr->event); + priv->hostt.qtail = (priv->hostt.qtail + 1) % SME_EVENT_BUFF_SIZE; + +- spin_lock(&priv->tx_dev.tx_dev_lock); ++ spin_lock_bh(&priv->tx_dev.tx_dev_lock); + result = enqueue_txdev(priv, p, size, complete_handler, skb); +- spin_unlock(&priv->tx_dev.tx_dev_lock); ++ spin_unlock_bh(&priv->tx_dev.tx_dev_lock); + + if (txq_has_space(priv)) + queue_delayed_work(priv->wq, &priv->rw_dwork, 0); +diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c +index fdfed54e62f34..b9bdbc8b7b183 100644 +--- a/drivers/thunderbolt/switch.c ++++ b/drivers/thunderbolt/switch.c +@@ -2877,6 +2877,7 @@ void tb_switch_remove(struct tb_switch *sw) + tb_switch_remove(port->remote->sw); + port->remote = NULL; + } else if (port->xdomain) { ++ port->xdomain->is_unplugged = true; + tb_xdomain_remove(port->xdomain); + port->xdomain = NULL; + } +diff --git a/drivers/usb/cdns3/cdnsp-gadget.h b/drivers/usb/cdns3/cdnsp-gadget.h +index f740fa6089d85..a61aef0dc273c 100644 +--- a/drivers/usb/cdns3/cdnsp-gadget.h ++++ b/drivers/usb/cdns3/cdnsp-gadget.h +@@ -811,6 +811,7 @@ struct cdnsp_stream_info { + * generate Missed Service Error Event. + * Set skip flag when receive a Missed Service Error Event and + * process the missed tds on the endpoint ring. ++ * @wa1_nop_trb: hold pointer to NOP trb. + */ + struct cdnsp_ep { + struct usb_ep endpoint; +@@ -838,6 +839,8 @@ struct cdnsp_ep { + #define EP_UNCONFIGURED BIT(7) + + bool skip; ++ union cdnsp_trb *wa1_nop_trb; ++ + }; + + /** +diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c +index 8a2cc0405a4ad..04e8db773a825 100644 +--- a/drivers/usb/cdns3/cdnsp-ring.c ++++ b/drivers/usb/cdns3/cdnsp-ring.c +@@ -402,7 +402,7 @@ static u64 cdnsp_get_hw_deq(struct cdnsp_device *pdev, + struct cdnsp_stream_ctx *st_ctx; + struct cdnsp_ep *pep; + +- pep = &pdev->eps[stream_id]; ++ pep = &pdev->eps[ep_index]; + + if (pep->ep_state & EP_HAS_STREAMS) { + st_ctx = &pep->stream_info.stream_ctx_array[stream_id]; +@@ -1902,6 +1902,23 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq) + if (ret) + return ret; + ++ /* ++ * workaround 1: STOP EP command on LINK TRB with TC bit set to 1 ++ * causes that internal cycle bit can have incorrect state after ++ * command complete. In consequence empty transfer ring can be ++ * incorrectly detected when EP is resumed. ++ * NOP TRB before LINK TRB avoid such scenario. STOP EP command is ++ * then on NOP TRB and internal cycle bit is not changed and have ++ * correct value. ++ */ ++ if (pep->wa1_nop_trb) { ++ field = le32_to_cpu(pep->wa1_nop_trb->trans_event.flags); ++ field ^= TRB_CYCLE; ++ ++ pep->wa1_nop_trb->trans_event.flags = cpu_to_le32(field); ++ pep->wa1_nop_trb = NULL; ++ } ++ + /* + * Don't give the first TRB to the hardware (by toggling the cycle bit) + * until we've finished creating all the other TRBs. The ring's cycle +@@ -1997,6 +2014,17 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq) + send_addr = addr; + } + ++ if (cdnsp_trb_is_link(ring->enqueue + 1)) { ++ field = TRB_TYPE(TRB_TR_NOOP) | TRB_IOC; ++ if (!ring->cycle_state) ++ field |= TRB_CYCLE; ++ ++ pep->wa1_nop_trb = ring->enqueue; ++ ++ cdnsp_queue_trb(pdev, ring, 0, 0x0, 0x0, ++ TRB_INTR_TARGET(0), field); ++ } ++ + cdnsp_check_trb_math(preq, enqd_len); + ret = cdnsp_giveback_first_trb(pdev, pep, preq->request.stream_id, + start_cycle, start_trb); +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index f21fd809e44ff..2957a17b185e7 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1741,6 +1741,9 @@ static const struct usb_device_id acm_ids[] = { + { USB_DEVICE(0x11ca, 0x0201), /* VeriFone Mx870 Gadget Serial */ + .driver_info = SINGLE_RX_URB, + }, ++ { USB_DEVICE(0x1901, 0x0006), /* GE Healthcare Patient Monitor UI Controller */ ++ .driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */ ++ }, + { USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, +diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c +index c9501907f7eb6..585ef71b9318b 100644 +--- a/drivers/usb/core/sysfs.c ++++ b/drivers/usb/core/sysfs.c +@@ -670,6 +670,7 @@ static int add_power_attributes(struct device *dev) + + static void remove_power_attributes(struct device *dev) + { ++ sysfs_unmerge_group(&dev->kobj, &usb3_hardware_lpm_attr_group); + sysfs_unmerge_group(&dev->kobj, &usb2_hardware_lpm_attr_group); + sysfs_unmerge_group(&dev->kobj, &power_attr_group); + } +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 1dc417da1a0fe..de9b638c207ac 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -430,6 +430,13 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) + static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) + { + struct dwc3_event_buffer *evt; ++ unsigned int hw_mode; ++ ++ hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); ++ if (hw_mode == DWC3_GHWPARAMS0_MODE_HOST) { ++ dwc->ev_buf = NULL; ++ return 0; ++ } + + evt = dwc3_alloc_one_event_buffer(dwc, length); + if (IS_ERR(evt)) { +@@ -451,6 +458,9 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) + { + struct dwc3_event_buffer *evt; + ++ if (!dwc->ev_buf) ++ return 0; ++ + evt = dwc->ev_buf; + evt->lpos = 0; + dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), +@@ -467,6 +477,17 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) + void dwc3_event_buffers_cleanup(struct dwc3 *dwc) + { + struct dwc3_event_buffer *evt; ++ u32 reg; ++ ++ if (!dwc->ev_buf) ++ return; ++ /* ++ * Exynos platforms may not be able to access event buffer if the ++ * controller failed to halt on dwc3_core_exit(). ++ */ ++ reg = dwc3_readl(dwc->regs, DWC3_DSTS); ++ if (!(reg & DWC3_DSTS_DEVCTRLHLT)) ++ return; + + evt = dwc->ev_buf; + +diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c +index efaf0db595f46..6b59bbb22da49 100644 +--- a/drivers/usb/dwc3/dwc3-omap.c ++++ b/drivers/usb/dwc3/dwc3-omap.c +@@ -522,11 +522,13 @@ static int dwc3_omap_probe(struct platform_device *pdev) + if (ret) { + dev_err(dev, "failed to request IRQ #%d --> %d\n", + omap->irq, ret); +- goto err1; ++ goto err2; + } + dwc3_omap_enable_irqs(omap); + return 0; + ++err2: ++ of_platform_depopulate(dev); + err1: + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); +diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c +index 166b5bde45cbc..14c86fe006489 100644 +--- a/drivers/usb/dwc3/dwc3-st.c ++++ b/drivers/usb/dwc3/dwc3-st.c +@@ -219,10 +219,8 @@ static int st_dwc3_probe(struct platform_device *pdev) + dwc3_data->regmap = regmap; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "syscfg-reg"); +- if (!res) { +- ret = -ENXIO; +- goto undo_platform_dev_alloc; +- } ++ if (!res) ++ return -ENXIO; + + dwc3_data->syscfg_reg_off = res->start; + +@@ -233,8 +231,7 @@ static int st_dwc3_probe(struct platform_device *pdev) + devm_reset_control_get_exclusive(dev, "powerdown"); + if (IS_ERR(dwc3_data->rstc_pwrdn)) { + dev_err(&pdev->dev, "could not get power controller\n"); +- ret = PTR_ERR(dwc3_data->rstc_pwrdn); +- goto undo_platform_dev_alloc; ++ return PTR_ERR(dwc3_data->rstc_pwrdn); + } + + /* Manage PowerDown */ +@@ -269,7 +266,7 @@ static int st_dwc3_probe(struct platform_device *pdev) + if (!child_pdev) { + dev_err(dev, "failed to find dwc3 core device\n"); + ret = -ENODEV; +- goto err_node_put; ++ goto depopulate; + } + + dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev); +@@ -285,6 +282,7 @@ static int st_dwc3_probe(struct platform_device *pdev) + ret = st_dwc3_drd_init(dwc3_data); + if (ret) { + dev_err(dev, "drd initialisation failed\n"); ++ of_platform_depopulate(dev); + goto undo_softreset; + } + +@@ -294,14 +292,14 @@ static int st_dwc3_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, dwc3_data); + return 0; + ++depopulate: ++ of_platform_depopulate(dev); + err_node_put: + of_node_put(child); + undo_softreset: + reset_control_assert(dwc3_data->rstc_rst); + undo_powerdown: + reset_control_assert(dwc3_data->rstc_pwrdn); +-undo_platform_dev_alloc: +- platform_device_put(pdev); + return ret; + } + +diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c +index 29fcb9b461d71..abe7c9a6ce234 100644 +--- a/drivers/usb/gadget/udc/fsl_udc_core.c ++++ b/drivers/usb/gadget/udc/fsl_udc_core.c +@@ -2485,7 +2485,7 @@ static int fsl_udc_probe(struct platform_device *pdev) + /* setup the udc->eps[] for non-control endpoints and link + * to gadget.ep_list */ + for (i = 1; i < (int)(udc_controller->max_ep / 2); i++) { +- char name[14]; ++ char name[16]; + + sprintf(name, "ep%dout", i); + struct_ep_setup(udc_controller, i * 2, name, 1); +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 2539d97b90c31..fa1efed0a5fc2 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -2954,7 +2954,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, + xhci->num_active_eps); + return -ENOMEM; + } +- if ((xhci->quirks & XHCI_SW_BW_CHECKING) && ++ if ((xhci->quirks & XHCI_SW_BW_CHECKING) && !ctx_change && + xhci_reserve_bandwidth(xhci, virt_dev, command->in_ctx)) { + if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) + xhci_free_host_resources(xhci, ctrl_ctx); +@@ -4294,8 +4294,10 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, + mutex_unlock(&xhci->mutex); + ret = xhci_disable_slot(xhci, udev->slot_id); + xhci_free_virt_device(xhci, udev->slot_id); +- if (!ret) +- xhci_alloc_dev(hcd, udev); ++ if (!ret) { ++ if (xhci_alloc_dev(hcd, udev) == 1) ++ xhci_setup_addressable_virt_dev(xhci, udev); ++ } + kfree(command->completion); + kfree(command); + return -EPROTO; +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index cb0eb7fd25426..d34458f11d825 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -619,6 +619,8 @@ static void option_instat_callback(struct urb *urb); + + /* MeiG Smart Technology products */ + #define MEIGSMART_VENDOR_ID 0x2dee ++/* MeiG Smart SRM825L based on Qualcomm 315 */ ++#define MEIGSMART_PRODUCT_SRM825L 0x4d22 + /* MeiG Smart SLM320 based on UNISOC UIS8910 */ + #define MEIGSMART_PRODUCT_SLM320 0x4d41 + +@@ -2366,6 +2368,9 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +diff --git a/fs/afs/file.c b/fs/afs/file.c +index b165377179c3c..6774e1fcf7c5c 100644 +--- a/fs/afs/file.c ++++ b/fs/afs/file.c +@@ -512,13 +512,17 @@ static void afs_add_open_mmap(struct afs_vnode *vnode) + + static void afs_drop_open_mmap(struct afs_vnode *vnode) + { +- if (!atomic_dec_and_test(&vnode->cb_nr_mmap)) ++ if (atomic_add_unless(&vnode->cb_nr_mmap, -1, 1)) + return; + + down_write(&vnode->volume->cell->fs_open_mmaps_lock); + +- if (atomic_read(&vnode->cb_nr_mmap) == 0) ++ read_seqlock_excl(&vnode->cb_lock); ++ // the only place where ->cb_nr_mmap may hit 0 ++ // see __afs_break_callback() for the other side... ++ if (atomic_dec_and_test(&vnode->cb_nr_mmap)) + list_del_init(&vnode->cb_mmap_link); ++ read_sequnlock_excl(&vnode->cb_lock); + + up_write(&vnode->volume->cell->fs_open_mmaps_lock); + flush_work(&vnode->cb_work); +diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c +index f51f6e4d1a322..a7084a720b28c 100644 +--- a/fs/binfmt_elf_fdpic.c ++++ b/fs/binfmt_elf_fdpic.c +@@ -320,7 +320,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) + else + executable_stack = EXSTACK_DEFAULT; + +- if (stack_size == 0) { ++ if (stack_size == 0 && interp_params.flags & ELF_FDPIC_FLAG_PRESENT) { + stack_size = interp_params.stack_size; + if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK) + executable_stack = EXSTACK_ENABLE_X; +diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c +index bb202ad369d53..740dac1012ae8 100644 +--- a/fs/binfmt_misc.c ++++ b/fs/binfmt_misc.c +@@ -60,12 +60,11 @@ typedef struct { + char *name; + struct dentry *dentry; + struct file *interp_file; ++ refcount_t users; /* sync removal with load_misc_binary() */ + } Node; + + static DEFINE_RWLOCK(entries_lock); + static struct file_system_type bm_fs_type; +-static struct vfsmount *bm_mnt; +-static int entry_count; + + /* + * Max length of the register string. Determined by: +@@ -82,19 +81,23 @@ static int entry_count; + */ + #define MAX_REGISTER_LENGTH 1920 + +-/* +- * Check if we support the binfmt +- * if we do, return the node, else NULL +- * locking is done in load_misc_binary ++/** ++ * search_binfmt_handler - search for a binary handler for @bprm ++ * @misc: handle to binfmt_misc instance ++ * @bprm: binary for which we are looking for a handler ++ * ++ * Search for a binary type handler for @bprm in the list of registered binary ++ * type handlers. ++ * ++ * Return: binary type list entry on success, NULL on failure + */ +-static Node *check_file(struct linux_binprm *bprm) ++static Node *search_binfmt_handler(struct linux_binprm *bprm) + { + char *p = strrchr(bprm->interp, '.'); +- struct list_head *l; ++ Node *e; + + /* Walk all the registered handlers. */ +- list_for_each(l, &entries) { +- Node *e = list_entry(l, Node, list); ++ list_for_each_entry(e, &entries, list) { + char *s; + int j; + +@@ -123,9 +126,49 @@ static Node *check_file(struct linux_binprm *bprm) + if (j == e->size) + return e; + } ++ + return NULL; + } + ++/** ++ * get_binfmt_handler - try to find a binary type handler ++ * @misc: handle to binfmt_misc instance ++ * @bprm: binary for which we are looking for a handler ++ * ++ * Try to find a binfmt handler for the binary type. If one is found take a ++ * reference to protect against removal via bm_{entry,status}_write(). ++ * ++ * Return: binary type list entry on success, NULL on failure ++ */ ++static Node *get_binfmt_handler(struct linux_binprm *bprm) ++{ ++ Node *e; ++ ++ read_lock(&entries_lock); ++ e = search_binfmt_handler(bprm); ++ if (e) ++ refcount_inc(&e->users); ++ read_unlock(&entries_lock); ++ return e; ++} ++ ++/** ++ * put_binfmt_handler - put binary handler node ++ * @e: node to put ++ * ++ * Free node syncing with load_misc_binary() and defer final free to ++ * load_misc_binary() in case it is using the binary type handler we were ++ * requested to remove. ++ */ ++static void put_binfmt_handler(Node *e) ++{ ++ if (refcount_dec_and_test(&e->users)) { ++ if (e->flags & MISC_FMT_OPEN_FILE) ++ filp_close(e->interp_file, NULL); ++ kfree(e); ++ } ++} ++ + /* + * the loader itself + */ +@@ -139,12 +182,7 @@ static int load_misc_binary(struct linux_binprm *bprm) + if (!enabled) + return retval; + +- /* to keep locking time low, we copy the interpreter string */ +- read_lock(&entries_lock); +- fmt = check_file(bprm); +- if (fmt) +- dget(fmt->dentry); +- read_unlock(&entries_lock); ++ fmt = get_binfmt_handler(bprm); + if (!fmt) + return retval; + +@@ -198,7 +236,16 @@ static int load_misc_binary(struct linux_binprm *bprm) + + retval = 0; + ret: +- dput(fmt->dentry); ++ ++ /* ++ * If we actually put the node here all concurrent calls to ++ * load_misc_binary() will have finished. We also know ++ * that for the refcount to be zero ->evict_inode() must have removed ++ * the node to be deleted from the list. All that is left for us is to ++ * close and free. ++ */ ++ put_binfmt_handler(fmt); ++ + return retval; + } + +@@ -553,30 +600,90 @@ static struct inode *bm_get_inode(struct super_block *sb, int mode) + return inode; + } + ++/** ++ * bm_evict_inode - cleanup data associated with @inode ++ * @inode: inode to which the data is attached ++ * ++ * Cleanup the binary type handler data associated with @inode if a binary type ++ * entry is removed or the filesystem is unmounted and the super block is ++ * shutdown. ++ * ++ * If the ->evict call was not caused by a super block shutdown but by a write ++ * to remove the entry or all entries via bm_{entry,status}_write() the entry ++ * will have already been removed from the list. We keep the list_empty() check ++ * to make that explicit. ++*/ + static void bm_evict_inode(struct inode *inode) + { + Node *e = inode->i_private; + +- if (e && e->flags & MISC_FMT_OPEN_FILE) +- filp_close(e->interp_file, NULL); +- + clear_inode(inode); +- kfree(e); ++ ++ if (e) { ++ write_lock(&entries_lock); ++ if (!list_empty(&e->list)) ++ list_del_init(&e->list); ++ write_unlock(&entries_lock); ++ put_binfmt_handler(e); ++ } + } + +-static void kill_node(Node *e) ++/** ++ * unlink_binfmt_dentry - remove the dentry for the binary type handler ++ * @dentry: dentry associated with the binary type handler ++ * ++ * Do the actual filesystem work to remove a dentry for a registered binary ++ * type handler. Since binfmt_misc only allows simple files to be created ++ * directly under the root dentry of the filesystem we ensure that we are ++ * indeed passed a dentry directly beneath the root dentry, that the inode ++ * associated with the root dentry is locked, and that it is a regular file we ++ * are asked to remove. ++ */ ++static void unlink_binfmt_dentry(struct dentry *dentry) + { +- struct dentry *dentry; ++ struct dentry *parent = dentry->d_parent; ++ struct inode *inode, *parent_inode; ++ ++ /* All entries are immediate descendants of the root dentry. */ ++ if (WARN_ON_ONCE(dentry->d_sb->s_root != parent)) ++ return; + ++ /* We only expect to be called on regular files. */ ++ inode = d_inode(dentry); ++ if (WARN_ON_ONCE(!S_ISREG(inode->i_mode))) ++ return; ++ ++ /* The parent inode must be locked. */ ++ parent_inode = d_inode(parent); ++ if (WARN_ON_ONCE(!inode_is_locked(parent_inode))) ++ return; ++ ++ if (simple_positive(dentry)) { ++ dget(dentry); ++ simple_unlink(parent_inode, dentry); ++ d_delete(dentry); ++ dput(dentry); ++ } ++} ++ ++/** ++ * remove_binfmt_handler - remove a binary type handler ++ * @misc: handle to binfmt_misc instance ++ * @e: binary type handler to remove ++ * ++ * Remove a binary type handler from the list of binary type handlers and ++ * remove its associated dentry. This is called from ++ * binfmt_{entry,status}_write(). In the future, we might want to think about ++ * adding a proper ->unlink() method to binfmt_misc instead of forcing caller's ++ * to use writes to files in order to delete binary type handlers. But it has ++ * worked for so long that it's not a pressing issue. ++ */ ++static void remove_binfmt_handler(Node *e) ++{ + write_lock(&entries_lock); + list_del_init(&e->list); + write_unlock(&entries_lock); +- +- dentry = e->dentry; +- drop_nlink(d_inode(dentry)); +- d_drop(dentry); +- dput(dentry); +- simple_release_fs(&bm_mnt, &entry_count); ++ unlink_binfmt_dentry(e->dentry); + } + + /* /<entry> */ +@@ -603,8 +710,8 @@ bm_entry_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) + static ssize_t bm_entry_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) + { +- struct dentry *root; +- Node *e = file_inode(file)->i_private; ++ struct inode *inode = file_inode(file); ++ Node *e = inode->i_private; + int res = parse_command(buffer, count); + + switch (res) { +@@ -618,13 +725,22 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer, + break; + case 3: + /* Delete this handler. */ +- root = file_inode(file)->i_sb->s_root; +- inode_lock(d_inode(root)); ++ inode = d_inode(inode->i_sb->s_root); ++ inode_lock(inode); + ++ /* ++ * In order to add new element or remove elements from the list ++ * via bm_{entry,register,status}_write() inode_lock() on the ++ * root inode must be held. ++ * The lock is exclusive ensuring that the list can't be ++ * modified. Only load_misc_binary() can access but does so ++ * read-only. So we only need to take the write lock when we ++ * actually remove the entry from the list. ++ */ + if (!list_empty(&e->list)) +- kill_node(e); ++ remove_binfmt_handler(e); + +- inode_unlock(d_inode(root)); ++ inode_unlock(inode); + break; + default: + return res; +@@ -683,13 +799,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, + if (!inode) + goto out2; + +- err = simple_pin_fs(&bm_fs_type, &bm_mnt, &entry_count); +- if (err) { +- iput(inode); +- inode = NULL; +- goto out2; +- } +- ++ refcount_set(&e->users, 1); + e->dentry = dget(dentry); + inode->i_private = e; + inode->i_fop = &bm_entry_operations; +@@ -733,7 +843,8 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) + { + int res = parse_command(buffer, count); +- struct dentry *root; ++ Node *e, *next; ++ struct inode *inode; + + switch (res) { + case 1: +@@ -746,13 +857,22 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer, + break; + case 3: + /* Delete all handlers. */ +- root = file_inode(file)->i_sb->s_root; +- inode_lock(d_inode(root)); ++ inode = d_inode(file_inode(file)->i_sb->s_root); ++ inode_lock(inode); + +- while (!list_empty(&entries)) +- kill_node(list_first_entry(&entries, Node, list)); ++ /* ++ * In order to add new element or remove elements from the list ++ * via bm_{entry,register,status}_write() inode_lock() on the ++ * root inode must be held. ++ * The lock is exclusive ensuring that the list can't be ++ * modified. Only load_misc_binary() can access but does so ++ * read-only. So we only need to take the write lock when we ++ * actually remove the entry from the list. ++ */ ++ list_for_each_entry_safe(e, next, &entries, list) ++ remove_binfmt_handler(e); + +- inode_unlock(d_inode(root)); ++ inode_unlock(inode); + break; + default: + return res; +diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c +index 8d8b455992362..fa4a5053ca89a 100644 +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -901,7 +901,7 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node) + + if (delayed_node && + test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) { +- BUG_ON(!delayed_node->root); ++ ASSERT(delayed_node->root); + clear_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags); + delayed_node->count--; + +diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c +index 0004488eeb060..ed8729c990883 100644 +--- a/fs/btrfs/free-space-cache.c ++++ b/fs/btrfs/free-space-cache.c +@@ -1787,9 +1787,9 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, + ctl->free_space -= bytes; + } + +-static void bitmap_set_bits(struct btrfs_free_space_ctl *ctl, +- struct btrfs_free_space *info, u64 offset, +- u64 bytes) ++static void btrfs_bitmap_set_bits(struct btrfs_free_space_ctl *ctl, ++ struct btrfs_free_space *info, u64 offset, ++ u64 bytes) + { + unsigned long start, count, end; + int extent_delta = 1; +@@ -2085,7 +2085,7 @@ static u64 add_bytes_to_bitmap(struct btrfs_free_space_ctl *ctl, + + bytes_to_set = min(end - offset, bytes); + +- bitmap_set_bits(ctl, info, offset, bytes_to_set); ++ btrfs_bitmap_set_bits(ctl, info, offset, bytes_to_set); + + /* + * We set some bytes, we have no idea what the max extent size is +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 07c6ab4ba0d43..66b56ddf3f4cc 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -4411,7 +4411,14 @@ static noinline int may_destroy_subvol(struct btrfs_root *root) + ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, path, 0, 0); + if (ret < 0) + goto out; +- BUG_ON(ret == 0); ++ if (ret == 0) { ++ /* ++ * Key with offset -1 found, there would have to exist a root ++ * with such id, but this is out of valid range. ++ */ ++ ret = -EUCLEAN; ++ goto out; ++ } + + ret = 0; + if (path->slots[0] > 0) { +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index 1f5ab51e18dc4..6cff41c46d02e 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -2648,8 +2648,6 @@ int btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, u64 bytenr, + if (nr_old_roots == 0 && nr_new_roots == 0) + goto out_free; + +- BUG_ON(!fs_info->quota_root); +- + trace_btrfs_qgroup_account_extent(fs_info, trans->transid, bytenr, + num_bytes, nr_old_roots, nr_new_roots); + +@@ -3679,6 +3677,8 @@ static int try_flush_qgroup(struct btrfs_root *root) + return 0; + } + ++ btrfs_run_delayed_iputs(root->fs_info); ++ btrfs_wait_on_delayed_iputs(root->fs_info); + ret = btrfs_start_delalloc_snapshot(root, true); + if (ret < 0) + goto out; +diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c +index c2842e892e4ed..577980b33aeb7 100644 +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -695,7 +695,12 @@ static int begin_cmd(struct send_ctx *sctx, int cmd) + if (WARN_ON(!sctx->send_buf)) + return -EINVAL; + +- BUG_ON(sctx->send_size); ++ if (unlikely(sctx->send_size != 0)) { ++ btrfs_err(sctx->send_root->fs_info, ++ "send: command header buffer not empty cmd %d offset %llu", ++ cmd, sctx->send_off); ++ return -EINVAL; ++ } + + sctx->send_size += sizeof(*hdr); + hdr = (struct btrfs_cmd_header *)sctx->send_buf; +@@ -6877,8 +6882,8 @@ static int tree_move_down(struct btrfs_path *path, int *level, u64 reada_min_gen + u64 reada_done = 0; + + lockdep_assert_held_read(&parent->fs_info->commit_root_sem); ++ ASSERT(*level != 0); + +- BUG_ON(*level == 0); + eb = btrfs_read_node_slot(parent, slot); + if (IS_ERR(eb)) + return PTR_ERR(eb); +diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c +index a190ae887bdc0..97f3c83e6aebb 100644 +--- a/fs/btrfs/tree-checker.c ++++ b/fs/btrfs/tree-checker.c +@@ -1596,6 +1596,72 @@ static int check_inode_ref(struct extent_buffer *leaf, + return 0; + } + ++static int check_dev_extent_item(const struct extent_buffer *leaf, ++ const struct btrfs_key *key, ++ int slot, ++ struct btrfs_key *prev_key) ++{ ++ struct btrfs_dev_extent *de; ++ const u32 sectorsize = leaf->fs_info->sectorsize; ++ ++ de = btrfs_item_ptr(leaf, slot, struct btrfs_dev_extent); ++ /* Basic fixed member checks. */ ++ if (unlikely(btrfs_dev_extent_chunk_tree(leaf, de) != ++ BTRFS_CHUNK_TREE_OBJECTID)) { ++ generic_err(leaf, slot, ++ "invalid dev extent chunk tree id, has %llu expect %llu", ++ btrfs_dev_extent_chunk_tree(leaf, de), ++ BTRFS_CHUNK_TREE_OBJECTID); ++ return -EUCLEAN; ++ } ++ if (unlikely(btrfs_dev_extent_chunk_objectid(leaf, de) != ++ BTRFS_FIRST_CHUNK_TREE_OBJECTID)) { ++ generic_err(leaf, slot, ++ "invalid dev extent chunk objectid, has %llu expect %llu", ++ btrfs_dev_extent_chunk_objectid(leaf, de), ++ BTRFS_FIRST_CHUNK_TREE_OBJECTID); ++ return -EUCLEAN; ++ } ++ /* Alignment check. */ ++ if (unlikely(!IS_ALIGNED(key->offset, sectorsize))) { ++ generic_err(leaf, slot, ++ "invalid dev extent key.offset, has %llu not aligned to %u", ++ key->offset, sectorsize); ++ return -EUCLEAN; ++ } ++ if (unlikely(!IS_ALIGNED(btrfs_dev_extent_chunk_offset(leaf, de), ++ sectorsize))) { ++ generic_err(leaf, slot, ++ "invalid dev extent chunk offset, has %llu not aligned to %u", ++ btrfs_dev_extent_chunk_objectid(leaf, de), ++ sectorsize); ++ return -EUCLEAN; ++ } ++ if (unlikely(!IS_ALIGNED(btrfs_dev_extent_length(leaf, de), ++ sectorsize))) { ++ generic_err(leaf, slot, ++ "invalid dev extent length, has %llu not aligned to %u", ++ btrfs_dev_extent_length(leaf, de), sectorsize); ++ return -EUCLEAN; ++ } ++ /* Overlap check with previous dev extent. */ ++ if (slot && prev_key->objectid == key->objectid && ++ prev_key->type == key->type) { ++ struct btrfs_dev_extent *prev_de; ++ u64 prev_len; ++ ++ prev_de = btrfs_item_ptr(leaf, slot - 1, struct btrfs_dev_extent); ++ prev_len = btrfs_dev_extent_length(leaf, prev_de); ++ if (unlikely(prev_key->offset + prev_len > key->offset)) { ++ generic_err(leaf, slot, ++ "dev extent overlap, prev offset %llu len %llu current offset %llu", ++ prev_key->objectid, prev_len, key->offset); ++ return -EUCLEAN; ++ } ++ } ++ return 0; ++} ++ + /* + * Common point to switch the item-specific validation. + */ +@@ -1631,6 +1697,9 @@ static int check_leaf_item(struct extent_buffer *leaf, + case BTRFS_DEV_ITEM_KEY: + ret = check_dev_item(leaf, key, slot); + break; ++ case BTRFS_DEV_EXTENT_KEY: ++ ret = check_dev_extent_item(leaf, key, slot, prev_key); ++ break; + case BTRFS_INODE_ITEM_KEY: + ret = check_inode_item(leaf, key, slot); + break; +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 6c41bf322315c..a3869e9c71b91 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -3404,9 +3404,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, + struct ext4_extent *ex, *abut_ex; + ext4_lblk_t ee_block, eof_block; + unsigned int ee_len, depth, map_len = map->m_len; +- int allocated = 0, max_zeroout = 0; + int err = 0; + int split_flag = EXT4_EXT_DATA_VALID2; ++ int allocated = 0; ++ unsigned int max_zeroout = 0; + + ext_debug(inode, "logical block %llu, max_blocks %u\n", + (unsigned long long)map->m_lblk, map_len); +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 630a5e5a380e2..a48c9cc5aa6e8 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -6496,6 +6496,9 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) + bool set_trimmed = false; + void *bitmap; + ++ if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info))) ++ return 0; ++ + last = ext4_last_grp_cluster(sb, e4b->bd_group); + bitmap = e4b->bd_bitmap; + if (start == 0 && max >= last) +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index 1c69dc91c3292..dc33b4e5c07b8 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -2269,6 +2269,8 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) + #endif + + segno = GET_SEGNO(sbi, blkaddr); ++ if (segno == NULL_SEGNO) ++ return; + + se = get_seg_entry(sbi, segno); + new_vblocks = se->valid_blocks + del; +@@ -3443,8 +3445,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, + * since SSR needs latest valid block information. + */ + update_sit_entry(sbi, *new_blkaddr, 1); +- if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) +- update_sit_entry(sbi, old_blkaddr, -1); ++ update_sit_entry(sbi, old_blkaddr, -1); + + if (!__has_curseg_space(sbi, curseg)) { + if (from_gc) +diff --git a/fs/file.c b/fs/file.c +index 0669cc0f1809f..72fe61e550cdb 100644 +--- a/fs/file.c ++++ b/fs/file.c +@@ -46,27 +46,23 @@ static void free_fdtable_rcu(struct rcu_head *rcu) + #define BITBIT_NR(nr) BITS_TO_LONGS(BITS_TO_LONGS(nr)) + #define BITBIT_SIZE(nr) (BITBIT_NR(nr) * sizeof(long)) + ++#define fdt_words(fdt) ((fdt)->max_fds / BITS_PER_LONG) // words in ->open_fds + /* + * Copy 'count' fd bits from the old table to the new table and clear the extra + * space if any. This does not copy the file pointers. Called with the files + * spinlock held for write. + */ +-static void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt, +- unsigned int count) ++static inline void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt, ++ unsigned int copy_words) + { +- unsigned int cpy, set; +- +- cpy = count / BITS_PER_BYTE; +- set = (nfdt->max_fds - count) / BITS_PER_BYTE; +- memcpy(nfdt->open_fds, ofdt->open_fds, cpy); +- memset((char *)nfdt->open_fds + cpy, 0, set); +- memcpy(nfdt->close_on_exec, ofdt->close_on_exec, cpy); +- memset((char *)nfdt->close_on_exec + cpy, 0, set); +- +- cpy = BITBIT_SIZE(count); +- set = BITBIT_SIZE(nfdt->max_fds) - cpy; +- memcpy(nfdt->full_fds_bits, ofdt->full_fds_bits, cpy); +- memset((char *)nfdt->full_fds_bits + cpy, 0, set); ++ unsigned int nwords = fdt_words(nfdt); ++ ++ bitmap_copy_and_extend(nfdt->open_fds, ofdt->open_fds, ++ copy_words * BITS_PER_LONG, nwords * BITS_PER_LONG); ++ bitmap_copy_and_extend(nfdt->close_on_exec, ofdt->close_on_exec, ++ copy_words * BITS_PER_LONG, nwords * BITS_PER_LONG); ++ bitmap_copy_and_extend(nfdt->full_fds_bits, ofdt->full_fds_bits, ++ copy_words, nwords); + } + + /* +@@ -84,7 +80,7 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt) + memcpy(nfdt->fd, ofdt->fd, cpy); + memset((char *)nfdt->fd + cpy, 0, set); + +- copy_fd_bitmaps(nfdt, ofdt, ofdt->max_fds); ++ copy_fd_bitmaps(nfdt, ofdt, fdt_words(ofdt)); + } + + /* +@@ -374,7 +370,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int + open_files = sane_fdtable_size(old_fdt, max_fds); + } + +- copy_fd_bitmaps(new_fdt, old_fdt, open_files); ++ copy_fd_bitmaps(new_fdt, old_fdt, open_files / BITS_PER_LONG); + + old_fds = old_fdt->fd; + new_fds = new_fdt->fd; +diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c +index c7d882a9fe339..295344a462e1d 100644 +--- a/fs/fuse/cuse.c ++++ b/fs/fuse/cuse.c +@@ -474,8 +474,7 @@ static int cuse_send_init(struct cuse_conn *cc) + + static void cuse_fc_release(struct fuse_conn *fc) + { +- struct cuse_conn *cc = fc_to_cc(fc); +- kfree_rcu(cc, fc.rcu); ++ kfree(fc_to_cc(fc)); + } + + /** +diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c +index d6b5339c56e2c..86416f7b8b559 100644 +--- a/fs/fuse/dev.c ++++ b/fs/fuse/dev.c +@@ -1623,9 +1623,11 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, + + this_num = min_t(unsigned, num, PAGE_SIZE - offset); + err = fuse_copy_page(cs, &page, offset, this_num, 0); +- if (!err && offset == 0 && +- (this_num == PAGE_SIZE || file_size == end)) ++ if (!PageUptodate(page) && !err && offset == 0 && ++ (this_num == PAGE_SIZE || file_size == end)) { ++ zero_user_segment(page, this_num, PAGE_SIZE); + SetPageUptodate(page); ++ } + unlock_page(page); + put_page(page); + +diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h +index 55b7ca26fb8ab..ac655c7a15db2 100644 +--- a/fs/fuse/fuse_i.h ++++ b/fs/fuse/fuse_i.h +@@ -848,6 +848,7 @@ struct fuse_mount { + + /* Entry on fc->mounts */ + struct list_head fc_entry; ++ struct rcu_head rcu; + }; + + static inline struct fuse_mount *get_fuse_mount_super(struct super_block *sb) +diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c +index 396866f9d72c3..40a4c7680bd7e 100644 +--- a/fs/fuse/inode.c ++++ b/fs/fuse/inode.c +@@ -883,6 +883,14 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm, + } + EXPORT_SYMBOL_GPL(fuse_conn_init); + ++static void delayed_release(struct rcu_head *p) ++{ ++ struct fuse_conn *fc = container_of(p, struct fuse_conn, rcu); ++ ++ put_user_ns(fc->user_ns); ++ fc->release(fc); ++} ++ + void fuse_conn_put(struct fuse_conn *fc) + { + if (refcount_dec_and_test(&fc->count)) { +@@ -894,13 +902,12 @@ void fuse_conn_put(struct fuse_conn *fc) + if (fiq->ops->release) + fiq->ops->release(fiq); + put_pid_ns(fc->pid_ns); +- put_user_ns(fc->user_ns); + bucket = rcu_dereference_protected(fc->curr_bucket, 1); + if (bucket) { + WARN_ON(atomic_read(&bucket->count) != 1); + kfree(bucket); + } +- fc->release(fc); ++ call_rcu(&fc->rcu, delayed_release); + } + } + EXPORT_SYMBOL_GPL(fuse_conn_put); +@@ -1297,7 +1304,7 @@ EXPORT_SYMBOL_GPL(fuse_send_init); + void fuse_free_conn(struct fuse_conn *fc) + { + WARN_ON(!list_empty(&fc->devices)); +- kfree_rcu(fc, rcu); ++ kfree(fc); + } + EXPORT_SYMBOL_GPL(fuse_free_conn); + +@@ -1836,7 +1843,7 @@ static void fuse_sb_destroy(struct super_block *sb) + void fuse_mount_destroy(struct fuse_mount *fm) + { + fuse_conn_put(fm->fc); +- kfree(fm); ++ kfree_rcu(fm, rcu); + } + EXPORT_SYMBOL(fuse_mount_destroy); + +diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c +index 94fc874f5de7f..a4deacc6f78c7 100644 +--- a/fs/fuse/virtio_fs.c ++++ b/fs/fuse/virtio_fs.c +@@ -310,6 +310,16 @@ static int virtio_fs_read_tag(struct virtio_device *vdev, struct virtio_fs *fs) + return -ENOMEM; + memcpy(fs->tag, tag_buf, len); + fs->tag[len] = '\0'; ++ ++ /* While the VIRTIO specification allows any character, newlines are ++ * awkward on mount(8) command-lines and cause problems in the sysfs ++ * "tag" attr and uevent TAG= properties. Forbid them. ++ */ ++ if (strchr(fs->tag, '\n')) { ++ dev_dbg(&vdev->dev, "refusing virtiofs tag with newline character\n"); ++ return -EINVAL; ++ } ++ + return 0; + } + +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index 462e957eda8be..763d8dccdfc13 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -1910,7 +1910,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) + kuid_t ouid, nuid; + kgid_t ogid, ngid; + int error; +- struct gfs2_alloc_parms ap; ++ struct gfs2_alloc_parms ap = {}; + + ouid = inode->i_uid; + ogid = inode->i_gid; +diff --git a/fs/inode.c b/fs/inode.c +index ec41a11e2f8fe..f957c130c7a6a 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -456,6 +456,39 @@ static void inode_lru_list_del(struct inode *inode) + this_cpu_dec(nr_unused); + } + ++static void inode_pin_lru_isolating(struct inode *inode) ++{ ++ lockdep_assert_held(&inode->i_lock); ++ WARN_ON(inode->i_state & (I_LRU_ISOLATING | I_FREEING | I_WILL_FREE)); ++ inode->i_state |= I_LRU_ISOLATING; ++} ++ ++static void inode_unpin_lru_isolating(struct inode *inode) ++{ ++ spin_lock(&inode->i_lock); ++ WARN_ON(!(inode->i_state & I_LRU_ISOLATING)); ++ inode->i_state &= ~I_LRU_ISOLATING; ++ smp_mb(); ++ wake_up_bit(&inode->i_state, __I_LRU_ISOLATING); ++ spin_unlock(&inode->i_lock); ++} ++ ++static void inode_wait_for_lru_isolating(struct inode *inode) ++{ ++ spin_lock(&inode->i_lock); ++ if (inode->i_state & I_LRU_ISOLATING) { ++ DEFINE_WAIT_BIT(wq, &inode->i_state, __I_LRU_ISOLATING); ++ wait_queue_head_t *wqh; ++ ++ wqh = bit_waitqueue(&inode->i_state, __I_LRU_ISOLATING); ++ spin_unlock(&inode->i_lock); ++ __wait_on_bit(wqh, &wq, bit_wait, TASK_UNINTERRUPTIBLE); ++ spin_lock(&inode->i_lock); ++ WARN_ON(inode->i_state & I_LRU_ISOLATING); ++ } ++ spin_unlock(&inode->i_lock); ++} ++ + /** + * inode_sb_list_add - add inode to the superblock list of inodes + * @inode: inode to add +@@ -575,6 +608,8 @@ static void evict(struct inode *inode) + + inode_sb_list_del(inode); + ++ inode_wait_for_lru_isolating(inode); ++ + /* + * Wait for flusher thread to be done with the inode so that filesystem + * does not start destroying it while writeback is still running. Since +@@ -772,7 +807,7 @@ static enum lru_status inode_lru_isolate(struct list_head *item, + } + + if (inode_has_buffers(inode) || !mapping_empty(&inode->i_data)) { +- __iget(inode); ++ inode_pin_lru_isolating(inode); + spin_unlock(&inode->i_lock); + spin_unlock(lru_lock); + if (remove_inode_buffers(inode)) { +@@ -785,7 +820,7 @@ static enum lru_status inode_lru_isolate(struct list_head *item, + if (current->reclaim_state) + current->reclaim_state->reclaimed_slab += reap; + } +- iput(inode); ++ inode_unpin_lru_isolating(inode); + spin_lock(lru_lock); + return LRU_RETRY; + } +diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c +index 5579e67da17db..c33f78513f00f 100644 +--- a/fs/lockd/svc.c ++++ b/fs/lockd/svc.c +@@ -759,8 +759,6 @@ static const struct svc_version *nlmsvc_version[] = { + #endif + }; + +-static struct svc_stat nlmsvc_stats; +- + #define NLM_NRVERS ARRAY_SIZE(nlmsvc_version) + static struct svc_program nlmsvc_program = { + .pg_prog = NLM_PROGRAM, /* program number */ +@@ -768,7 +766,6 @@ static struct svc_program nlmsvc_program = { + .pg_vers = nlmsvc_version, /* version table */ + .pg_name = "lockd", /* service name */ + .pg_class = "nfsd", /* share authentication with nfsd */ +- .pg_stats = &nlmsvc_stats, /* stats table */ + .pg_authenticate = &lockd_authenticate, /* export authentication */ + .pg_init_request = svc_generic_init_request, + .pg_rpcbind_set = svc_generic_rpcbind_set, +diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c +index 8fe143cad4a2b..f00fff3633f60 100644 +--- a/fs/nfs/callback.c ++++ b/fs/nfs/callback.c +@@ -407,15 +407,12 @@ static const struct svc_version *nfs4_callback_version[] = { + [4] = &nfs4_callback_version4, + }; + +-static struct svc_stat nfs4_callback_stats; +- + static struct svc_program nfs4_callback_program = { + .pg_prog = NFS4_CALLBACK, /* RPC service number */ + .pg_nvers = ARRAY_SIZE(nfs4_callback_version), /* Number of entries */ + .pg_vers = nfs4_callback_version, /* version table */ + .pg_name = "NFSv4 callback", /* service name */ + .pg_class = "nfs", /* authentication class */ +- .pg_stats = &nfs4_callback_stats, + .pg_authenticate = nfs_callback_authenticate, + .pg_init_request = svc_generic_init_request, + .pg_rpcbind_set = svc_generic_rpcbind_set, +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index 9f6776c7062ec..e13f1c762951a 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -1994,6 +1994,14 @@ pnfs_update_layout(struct inode *ino, + } + + lookup_again: ++ if (!nfs4_valid_open_stateid(ctx->state)) { ++ trace_pnfs_update_layout(ino, pos, count, ++ iomode, lo, lseg, ++ PNFS_UPDATE_LAYOUT_INVALID_OPEN); ++ lseg = ERR_PTR(-EIO); ++ goto out; ++ } ++ + lseg = ERR_PTR(nfs4_client_recover_expired_lease(clp)); + if (IS_ERR(lseg)) + goto out; +diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c +index 668c7527b17e8..16fadade86ccb 100644 +--- a/fs/nfsd/export.c ++++ b/fs/nfsd/export.c +@@ -339,12 +339,16 @@ static int export_stats_init(struct export_stats *stats) + + static void export_stats_reset(struct export_stats *stats) + { +- nfsd_percpu_counters_reset(stats->counter, EXP_STATS_COUNTERS_NUM); ++ if (stats) ++ nfsd_percpu_counters_reset(stats->counter, ++ EXP_STATS_COUNTERS_NUM); + } + + static void export_stats_destroy(struct export_stats *stats) + { +- nfsd_percpu_counters_destroy(stats->counter, EXP_STATS_COUNTERS_NUM); ++ if (stats) ++ nfsd_percpu_counters_destroy(stats->counter, ++ EXP_STATS_COUNTERS_NUM); + } + + static void svc_export_put(struct kref *ref) +@@ -353,7 +357,8 @@ static void svc_export_put(struct kref *ref) + path_put(&exp->ex_path); + auth_domain_put(exp->ex_client); + nfsd4_fslocs_free(&exp->ex_fslocs); +- export_stats_destroy(&exp->ex_stats); ++ export_stats_destroy(exp->ex_stats); ++ kfree(exp->ex_stats); + kfree(exp->ex_uuid); + kfree_rcu(exp, ex_rcu); + } +@@ -744,13 +749,15 @@ static int svc_export_show(struct seq_file *m, + seq_putc(m, '\t'); + seq_escape(m, exp->ex_client->name, " \t\n\\"); + if (export_stats) { +- seq_printf(m, "\t%lld\n", exp->ex_stats.start_time); ++ struct percpu_counter *counter = exp->ex_stats->counter; ++ ++ seq_printf(m, "\t%lld\n", exp->ex_stats->start_time); + seq_printf(m, "\tfh_stale: %lld\n", +- percpu_counter_sum_positive(&exp->ex_stats.counter[EXP_STATS_FH_STALE])); ++ percpu_counter_sum_positive(&counter[EXP_STATS_FH_STALE])); + seq_printf(m, "\tio_read: %lld\n", +- percpu_counter_sum_positive(&exp->ex_stats.counter[EXP_STATS_IO_READ])); ++ percpu_counter_sum_positive(&counter[EXP_STATS_IO_READ])); + seq_printf(m, "\tio_write: %lld\n", +- percpu_counter_sum_positive(&exp->ex_stats.counter[EXP_STATS_IO_WRITE])); ++ percpu_counter_sum_positive(&counter[EXP_STATS_IO_WRITE])); + seq_putc(m, '\n'); + return 0; + } +@@ -796,7 +803,7 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem) + new->ex_layout_types = 0; + new->ex_uuid = NULL; + new->cd = item->cd; +- export_stats_reset(&new->ex_stats); ++ export_stats_reset(new->ex_stats); + } + + static void export_update(struct cache_head *cnew, struct cache_head *citem) +@@ -832,7 +839,14 @@ static struct cache_head *svc_export_alloc(void) + if (!i) + return NULL; + +- if (export_stats_init(&i->ex_stats)) { ++ i->ex_stats = kmalloc(sizeof(*(i->ex_stats)), GFP_KERNEL); ++ if (!i->ex_stats) { ++ kfree(i); ++ return NULL; ++ } ++ ++ if (export_stats_init(i->ex_stats)) { ++ kfree(i->ex_stats); + kfree(i); + return NULL; + } +diff --git a/fs/nfsd/export.h b/fs/nfsd/export.h +index d03f7f6a8642d..f73e23bb24a1e 100644 +--- a/fs/nfsd/export.h ++++ b/fs/nfsd/export.h +@@ -64,10 +64,10 @@ struct svc_export { + struct cache_head h; + struct auth_domain * ex_client; + int ex_flags; ++ int ex_fsid; + struct path ex_path; + kuid_t ex_anon_uid; + kgid_t ex_anon_gid; +- int ex_fsid; + unsigned char * ex_uuid; /* 16 byte fsid */ + struct nfsd4_fs_locations ex_fslocs; + uint32_t ex_nflavors; +@@ -76,7 +76,7 @@ struct svc_export { + struct nfsd4_deviceid_map *ex_devid_map; + struct cache_detail *cd; + struct rcu_head ex_rcu; +- struct export_stats ex_stats; ++ struct export_stats *ex_stats; + }; + + /* an "export key" (expkey) maps a filehandlefragement to an +diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h +index 51a4b7885cae2..548422b24a7d7 100644 +--- a/fs/nfsd/netns.h ++++ b/fs/nfsd/netns.h +@@ -10,8 +10,10 @@ + + #include <net/net_namespace.h> + #include <net/netns/generic.h> ++#include <linux/nfs4.h> + #include <linux/percpu_counter.h> + #include <linux/siphash.h> ++#include <linux/sunrpc/stats.h> + + /* Hash tables for nfs4_clientid state */ + #define CLIENT_HASH_BITS 4 +@@ -25,10 +27,22 @@ struct nfsd4_client_tracking_ops; + + enum { + /* cache misses due only to checksum comparison failures */ +- NFSD_NET_PAYLOAD_MISSES, ++ NFSD_STATS_PAYLOAD_MISSES, + /* amount of memory (in bytes) currently consumed by the DRC */ +- NFSD_NET_DRC_MEM_USAGE, +- NFSD_NET_COUNTERS_NUM ++ NFSD_STATS_DRC_MEM_USAGE, ++ NFSD_STATS_RC_HITS, /* repcache hits */ ++ NFSD_STATS_RC_MISSES, /* repcache misses */ ++ NFSD_STATS_RC_NOCACHE, /* uncached reqs */ ++ NFSD_STATS_FH_STALE, /* FH stale error */ ++ NFSD_STATS_IO_READ, /* bytes returned to read requests */ ++ NFSD_STATS_IO_WRITE, /* bytes passed in write requests */ ++#ifdef CONFIG_NFSD_V4 ++ NFSD_STATS_FIRST_NFS4_OP, /* count of individual nfsv4 operations */ ++ NFSD_STATS_LAST_NFS4_OP = NFSD_STATS_FIRST_NFS4_OP + LAST_NFS4_OP, ++#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op)) ++ NFSD_STATS_WDELEG_GETATTR, /* count of getattr conflict with wdeleg */ ++#endif ++ NFSD_STATS_COUNTERS_NUM + }; + + /* +@@ -168,7 +182,10 @@ struct nfsd_net { + atomic_t num_drc_entries; + + /* Per-netns stats counters */ +- struct percpu_counter counter[NFSD_NET_COUNTERS_NUM]; ++ struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM]; ++ ++ /* sunrpc svc stats */ ++ struct svc_stat nfsd_svcstats; + + /* longest hash chain seen */ + unsigned int longest_chain; +diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c +index e0ff2212866a4..11dcf3debb1d7 100644 +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -2435,10 +2435,10 @@ nfsd4_proc_null(struct svc_rqst *rqstp) + return rpc_success; + } + +-static inline void nfsd4_increment_op_stats(u32 opnum) ++static inline void nfsd4_increment_op_stats(struct nfsd_net *nn, u32 opnum) + { + if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP) +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_NFS4_OP(opnum)]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_NFS4_OP(opnum)]); + } + + static const struct nfsd4_operation nfsd4_ops[]; +@@ -2713,7 +2713,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) + status, nfsd4_op_name(op->opnum)); + + nfsd4_cstate_clear_replay(cstate); +- nfsd4_increment_op_stats(op->opnum); ++ nfsd4_increment_op_stats(nn, op->opnum); + } + + fh_put(current_fh); +diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c +index 2b5417e06d80d..448700939dfe9 100644 +--- a/fs/nfsd/nfscache.c ++++ b/fs/nfsd/nfscache.c +@@ -85,8 +85,8 @@ nfsd_hashsize(unsigned int limit) + } + + static struct svc_cacherep * +-nfsd_reply_cache_alloc(struct svc_rqst *rqstp, __wsum csum, +- struct nfsd_net *nn) ++nfsd_cacherep_alloc(struct svc_rqst *rqstp, __wsum csum, ++ struct nfsd_net *nn) + { + struct svc_cacherep *rp; + +@@ -110,21 +110,48 @@ nfsd_reply_cache_alloc(struct svc_rqst *rqstp, __wsum csum, + return rp; + } + +-static void +-nfsd_reply_cache_free_locked(struct nfsd_drc_bucket *b, struct svc_cacherep *rp, +- struct nfsd_net *nn) ++static void nfsd_cacherep_free(struct svc_cacherep *rp) + { +- if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) { +- nfsd_stats_drc_mem_usage_sub(nn, rp->c_replvec.iov_len); ++ if (rp->c_type == RC_REPLBUFF) + kfree(rp->c_replvec.iov_base); ++ kmem_cache_free(drc_slab, rp); ++} ++ ++static unsigned long ++nfsd_cacherep_dispose(struct list_head *dispose) ++{ ++ struct svc_cacherep *rp; ++ unsigned long freed = 0; ++ ++ while (!list_empty(dispose)) { ++ rp = list_first_entry(dispose, struct svc_cacherep, c_lru); ++ list_del(&rp->c_lru); ++ nfsd_cacherep_free(rp); ++ freed++; + } ++ return freed; ++} ++ ++static void ++nfsd_cacherep_unlink_locked(struct nfsd_net *nn, struct nfsd_drc_bucket *b, ++ struct svc_cacherep *rp) ++{ ++ if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) ++ nfsd_stats_drc_mem_usage_sub(nn, rp->c_replvec.iov_len); + if (rp->c_state != RC_UNUSED) { + rb_erase(&rp->c_node, &b->rb_head); + list_del(&rp->c_lru); + atomic_dec(&nn->num_drc_entries); + nfsd_stats_drc_mem_usage_sub(nn, sizeof(*rp)); + } +- kmem_cache_free(drc_slab, rp); ++} ++ ++static void ++nfsd_reply_cache_free_locked(struct nfsd_drc_bucket *b, struct svc_cacherep *rp, ++ struct nfsd_net *nn) ++{ ++ nfsd_cacherep_unlink_locked(nn, b, rp); ++ nfsd_cacherep_free(rp); + } + + static void +@@ -132,8 +159,9 @@ nfsd_reply_cache_free(struct nfsd_drc_bucket *b, struct svc_cacherep *rp, + struct nfsd_net *nn) + { + spin_lock(&b->cache_lock); +- nfsd_reply_cache_free_locked(b, rp, nn); ++ nfsd_cacherep_unlink_locked(nn, b, rp); + spin_unlock(&b->cache_lock); ++ nfsd_cacherep_free(rp); + } + + int nfsd_drc_slab_create(void) +@@ -148,16 +176,6 @@ void nfsd_drc_slab_free(void) + kmem_cache_destroy(drc_slab); + } + +-static int nfsd_reply_cache_stats_init(struct nfsd_net *nn) +-{ +- return nfsd_percpu_counters_init(nn->counter, NFSD_NET_COUNTERS_NUM); +-} +- +-static void nfsd_reply_cache_stats_destroy(struct nfsd_net *nn) +-{ +- nfsd_percpu_counters_destroy(nn->counter, NFSD_NET_COUNTERS_NUM); +-} +- + int nfsd_reply_cache_init(struct nfsd_net *nn) + { + unsigned int hashsize; +@@ -169,16 +187,12 @@ int nfsd_reply_cache_init(struct nfsd_net *nn) + hashsize = nfsd_hashsize(nn->max_drc_entries); + nn->maskbits = ilog2(hashsize); + +- status = nfsd_reply_cache_stats_init(nn); +- if (status) +- goto out_nomem; +- + nn->nfsd_reply_cache_shrinker.scan_objects = nfsd_reply_cache_scan; + nn->nfsd_reply_cache_shrinker.count_objects = nfsd_reply_cache_count; + nn->nfsd_reply_cache_shrinker.seeks = 1; + status = register_shrinker(&nn->nfsd_reply_cache_shrinker); + if (status) +- goto out_stats_destroy; ++ return status; + + nn->drc_hashtbl = kvzalloc(array_size(hashsize, + sizeof(*nn->drc_hashtbl)), GFP_KERNEL); +@@ -194,9 +208,6 @@ int nfsd_reply_cache_init(struct nfsd_net *nn) + return 0; + out_shrinker: + unregister_shrinker(&nn->nfsd_reply_cache_shrinker); +-out_stats_destroy: +- nfsd_reply_cache_stats_destroy(nn); +-out_nomem: + printk(KERN_ERR "nfsd: failed to allocate reply cache\n"); + return -ENOMEM; + } +@@ -216,7 +227,6 @@ void nfsd_reply_cache_shutdown(struct nfsd_net *nn) + rp, nn); + } + } +- nfsd_reply_cache_stats_destroy(nn); + + kvfree(nn->drc_hashtbl); + nn->drc_hashtbl = NULL; +@@ -243,12 +253,21 @@ nfsd_cache_bucket_find(__be32 xid, struct nfsd_net *nn) + return &nn->drc_hashtbl[hash]; + } + +-static long prune_bucket(struct nfsd_drc_bucket *b, struct nfsd_net *nn, +- unsigned int max) ++/* ++ * Remove and return no more than @max expired entries in bucket @b. ++ * If @max is zero, do not limit the number of removed entries. ++ */ ++static void ++nfsd_prune_bucket_locked(struct nfsd_net *nn, struct nfsd_drc_bucket *b, ++ unsigned int max, struct list_head *dispose) + { ++ unsigned long expiry = jiffies - RC_EXPIRE; + struct svc_cacherep *rp, *tmp; +- long freed = 0; ++ unsigned int freed = 0; ++ ++ lockdep_assert_held(&b->cache_lock); + ++ /* The bucket LRU is ordered oldest-first. */ + list_for_each_entry_safe(rp, tmp, &b->lru_head, c_lru) { + /* + * Don't free entries attached to calls that are still +@@ -256,60 +275,77 @@ static long prune_bucket(struct nfsd_drc_bucket *b, struct nfsd_net *nn, + */ + if (rp->c_state == RC_INPROG) + continue; ++ + if (atomic_read(&nn->num_drc_entries) <= nn->max_drc_entries && +- time_before(jiffies, rp->c_timestamp + RC_EXPIRE)) ++ time_before(expiry, rp->c_timestamp)) + break; +- nfsd_reply_cache_free_locked(b, rp, nn); +- if (max && freed++ > max) ++ ++ nfsd_cacherep_unlink_locked(nn, b, rp); ++ list_add(&rp->c_lru, dispose); ++ ++ if (max && ++freed > max) + break; + } +- return freed; + } + +-static long nfsd_prune_bucket(struct nfsd_drc_bucket *b, struct nfsd_net *nn) ++/** ++ * nfsd_reply_cache_count - count_objects method for the DRC shrinker ++ * @shrink: our registered shrinker context ++ * @sc: garbage collection parameters ++ * ++ * Returns the total number of entries in the duplicate reply cache. To ++ * keep things simple and quick, this is not the number of expired entries ++ * in the cache (ie, the number that would be removed by a call to ++ * nfsd_reply_cache_scan). ++ */ ++static unsigned long ++nfsd_reply_cache_count(struct shrinker *shrink, struct shrink_control *sc) + { +- return prune_bucket(b, nn, 3); ++ struct nfsd_net *nn = container_of(shrink, ++ struct nfsd_net, nfsd_reply_cache_shrinker); ++ ++ return atomic_read(&nn->num_drc_entries); + } + +-/* +- * Walk the LRU list and prune off entries that are older than RC_EXPIRE. +- * Also prune the oldest ones when the total exceeds the max number of entries. ++/** ++ * nfsd_reply_cache_scan - scan_objects method for the DRC shrinker ++ * @shrink: our registered shrinker context ++ * @sc: garbage collection parameters ++ * ++ * Free expired entries on each bucket's LRU list until we've released ++ * nr_to_scan freed objects. Nothing will be released if the cache ++ * has not exceeded it's max_drc_entries limit. ++ * ++ * Returns the number of entries released by this call. + */ +-static long +-prune_cache_entries(struct nfsd_net *nn) ++static unsigned long ++nfsd_reply_cache_scan(struct shrinker *shrink, struct shrink_control *sc) + { ++ struct nfsd_net *nn = container_of(shrink, ++ struct nfsd_net, nfsd_reply_cache_shrinker); ++ unsigned long freed = 0; ++ LIST_HEAD(dispose); + unsigned int i; +- long freed = 0; + + for (i = 0; i < nn->drc_hashsize; i++) { + struct nfsd_drc_bucket *b = &nn->drc_hashtbl[i]; + + if (list_empty(&b->lru_head)) + continue; ++ + spin_lock(&b->cache_lock); +- freed += prune_bucket(b, nn, 0); ++ nfsd_prune_bucket_locked(nn, b, 0, &dispose); + spin_unlock(&b->cache_lock); +- } +- return freed; +-} + +-static unsigned long +-nfsd_reply_cache_count(struct shrinker *shrink, struct shrink_control *sc) +-{ +- struct nfsd_net *nn = container_of(shrink, +- struct nfsd_net, nfsd_reply_cache_shrinker); ++ freed += nfsd_cacherep_dispose(&dispose); ++ if (freed > sc->nr_to_scan) ++ break; ++ } + +- return atomic_read(&nn->num_drc_entries); ++ trace_nfsd_drc_gc(nn, freed); ++ return freed; + } + +-static unsigned long +-nfsd_reply_cache_scan(struct shrinker *shrink, struct shrink_control *sc) +-{ +- struct nfsd_net *nn = container_of(shrink, +- struct nfsd_net, nfsd_reply_cache_shrinker); +- +- return prune_cache_entries(nn); +-} + /* + * Walk an xdr_buf and get a CRC for at most the first RC_CSUMLEN bytes + */ +@@ -421,16 +457,18 @@ nfsd_cache_insert(struct nfsd_drc_bucket *b, struct svc_cacherep *key, + */ + int nfsd_cache_lookup(struct svc_rqst *rqstp) + { +- struct nfsd_net *nn; ++ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + struct svc_cacherep *rp, *found; + __wsum csum; + struct nfsd_drc_bucket *b; + int type = rqstp->rq_cachetype; ++ unsigned long freed; ++ LIST_HEAD(dispose); + int rtn = RC_DOIT; + + rqstp->rq_cacherep = NULL; + if (type == RC_NOCACHE) { +- nfsd_stats_rc_nocache_inc(); ++ nfsd_stats_rc_nocache_inc(nn); + goto out; + } + +@@ -440,8 +478,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp) + * Since the common case is a cache miss followed by an insert, + * preallocate an entry. + */ +- nn = net_generic(SVC_NET(rqstp), nfsd_net_id); +- rp = nfsd_reply_cache_alloc(rqstp, csum, nn); ++ rp = nfsd_cacherep_alloc(rqstp, csum, nn); + if (!rp) + goto out; + +@@ -450,25 +487,23 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp) + found = nfsd_cache_insert(b, rp, nn); + if (found != rp) + goto found_entry; +- +- nfsd_stats_rc_misses_inc(); + rqstp->rq_cacherep = rp; + rp->c_state = RC_INPROG; ++ nfsd_prune_bucket_locked(nn, b, 3, &dispose); ++ spin_unlock(&b->cache_lock); + ++ freed = nfsd_cacherep_dispose(&dispose); ++ trace_nfsd_drc_gc(nn, freed); ++ ++ nfsd_stats_rc_misses_inc(nn); + atomic_inc(&nn->num_drc_entries); + nfsd_stats_drc_mem_usage_add(nn, sizeof(*rp)); +- +- nfsd_prune_bucket(b, nn); +- +-out_unlock: +- spin_unlock(&b->cache_lock); +-out: +- return rtn; ++ goto out; + + found_entry: + /* We found a matching entry which is either in progress or done. */ + nfsd_reply_cache_free_locked(NULL, rp, nn); +- nfsd_stats_rc_hits_inc(); ++ nfsd_stats_rc_hits_inc(nn); + rtn = RC_DROPIT; + rp = found; + +@@ -501,7 +536,10 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp) + + out_trace: + trace_nfsd_drc_found(nn, rqstp, rtn); +- goto out_unlock; ++out_unlock: ++ spin_unlock(&b->cache_lock); ++out: ++ return rtn; + } + + /** +@@ -613,15 +651,15 @@ int nfsd_reply_cache_stats_show(struct seq_file *m, void *v) + atomic_read(&nn->num_drc_entries)); + seq_printf(m, "hash buckets: %u\n", 1 << nn->maskbits); + seq_printf(m, "mem usage: %lld\n", +- percpu_counter_sum_positive(&nn->counter[NFSD_NET_DRC_MEM_USAGE])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_DRC_MEM_USAGE])); + seq_printf(m, "cache hits: %lld\n", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_HITS])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_HITS])); + seq_printf(m, "cache misses: %lld\n", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_MISSES])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_MISSES])); + seq_printf(m, "not cached: %lld\n", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_NOCACHE])); + seq_printf(m, "payload misses: %lld\n", +- percpu_counter_sum_positive(&nn->counter[NFSD_NET_PAYLOAD_MISSES])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_PAYLOAD_MISSES])); + seq_printf(m, "longest chain len: %u\n", nn->longest_chain); + seq_printf(m, "cachesize at longest: %u\n", nn->longest_chain_cachesize); + return 0; +diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c +index f77f00c931723..2feaa49fb9fe2 100644 +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -1458,18 +1458,21 @@ static __net_init int nfsd_init_net(struct net *net) + retval = nfsd_idmap_init(net); + if (retval) + goto out_idmap_error; ++ retval = nfsd_stat_counters_init(nn); ++ if (retval) ++ goto out_repcache_error; ++ memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats)); ++ nn->nfsd_svcstats.program = &nfsd_program; + nn->nfsd_versions = NULL; + nn->nfsd4_minorversions = NULL; + nfsd4_init_leases_net(nn); +- retval = nfsd_reply_cache_init(nn); +- if (retval) +- goto out_cache_error; + get_random_bytes(&nn->siphash_key, sizeof(nn->siphash_key)); + seqlock_init(&nn->writeverf_lock); ++ nfsd_proc_stat_init(net); + + return 0; + +-out_cache_error: ++out_repcache_error: + nfsd_idmap_shutdown(net); + out_idmap_error: + nfsd_export_shutdown(net); +@@ -1481,10 +1484,11 @@ static __net_exit void nfsd_exit_net(struct net *net) + { + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + +- nfsd_reply_cache_shutdown(nn); ++ nfsd_proc_stat_shutdown(net); ++ nfsd_stat_counters_destroy(nn); + nfsd_idmap_shutdown(net); + nfsd_export_shutdown(net); +- nfsd_netns_free_versions(net_generic(net, nfsd_net_id)); ++ nfsd_netns_free_versions(nn); + } + + static struct pernet_operations nfsd_net_ops = { +@@ -1504,12 +1508,9 @@ static int __init init_nfsd(void) + retval = nfsd4_init_pnfs(); + if (retval) + goto out_free_slabs; +- retval = nfsd_stat_init(); /* Statistics */ +- if (retval) +- goto out_free_pnfs; + retval = nfsd_drc_slab_create(); + if (retval) +- goto out_free_stat; ++ goto out_free_pnfs; + nfsd_lockd_init(); /* lockd->nfsd callbacks */ + retval = create_proc_exports_entry(); + if (retval) +@@ -1539,8 +1540,6 @@ static int __init init_nfsd(void) + out_free_lockd: + nfsd_lockd_shutdown(); + nfsd_drc_slab_free(); +-out_free_stat: +- nfsd_stat_shutdown(); + out_free_pnfs: + nfsd4_exit_pnfs(); + out_free_slabs: +@@ -1557,7 +1556,6 @@ static void __exit exit_nfsd(void) + nfsd_drc_slab_free(); + remove_proc_entry("fs/nfs/exports", NULL); + remove_proc_entry("fs/nfs", NULL); +- nfsd_stat_shutdown(); + nfsd_lockd_shutdown(); + nfsd4_free_slabs(); + nfsd4_exit_pnfs(); +diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h +index 013bfa24ced21..996f3f62335b2 100644 +--- a/fs/nfsd/nfsd.h ++++ b/fs/nfsd/nfsd.h +@@ -69,6 +69,7 @@ extern struct mutex nfsd_mutex; + extern spinlock_t nfsd_drc_lock; + extern unsigned long nfsd_drc_max_mem; + extern unsigned long nfsd_drc_mem_used; ++extern atomic_t nfsd_th_cnt; /* number of available threads */ + + extern const struct seq_operations nfs_exports_op; + +diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c +index 3a2ad88ae6481..e73e9d44f1b0c 100644 +--- a/fs/nfsd/nfsfh.c ++++ b/fs/nfsd/nfsfh.c +@@ -327,6 +327,7 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) + __be32 + fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) + { ++ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + struct svc_export *exp = NULL; + struct dentry *dentry; + __be32 error; +@@ -395,7 +396,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) + out: + trace_nfsd_fh_verify_err(rqstp, fhp, type, access, error); + if (error == nfserr_stale) +- nfsd_stats_fh_stale_inc(exp); ++ nfsd_stats_fh_stale_inc(nn, exp); + return error; + } + +diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c +index 3d4fd40c987bd..6b4f7977f86dc 100644 +--- a/fs/nfsd/nfssvc.c ++++ b/fs/nfsd/nfssvc.c +@@ -34,6 +34,7 @@ + + #define NFSDDBG_FACILITY NFSDDBG_SVC + ++atomic_t nfsd_th_cnt = ATOMIC_INIT(0); + extern struct svc_program nfsd_program; + static int nfsd(void *vrqstp); + #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) +@@ -89,7 +90,6 @@ unsigned long nfsd_drc_max_mem; + unsigned long nfsd_drc_mem_used; + + #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) +-static struct svc_stat nfsd_acl_svcstats; + static const struct svc_version *nfsd_acl_version[] = { + # if defined(CONFIG_NFSD_V2_ACL) + [2] = &nfsd_acl_version2, +@@ -108,15 +108,11 @@ static struct svc_program nfsd_acl_program = { + .pg_vers = nfsd_acl_version, + .pg_name = "nfsacl", + .pg_class = "nfsd", +- .pg_stats = &nfsd_acl_svcstats, + .pg_authenticate = &svc_set_client, + .pg_init_request = nfsd_acl_init_request, + .pg_rpcbind_set = nfsd_acl_rpcbind_set, + }; + +-static struct svc_stat nfsd_acl_svcstats = { +- .program = &nfsd_acl_program, +-}; + #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ + + static const struct svc_version *nfsd_version[] = { +@@ -141,7 +137,6 @@ struct svc_program nfsd_program = { + .pg_vers = nfsd_version, /* version table */ + .pg_name = "nfsd", /* program name */ + .pg_class = "nfsd", /* authentication class */ +- .pg_stats = &nfsd_svcstats, /* version table */ + .pg_authenticate = &svc_set_client, /* export authentication */ + .pg_init_request = nfsd_init_request, + .pg_rpcbind_set = nfsd_rpcbind_set, +@@ -427,16 +422,23 @@ static int nfsd_startup_net(struct net *net, const struct cred *cred) + ret = nfsd_file_cache_start_net(net); + if (ret) + goto out_lockd; +- ret = nfs4_state_start_net(net); ++ ++ ret = nfsd_reply_cache_init(nn); + if (ret) + goto out_filecache; + ++ ret = nfs4_state_start_net(net); ++ if (ret) ++ goto out_reply_cache; ++ + #ifdef CONFIG_NFSD_V4_2_INTER_SSC + nfsd4_ssc_init_umount_work(nn); + #endif + nn->nfsd_net_up = true; + return 0; + ++out_reply_cache: ++ nfsd_reply_cache_shutdown(nn); + out_filecache: + nfsd_file_cache_shutdown_net(net); + out_lockd: +@@ -454,6 +456,7 @@ static void nfsd_shutdown_net(struct net *net) + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + + nfs4_state_shutdown_net(net); ++ nfsd_reply_cache_shutdown(nn); + nfsd_file_cache_shutdown_net(net); + if (nn->lockd_up) { + lockd_down(net); +@@ -662,7 +665,8 @@ int nfsd_create_serv(struct net *net) + if (nfsd_max_blksize == 0) + nfsd_max_blksize = nfsd_get_default_max_blksize(); + nfsd_reset_versions(nn); +- serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize, nfsd); ++ serv = svc_create_pooled(&nfsd_program, &nn->nfsd_svcstats, ++ nfsd_max_blksize, nfsd); + if (serv == NULL) + return -ENOMEM; + +@@ -938,7 +942,7 @@ nfsd(void *vrqstp) + + current->fs->umask = 0; + +- atomic_inc(&nfsdstats.th_cnt); ++ atomic_inc(&nfsd_th_cnt); + + set_freezable(); + +@@ -962,7 +966,7 @@ nfsd(void *vrqstp) + validate_process_creds(); + } + +- atomic_dec(&nfsdstats.th_cnt); ++ atomic_dec(&nfsd_th_cnt); + + out: + /* Release the thread */ +diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c +index 777e24e5da33b..7a58dba0045c3 100644 +--- a/fs/nfsd/stats.c ++++ b/fs/nfsd/stats.c +@@ -27,25 +27,22 @@ + + #include "nfsd.h" + +-struct nfsd_stats nfsdstats; +-struct svc_stat nfsd_svcstats = { +- .program = &nfsd_program, +-}; +- + static int nfsd_show(struct seq_file *seq, void *v) + { ++ struct net *net = PDE_DATA(file_inode(seq->file)); ++ struct nfsd_net *nn = net_generic(net, nfsd_net_id); + int i; + + seq_printf(seq, "rc %lld %lld %lld\nfh %lld 0 0 0 0\nio %lld %lld\n", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_HITS]), +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_MISSES]), +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE]), +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_FH_STALE]), +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_READ]), +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_WRITE])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_HITS]), ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_MISSES]), ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_NOCACHE]), ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_FH_STALE]), ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_IO_READ]), ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_IO_WRITE])); + + /* thread usage: */ +- seq_printf(seq, "th %u 0", atomic_read(&nfsdstats.th_cnt)); ++ seq_printf(seq, "th %u 0", atomic_read(&nfsd_th_cnt)); + + /* deprecated thread usage histogram stats */ + for (i = 0; i < 10; i++) +@@ -55,7 +52,7 @@ static int nfsd_show(struct seq_file *seq, void *v) + seq_puts(seq, "\nra 0 0 0 0 0 0 0 0 0 0 0 0\n"); + + /* show my rpc info */ +- svc_seq_show(seq, &nfsd_svcstats); ++ svc_seq_show(seq, &nn->nfsd_svcstats); + + #ifdef CONFIG_NFSD_V4 + /* Show count for individual nfsv4 operations */ +@@ -63,7 +60,7 @@ static int nfsd_show(struct seq_file *seq, void *v) + seq_printf(seq,"proc4ops %u", LAST_NFS4_OP + 1); + for (i = 0; i <= LAST_NFS4_OP; i++) { + seq_printf(seq, " %lld", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_NFS4_OP(i)])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_NFS4_OP(i)])); + } + + seq_putc(seq, '\n'); +@@ -74,7 +71,7 @@ static int nfsd_show(struct seq_file *seq, void *v) + + DEFINE_PROC_SHOW_ATTRIBUTE(nfsd); + +-int nfsd_percpu_counters_init(struct percpu_counter counters[], int num) ++int nfsd_percpu_counters_init(struct percpu_counter *counters, int num) + { + int i, err = 0; + +@@ -106,31 +103,24 @@ void nfsd_percpu_counters_destroy(struct percpu_counter counters[], int num) + percpu_counter_destroy(&counters[i]); + } + +-static int nfsd_stat_counters_init(void) ++int nfsd_stat_counters_init(struct nfsd_net *nn) + { +- return nfsd_percpu_counters_init(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM); ++ return nfsd_percpu_counters_init(nn->counter, NFSD_STATS_COUNTERS_NUM); + } + +-static void nfsd_stat_counters_destroy(void) ++void nfsd_stat_counters_destroy(struct nfsd_net *nn) + { +- nfsd_percpu_counters_destroy(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM); ++ nfsd_percpu_counters_destroy(nn->counter, NFSD_STATS_COUNTERS_NUM); + } + +-int nfsd_stat_init(void) ++void nfsd_proc_stat_init(struct net *net) + { +- int err; +- +- err = nfsd_stat_counters_init(); +- if (err) +- return err; ++ struct nfsd_net *nn = net_generic(net, nfsd_net_id); + +- svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_ops); +- +- return 0; ++ svc_proc_register(net, &nn->nfsd_svcstats, &nfsd_proc_ops); + } + +-void nfsd_stat_shutdown(void) ++void nfsd_proc_stat_shutdown(struct net *net) + { +- nfsd_stat_counters_destroy(); +- svc_proc_unregister(&init_net, "nfsd"); ++ svc_proc_unregister(net, "nfsd"); + } +diff --git a/fs/nfsd/stats.h b/fs/nfsd/stats.h +index 9b43dc3d99913..14525e854cbac 100644 +--- a/fs/nfsd/stats.h ++++ b/fs/nfsd/stats.h +@@ -10,87 +10,66 @@ + #include <uapi/linux/nfsd/stats.h> + #include <linux/percpu_counter.h> + +- +-enum { +- NFSD_STATS_RC_HITS, /* repcache hits */ +- NFSD_STATS_RC_MISSES, /* repcache misses */ +- NFSD_STATS_RC_NOCACHE, /* uncached reqs */ +- NFSD_STATS_FH_STALE, /* FH stale error */ +- NFSD_STATS_IO_READ, /* bytes returned to read requests */ +- NFSD_STATS_IO_WRITE, /* bytes passed in write requests */ +-#ifdef CONFIG_NFSD_V4 +- NFSD_STATS_FIRST_NFS4_OP, /* count of individual nfsv4 operations */ +- NFSD_STATS_LAST_NFS4_OP = NFSD_STATS_FIRST_NFS4_OP + LAST_NFS4_OP, +-#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op)) +-#endif +- NFSD_STATS_COUNTERS_NUM +-}; +- +-struct nfsd_stats { +- struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM]; +- +- atomic_t th_cnt; /* number of available threads */ +-}; +- +-extern struct nfsd_stats nfsdstats; +- +-extern struct svc_stat nfsd_svcstats; +- +-int nfsd_percpu_counters_init(struct percpu_counter counters[], int num); +-void nfsd_percpu_counters_reset(struct percpu_counter counters[], int num); +-void nfsd_percpu_counters_destroy(struct percpu_counter counters[], int num); +-int nfsd_stat_init(void); +-void nfsd_stat_shutdown(void); +- +-static inline void nfsd_stats_rc_hits_inc(void) ++int nfsd_percpu_counters_init(struct percpu_counter *counters, int num); ++void nfsd_percpu_counters_reset(struct percpu_counter *counters, int num); ++void nfsd_percpu_counters_destroy(struct percpu_counter *counters, int num); ++int nfsd_stat_counters_init(struct nfsd_net *nn); ++void nfsd_stat_counters_destroy(struct nfsd_net *nn); ++void nfsd_proc_stat_init(struct net *net); ++void nfsd_proc_stat_shutdown(struct net *net); ++ ++static inline void nfsd_stats_rc_hits_inc(struct nfsd_net *nn) + { +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_HITS]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_RC_HITS]); + } + +-static inline void nfsd_stats_rc_misses_inc(void) ++static inline void nfsd_stats_rc_misses_inc(struct nfsd_net *nn) + { +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_MISSES]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_RC_MISSES]); + } + +-static inline void nfsd_stats_rc_nocache_inc(void) ++static inline void nfsd_stats_rc_nocache_inc(struct nfsd_net *nn) + { +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_RC_NOCACHE]); + } + +-static inline void nfsd_stats_fh_stale_inc(struct svc_export *exp) ++static inline void nfsd_stats_fh_stale_inc(struct nfsd_net *nn, ++ struct svc_export *exp) + { +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_FH_STALE]); +- if (exp) +- percpu_counter_inc(&exp->ex_stats.counter[EXP_STATS_FH_STALE]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_FH_STALE]); ++ if (exp && exp->ex_stats) ++ percpu_counter_inc(&exp->ex_stats->counter[EXP_STATS_FH_STALE]); + } + +-static inline void nfsd_stats_io_read_add(struct svc_export *exp, s64 amount) ++static inline void nfsd_stats_io_read_add(struct nfsd_net *nn, ++ struct svc_export *exp, s64 amount) + { +- percpu_counter_add(&nfsdstats.counter[NFSD_STATS_IO_READ], amount); +- if (exp) +- percpu_counter_add(&exp->ex_stats.counter[EXP_STATS_IO_READ], amount); ++ percpu_counter_add(&nn->counter[NFSD_STATS_IO_READ], amount); ++ if (exp && exp->ex_stats) ++ percpu_counter_add(&exp->ex_stats->counter[EXP_STATS_IO_READ], amount); + } + +-static inline void nfsd_stats_io_write_add(struct svc_export *exp, s64 amount) ++static inline void nfsd_stats_io_write_add(struct nfsd_net *nn, ++ struct svc_export *exp, s64 amount) + { +- percpu_counter_add(&nfsdstats.counter[NFSD_STATS_IO_WRITE], amount); +- if (exp) +- percpu_counter_add(&exp->ex_stats.counter[EXP_STATS_IO_WRITE], amount); ++ percpu_counter_add(&nn->counter[NFSD_STATS_IO_WRITE], amount); ++ if (exp && exp->ex_stats) ++ percpu_counter_add(&exp->ex_stats->counter[EXP_STATS_IO_WRITE], amount); + } + + static inline void nfsd_stats_payload_misses_inc(struct nfsd_net *nn) + { +- percpu_counter_inc(&nn->counter[NFSD_NET_PAYLOAD_MISSES]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_PAYLOAD_MISSES]); + } + + static inline void nfsd_stats_drc_mem_usage_add(struct nfsd_net *nn, s64 amount) + { +- percpu_counter_add(&nn->counter[NFSD_NET_DRC_MEM_USAGE], amount); ++ percpu_counter_add(&nn->counter[NFSD_STATS_DRC_MEM_USAGE], amount); + } + + static inline void nfsd_stats_drc_mem_usage_sub(struct nfsd_net *nn, s64 amount) + { +- percpu_counter_sub(&nn->counter[NFSD_NET_DRC_MEM_USAGE], amount); ++ percpu_counter_sub(&nn->counter[NFSD_STATS_DRC_MEM_USAGE], amount); + } + + #endif /* _NFSD_STATS_H */ +diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h +index 276420ea3b8d9..91e9921db725e 100644 +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -1260,6 +1260,28 @@ TRACE_EVENT(nfsd_drc_mismatch, + __entry->ingress) + ); + ++TRACE_EVENT_CONDITION(nfsd_drc_gc, ++ TP_PROTO( ++ const struct nfsd_net *nn, ++ unsigned long freed ++ ), ++ TP_ARGS(nn, freed), ++ TP_CONDITION(freed > 0), ++ TP_STRUCT__entry( ++ __field(unsigned long long, boot_time) ++ __field(unsigned long, freed) ++ __field(int, total) ++ ), ++ TP_fast_assign( ++ __entry->boot_time = nn->boot_time; ++ __entry->freed = freed; ++ __entry->total = atomic_read(&nn->num_drc_entries); ++ ), ++ TP_printk("boot_time=%16llx total=%d freed=%lu", ++ __entry->boot_time, __entry->total, __entry->freed ++ ) ++); ++ + TRACE_EVENT(nfsd_cb_args, + TP_PROTO( + const struct nfs4_client *clp, +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index 0f430548bfbbe..8716490301525 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -984,7 +984,9 @@ static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp, + unsigned long *count, u32 *eof, ssize_t host_err) + { + if (host_err >= 0) { +- nfsd_stats_io_read_add(fhp->fh_export, host_err); ++ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); ++ ++ nfsd_stats_io_read_add(nn, fhp->fh_export, host_err); + *eof = nfsd_eof_on_read(file, offset, host_err, *count); + *count = host_err; + fsnotify_access(file); +@@ -1127,7 +1129,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, + goto out_nfserr; + } + *cnt = host_err; +- nfsd_stats_io_write_add(exp, *cnt); ++ nfsd_stats_io_write_add(nn, exp, *cnt); + fsnotify_modify(file); + host_err = filemap_check_wb_err(file->f_mapping, since); + if (host_err < 0) +diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c +index 95589a496f0ff..7dccff6c99833 100644 +--- a/fs/ntfs3/bitmap.c ++++ b/fs/ntfs3/bitmap.c +@@ -661,7 +661,7 @@ int wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits) + wnd->total_zeroes = nbits; + wnd->extent_max = MINUS_ONE_T; + wnd->zone_bit = wnd->zone_end = 0; +- wnd->nwnd = bytes_to_block(sb, bitmap_size(nbits)); ++ wnd->nwnd = bytes_to_block(sb, ntfs3_bitmap_size(nbits)); + wnd->bits_last = nbits & (wbits - 1); + if (!wnd->bits_last) + wnd->bits_last = wbits; +@@ -1325,7 +1325,7 @@ int wnd_extend(struct wnd_bitmap *wnd, size_t new_bits) + return -EINVAL; + + /* Align to 8 byte boundary. */ +- new_wnd = bytes_to_block(sb, bitmap_size(new_bits)); ++ new_wnd = bytes_to_block(sb, ntfs3_bitmap_size(new_bits)); + new_last = new_bits & (wbits - 1); + if (!new_last) + new_last = wbits; +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index 4bd3e6718ee65..abf28c0db71a3 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -493,7 +493,7 @@ static int ntfs_extend_mft(struct ntfs_sb_info *sbi) + ni->mi.dirty = true; + + /* Step 2: Resize $MFT::BITMAP. */ +- new_bitmap_bytes = bitmap_size(new_mft_total); ++ new_bitmap_bytes = ntfs3_bitmap_size(new_mft_total); + + err = attr_set_size(ni, ATTR_BITMAP, NULL, 0, &sbi->mft.bitmap.run, + new_bitmap_bytes, &new_bitmap_bytes, true, NULL); +diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c +index 13f492d0d971f..9cffd59e9735b 100644 +--- a/fs/ntfs3/index.c ++++ b/fs/ntfs3/index.c +@@ -1461,8 +1461,8 @@ static int indx_create_allocate(struct ntfs_index *indx, struct ntfs_inode *ni, + + alloc->nres.valid_size = alloc->nres.data_size = cpu_to_le64(data_size); + +- err = ni_insert_resident(ni, bitmap_size(1), ATTR_BITMAP, in->name, +- in->name_len, &bitmap, NULL, NULL); ++ err = ni_insert_resident(ni, ntfs3_bitmap_size(1), ATTR_BITMAP, ++ in->name, in->name_len, &bitmap, NULL, NULL); + if (err) + goto out2; + +@@ -1523,8 +1523,9 @@ static int indx_add_allocate(struct ntfs_index *indx, struct ntfs_inode *ni, + if (bmp) { + /* Increase bitmap. */ + err = attr_set_size(ni, ATTR_BITMAP, in->name, in->name_len, +- &indx->bitmap_run, bitmap_size(bit + 1), +- NULL, true, NULL); ++ &indx->bitmap_run, ++ ntfs3_bitmap_size(bit + 1), NULL, true, ++ NULL); + if (err) + goto out1; + } +@@ -2087,7 +2088,7 @@ static int indx_shrink(struct ntfs_index *indx, struct ntfs_inode *ni, + if (err) + return err; + +- bpb = bitmap_size(bit); ++ bpb = ntfs3_bitmap_size(bit); + if (bpb * 8 == nbits) + return 0; + +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index e67bef4018079..b4c09b99edd1d 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -950,9 +950,9 @@ static inline bool run_is_empty(struct runs_tree *run) + } + + /* NTFS uses quad aligned bitmaps. */ +-static inline size_t bitmap_size(size_t bits) ++static inline size_t ntfs3_bitmap_size(size_t bits) + { +- return ALIGN((bits + 7) >> 3, 8); ++ return BITS_TO_U64(bits) * sizeof(u64); + } + + #define _100ns2seconds 10000000 +diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c +index 0a71075042bbb..2ce26062e55ed 100644 +--- a/fs/ntfs3/super.c ++++ b/fs/ntfs3/super.c +@@ -1103,7 +1103,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc) + + /* Check bitmap boundary. */ + tt = sbi->used.bitmap.nbits; +- if (inode->i_size < bitmap_size(tt)) { ++ if (inode->i_size < ntfs3_bitmap_size(tt)) { + err = -EINVAL; + goto put_inode_out; + } +diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c +index edb414d3fd164..3b62fbcefa8c3 100644 +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -995,9 +995,8 @@ struct dquot *dqget(struct super_block *sb, struct kqid qid) + * smp_mb__before_atomic() in dquot_acquire(). + */ + smp_rmb(); +-#ifdef CONFIG_QUOTA_DEBUG +- BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ +-#endif ++ /* Has somebody invalidated entry under us? */ ++ WARN_ON_ONCE(hlist_unhashed(&dquot->dq_hash)); + out: + if (empty) + do_destroy_dquot(empty); +diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h +index 37f36dad18bd4..ce03547d69f45 100644 +--- a/include/linux/bitmap.h ++++ b/include/linux/bitmap.h +@@ -236,22 +236,24 @@ extern int bitmap_print_list_to_buf(char *buf, const unsigned long *maskp, + #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) + #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) + ++#define bitmap_size(nbits) (ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE) ++ + static inline void bitmap_zero(unsigned long *dst, unsigned int nbits) + { +- unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); ++ unsigned int len = bitmap_size(nbits); + memset(dst, 0, len); + } + + static inline void bitmap_fill(unsigned long *dst, unsigned int nbits) + { +- unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); ++ unsigned int len = bitmap_size(nbits); + memset(dst, 0xff, len); + } + + static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, + unsigned int nbits) + { +- unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); ++ unsigned int len = bitmap_size(nbits); + memcpy(dst, src, len); + } + +@@ -266,6 +268,18 @@ static inline void bitmap_copy_clear_tail(unsigned long *dst, + dst[nbits / BITS_PER_LONG] &= BITMAP_LAST_WORD_MASK(nbits); + } + ++static inline void bitmap_copy_and_extend(unsigned long *to, ++ const unsigned long *from, ++ unsigned int count, unsigned int size) ++{ ++ unsigned int copy = BITS_TO_LONGS(count); ++ ++ memcpy(to, from, copy * sizeof(long)); ++ if (count % BITS_PER_LONG) ++ to[copy - 1] &= BITMAP_LAST_WORD_MASK(count); ++ memset(to + copy, 0, bitmap_size(size) - copy * sizeof(long)); ++} ++ + /* + * On 32-bit systems bitmaps are represented as u32 arrays internally, and + * therefore conversion is not needed when copying data from/to arrays of u32. +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 905844172cfd8..c6d57814988d2 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -235,7 +235,7 @@ struct request { + void *end_io_data; + }; + +-static inline int blk_validate_block_size(unsigned int bsize) ++static inline int blk_validate_block_size(unsigned long bsize) + { + if (bsize < 512 || bsize > PAGE_SIZE || !is_power_of_2(bsize)) + return -EINVAL; +diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h +index b3c230dea0713..4555a4cb4632a 100644 +--- a/include/linux/cpumask.h ++++ b/include/linux/cpumask.h +@@ -667,7 +667,7 @@ static inline int cpulist_parse(const char *buf, struct cpumask *dstp) + */ + static inline unsigned int cpumask_size(void) + { +- return BITS_TO_LONGS(nr_cpumask_bits) * sizeof(long); ++ return bitmap_size(nr_cpumask_bits); + } + + /* +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 61e86502fe65e..27da89d0ed5ac 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -2429,6 +2429,9 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src, + * Used to detect that mark_inode_dirty() should not move + * inode between dirty lists. + * ++ * I_LRU_ISOLATING Inode is pinned being isolated from LRU without holding ++ * i_count. ++ * + * Q: What is the difference between I_WILL_FREE and I_FREEING? + */ + #define I_DIRTY_SYNC (1 << 0) +@@ -2451,6 +2454,8 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src, + #define I_CREATING (1 << 15) + #define I_DONTCACHE (1 << 16) + #define I_SYNC_QUEUED (1 << 17) ++#define __I_LRU_ISOLATING 19 ++#define I_LRU_ISOLATING (1 << __I_LRU_ISOLATING) + + #define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC) + #define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES) +diff --git a/include/linux/pm.h b/include/linux/pm.h +index d1c19f5b1380f..b8578e1f7c110 100644 +--- a/include/linux/pm.h ++++ b/include/linux/pm.h +@@ -8,6 +8,7 @@ + #ifndef _LINUX_PM_H + #define _LINUX_PM_H + ++#include <linux/export.h> + #include <linux/list.h> + #include <linux/workqueue.h> + #include <linux/spinlock.h> +@@ -357,13 +358,47 @@ struct dev_pm_ops { + #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) + #endif + ++#define _DEFINE_DEV_PM_OPS(name, \ ++ suspend_fn, resume_fn, \ ++ runtime_suspend_fn, runtime_resume_fn, idle_fn) \ ++const struct dev_pm_ops name = { \ ++ SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ ++ RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \ ++} ++ ++#ifdef CONFIG_PM ++#define _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \ ++ runtime_resume_fn, idle_fn, sec) \ ++ _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \ ++ runtime_resume_fn, idle_fn); \ ++ _EXPORT_SYMBOL(name, sec) ++#else ++#define _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \ ++ runtime_resume_fn, idle_fn, sec) \ ++static __maybe_unused _DEFINE_DEV_PM_OPS(__static_##name, suspend_fn, \ ++ resume_fn, runtime_suspend_fn, \ ++ runtime_resume_fn, idle_fn) ++#endif ++ + /* + * Use this if you want to use the same suspend and resume callbacks for suspend + * to RAM and hibernation. ++ * ++ * If the underlying dev_pm_ops struct symbol has to be exported, use ++ * EXPORT_SIMPLE_DEV_PM_OPS() or EXPORT_GPL_SIMPLE_DEV_PM_OPS() instead. + */ + #define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ +-const struct dev_pm_ops name = { \ +- SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ ++ _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL) ++ ++#define EXPORT_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ ++ _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "") ++#define EXPORT_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ ++ _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "_gpl") ++ ++/* Deprecated. Use DEFINE_SIMPLE_DEV_PM_OPS() instead. */ ++#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ ++const struct dev_pm_ops __maybe_unused name = { \ ++ SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ + } + + /* +@@ -378,20 +413,10 @@ const struct dev_pm_ops name = { \ + * suspend and "early" resume callback pointers, .suspend_late() and + * .resume_early(), to the same routines as .runtime_suspend() and + * .runtime_resume(), respectively (and analogously for hibernation). ++ * ++ * Deprecated. You most likely don't want this macro. Use ++ * DEFINE_RUNTIME_DEV_PM_OPS() instead. + */ +-#define DEFINE_UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ +-static const struct dev_pm_ops name = { \ +- SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ +- RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ +-} +- +-/* Deprecated. Use DEFINE_SIMPLE_DEV_PM_OPS() instead. */ +-#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ +-const struct dev_pm_ops __maybe_unused name = { \ +- SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ +-} +- +-/* Deprecated. Use DEFINE_UNIVERSAL_DEV_PM_OPS() instead. */ + #define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ + const struct dev_pm_ops __maybe_unused name = { \ + SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ +diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h +index 7efb105183134..9a10b6bac4a71 100644 +--- a/include/linux/pm_runtime.h ++++ b/include/linux/pm_runtime.h +@@ -22,6 +22,20 @@ + usage_count */ + #define RPM_AUTO 0x08 /* Use autosuspend_delay */ + ++/* ++ * Use this for defining a set of PM operations to be used in all situations ++ * (system suspend, hibernation or runtime PM). ++ * ++ * Note that the behaviour differs from the deprecated UNIVERSAL_DEV_PM_OPS() ++ * macro, which uses the provided callbacks for both runtime PM and system ++ * sleep, while DEFINE_RUNTIME_DEV_PM_OPS() uses pm_runtime_force_suspend() ++ * and pm_runtime_force_resume() for its system sleep callbacks. ++ */ ++#define DEFINE_RUNTIME_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ ++ _DEFINE_DEV_PM_OPS(name, pm_runtime_force_suspend, \ ++ pm_runtime_force_resume, suspend_fn, \ ++ resume_fn, idle_fn) ++ + #ifdef CONFIG_PM + extern struct workqueue_struct *pm_wq; + +diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h +index 6e48c1c88f1bb..57e0d9b7553b4 100644 +--- a/include/linux/sunrpc/svc.h ++++ b/include/linux/sunrpc/svc.h +@@ -409,7 +409,6 @@ struct svc_program { + const struct svc_version **pg_vers; /* version array */ + char * pg_name; /* service name */ + char * pg_class; /* class name: services sharing authentication */ +- struct svc_stat * pg_stats; /* rpc statistics */ + int (*pg_authenticate)(struct svc_rqst *); + __be32 (*pg_init_request)(struct svc_rqst *, + const struct svc_program *, +@@ -483,7 +482,9 @@ void svc_rqst_replace_page(struct svc_rqst *rqstp, + struct page *page); + void svc_rqst_free(struct svc_rqst *); + void svc_exit_thread(struct svc_rqst *); +-struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int, ++struct svc_serv * svc_create_pooled(struct svc_program *prog, ++ struct svc_stat *stats, ++ unsigned int bufsize, + int (*threadfn)(void *data)); + int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int); + int svc_pool_stats_open(struct svc_serv *serv, struct file *file); +diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h +index 3459a04a3d61c..2c37aa0a4ccb9 100644 +--- a/include/net/busy_poll.h ++++ b/include/net/busy_poll.h +@@ -63,7 +63,7 @@ static inline bool sk_can_busy_loop(struct sock *sk) + static inline unsigned long busy_loop_current_time(void) + { + #ifdef CONFIG_NET_RX_BUSY_POLL +- return (unsigned long)(local_clock() >> 10); ++ return (unsigned long)(ktime_get_ns() >> 10); + #else + return 0; + #endif +diff --git a/include/net/kcm.h b/include/net/kcm.h +index 2d704f8f49059..8e8252e08a9ce 100644 +--- a/include/net/kcm.h ++++ b/include/net/kcm.h +@@ -70,6 +70,7 @@ struct kcm_sock { + struct work_struct tx_work; + struct list_head wait_psock_list; + struct sk_buff *seq_skb; ++ struct mutex tx_mutex; + u32 tx_stopped : 1; + + /* Don't use bit fields here, these are set under different locks */ +diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h +index e1180771604d7..fb39edba3dea9 100644 +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -247,7 +247,7 @@ static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) + + static inline unsigned int scsi_logical_block_count(struct scsi_cmnd *scmd) + { +- unsigned int shift = ilog2(scmd->device->sector_size) - SECTOR_SHIFT; ++ unsigned int shift = ilog2(scmd->device->sector_size); + + return blk_rq_bytes(scsi_cmd_to_rq(scmd)) >> shift; + } +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index 82df5a07a8696..d6e70aa7e151d 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -22,6 +22,7 @@ + * distribution for more details. + */ + ++#include "cgroup-internal.h" + #include <linux/cpu.h> + #include <linux/cpumask.h> + #include <linux/cpuset.h> +@@ -3780,10 +3781,14 @@ int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns, + if (!buf) + goto out; + +- css = task_get_css(tsk, cpuset_cgrp_id); +- retval = cgroup_path_ns(css->cgroup, buf, PATH_MAX, +- current->nsproxy->cgroup_ns); +- css_put(css); ++ rcu_read_lock(); ++ spin_lock_irq(&css_set_lock); ++ css = task_css(tsk, cpuset_cgrp_id); ++ retval = cgroup_path_ns_locked(css->cgroup, buf, PATH_MAX, ++ current->nsproxy->cgroup_ns); ++ spin_unlock_irq(&css_set_lock); ++ rcu_read_unlock(); ++ + if (retval >= PATH_MAX) + retval = -ENAMETOOLONG; + if (retval < 0) +diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c +index 3ccb383741d08..5aa8eec89e781 100644 +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -20,6 +20,16 @@ + #include "tick-internal.h" + #include "timekeeping_internal.h" + ++static noinline u64 cycles_to_nsec_safe(struct clocksource *cs, u64 start, u64 end) ++{ ++ u64 delta = clocksource_delta(end, start, cs->mask); ++ ++ if (likely(delta < cs->max_cycles)) ++ return clocksource_cyc2ns(delta, cs->mult, cs->shift); ++ ++ return mul_u64_u32_shr(delta, cs->mult, cs->shift); ++} ++ + /** + * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks + * @mult: pointer to mult variable +@@ -213,8 +223,8 @@ enum wd_read_status { + static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) + { + unsigned int nretries, max_retries; +- u64 wd_end, wd_end2, wd_delta; + int64_t wd_delay, wd_seq_delay; ++ u64 wd_end, wd_end2; + + max_retries = clocksource_get_max_watchdog_retry(); + for (nretries = 0; nretries <= max_retries; nretries++) { +@@ -225,9 +235,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, + wd_end2 = watchdog->read(watchdog); + local_irq_enable(); + +- wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask); +- wd_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, +- watchdog->shift); ++ wd_delay = cycles_to_nsec_safe(watchdog, *wdnow, wd_end); + if (wd_delay <= WATCHDOG_MAX_SKEW) { + if (nretries > 1 && nretries >= max_retries) { + pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n", +@@ -245,8 +253,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, + * report system busy, reinit the watchdog and skip the current + * watchdog test. + */ +- wd_delta = clocksource_delta(wd_end2, wd_end, watchdog->mask); +- wd_seq_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, watchdog->shift); ++ wd_seq_delay = cycles_to_nsec_safe(watchdog, wd_end, wd_end2); + if (wd_seq_delay > WATCHDOG_MAX_SKEW/2) + goto skip_test; + } +@@ -357,8 +364,7 @@ void clocksource_verify_percpu(struct clocksource *cs) + delta = (csnow_end - csnow_mid) & cs->mask; + if (delta < 0) + cpumask_set_cpu(cpu, &cpus_ahead); +- delta = clocksource_delta(csnow_end, csnow_begin, cs->mask); +- cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift); ++ cs_nsec = cycles_to_nsec_safe(cs, csnow_begin, csnow_end); + if (cs_nsec > cs_nsec_max) + cs_nsec_max = cs_nsec; + if (cs_nsec < cs_nsec_min) +@@ -389,8 +395,8 @@ static inline void clocksource_reset_watchdog(void) + + static void clocksource_watchdog(struct timer_list *unused) + { +- u64 csnow, wdnow, cslast, wdlast, delta; + int64_t wd_nsec, cs_nsec, interval; ++ u64 csnow, wdnow, cslast, wdlast; + int next_cpu, reset_pending; + struct clocksource *cs; + enum wd_read_status read_ret; +@@ -447,12 +453,8 @@ static void clocksource_watchdog(struct timer_list *unused) + continue; + } + +- delta = clocksource_delta(wdnow, cs->wd_last, watchdog->mask); +- wd_nsec = clocksource_cyc2ns(delta, watchdog->mult, +- watchdog->shift); +- +- delta = clocksource_delta(csnow, cs->cs_last, cs->mask); +- cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift); ++ wd_nsec = cycles_to_nsec_safe(watchdog, cs->wd_last, wdnow); ++ cs_nsec = cycles_to_nsec_safe(cs, cs->cs_last, csnow); + wdlast = cs->wd_last; /* save these in case we print them */ + cslast = cs->cs_last; + cs->cs_last = csnow; +@@ -815,7 +817,7 @@ void clocksource_start_suspend_timing(struct clocksource *cs, u64 start_cycles) + */ + u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 cycle_now) + { +- u64 now, delta, nsec = 0; ++ u64 now, nsec = 0; + + if (!suspend_clocksource) + return 0; +@@ -830,12 +832,8 @@ u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 cycle_now) + else + now = suspend_clocksource->read(suspend_clocksource); + +- if (now > suspend_start) { +- delta = clocksource_delta(now, suspend_start, +- suspend_clocksource->mask); +- nsec = mul_u64_u32_shr(delta, suspend_clocksource->mult, +- suspend_clocksource->shift); +- } ++ if (now > suspend_start) ++ nsec = cycles_to_nsec_safe(suspend_clocksource, suspend_start, now); + + /* + * Disable the suspend timer to save power if current clocksource is +diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c +index 5502c687bd401..bdd9041d595e9 100644 +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -1284,6 +1284,8 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, + struct hrtimer_clock_base *base; + unsigned long flags; + ++ if (WARN_ON_ONCE(!timer->function)) ++ return; + /* + * Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft + * match on CONFIG_PREEMPT_RT = n. With PREEMPT_RT check the hard +diff --git a/lib/math/prime_numbers.c b/lib/math/prime_numbers.c +index d42cebf7407fc..d3b64b10da1c5 100644 +--- a/lib/math/prime_numbers.c ++++ b/lib/math/prime_numbers.c +@@ -6,8 +6,6 @@ + #include <linux/prime_numbers.h> + #include <linux/slab.h> + +-#define bitmap_size(nbits) (BITS_TO_LONGS(nbits) * sizeof(unsigned long)) +- + struct primes { + struct rcu_head rcu; + unsigned long last, sz; +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 98ff57c8eda69..9139da4baa39f 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -1437,7 +1437,7 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf) + vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd); + if (unlikely(!pmd_same(oldpmd, *vmf->pmd))) { + spin_unlock(vmf->ptl); +- goto out; ++ return 0; + } + + pmd = pmd_modify(oldpmd, vma->vm_page_prot); +@@ -1465,23 +1465,16 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf) + if (migrated) { + flags |= TNF_MIGRATED; + page_nid = target_nid; +- } else { +- flags |= TNF_MIGRATE_FAIL; +- vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd); +- if (unlikely(!pmd_same(oldpmd, *vmf->pmd))) { +- spin_unlock(vmf->ptl); +- goto out; +- } +- goto out_map; ++ task_numa_fault(last_cpupid, page_nid, HPAGE_PMD_NR, flags); ++ return 0; + } + +-out: +- if (page_nid != NUMA_NO_NODE) +- task_numa_fault(last_cpupid, page_nid, HPAGE_PMD_NR, +- flags); +- +- return 0; +- ++ flags |= TNF_MIGRATE_FAIL; ++ vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd); ++ if (unlikely(!pmd_same(oldpmd, *vmf->pmd))) { ++ spin_unlock(vmf->ptl); ++ return 0; ++ } + out_map: + /* Restore the PMD */ + pmd = pmd_modify(oldpmd, vma->vm_page_prot); +@@ -1491,7 +1484,10 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf) + set_pmd_at(vma->vm_mm, haddr, vmf->pmd, pmd); + update_mmu_cache_pmd(vma, vmf->address, vmf->pmd); + spin_unlock(vmf->ptl); +- goto out; ++ ++ if (page_nid != NUMA_NO_NODE) ++ task_numa_fault(last_cpupid, page_nid, HPAGE_PMD_NR, flags); ++ return 0; + } + + /* +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index 6f969ba0d6888..69dd12a799428 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -4807,9 +4807,12 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of, + buf = endp + 1; + + cfd = simple_strtoul(buf, &endp, 10); +- if ((*endp != ' ') && (*endp != '\0')) ++ if (*endp == '\0') ++ buf = endp; ++ else if (*endp == ' ') ++ buf = endp + 1; ++ else + return -EINVAL; +- buf = endp + 1; + + event = kzalloc(sizeof(*event), GFP_KERNEL); + if (!event) +diff --git a/mm/memory.c b/mm/memory.c +index 99d15abe4a061..4d6eda1cdb6db 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -4407,7 +4407,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf) + spin_lock(vmf->ptl); + if (unlikely(!pte_same(*vmf->pte, vmf->orig_pte))) { + pte_unmap_unlock(vmf->pte, vmf->ptl); +- goto out; ++ return 0; + } + + /* Get the normal PTE */ +@@ -4454,21 +4454,17 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf) + if (migrate_misplaced_page(page, vma, target_nid)) { + page_nid = target_nid; + flags |= TNF_MIGRATED; +- } else { +- flags |= TNF_MIGRATE_FAIL; +- vmf->pte = pte_offset_map(vmf->pmd, vmf->address); +- spin_lock(vmf->ptl); +- if (unlikely(!pte_same(*vmf->pte, vmf->orig_pte))) { +- pte_unmap_unlock(vmf->pte, vmf->ptl); +- goto out; +- } +- goto out_map; ++ task_numa_fault(last_cpupid, page_nid, 1, flags); ++ return 0; + } + +-out: +- if (page_nid != NUMA_NO_NODE) +- task_numa_fault(last_cpupid, page_nid, 1, flags); +- return 0; ++ flags |= TNF_MIGRATE_FAIL; ++ vmf->pte = pte_offset_map(vmf->pmd, vmf->address); ++ spin_lock(vmf->ptl); ++ if (unlikely(!pte_same(*vmf->pte, vmf->orig_pte))) { ++ pte_unmap_unlock(vmf->pte, vmf->ptl); ++ return 0; ++ } + out_map: + /* + * Make it present again, depending on how arch implements +@@ -4482,7 +4478,10 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf) + ptep_modify_prot_commit(vma, vmf->address, vmf->pte, old_pte, pte); + update_mmu_cache(vma, vmf->address, vmf->pte); + pte_unmap_unlock(vmf->pte, vmf->ptl); +- goto out; ++ ++ if (page_nid != NUMA_NO_NODE) ++ task_numa_fault(last_cpupid, page_nid, 1, flags); ++ return 0; + } + + static inline vm_fault_t create_huge_pmd(struct vm_fault *vmf) +diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c +index a796d72c7dbaa..8bb6c8ad11313 100644 +--- a/net/bluetooth/bnep/core.c ++++ b/net/bluetooth/bnep/core.c +@@ -385,7 +385,8 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) + + case BNEP_COMPRESSED_DST_ONLY: + __skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN); +- __skb_put_data(nskb, s->eh.h_source, ETH_ALEN + 2); ++ __skb_put_data(nskb, s->eh.h_source, ETH_ALEN); ++ put_unaligned(s->eh.h_proto, (__be16 *)__skb_put(nskb, 2)); + break; + + case BNEP_GENERAL: +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index fc4e02b3f26ad..7dff3f1a2a9eb 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -4876,19 +4876,19 @@ static void hci_sched_le(struct hci_dev *hdev) + { + struct hci_chan *chan; + struct sk_buff *skb; +- int quote, cnt, tmp; ++ int quote, *cnt, tmp; + + BT_DBG("%s", hdev->name); + + if (!hci_conn_num(hdev, LE_LINK)) + return; + +- cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; ++ cnt = hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt; + +- __check_timeout(hdev, cnt, LE_LINK); ++ __check_timeout(hdev, *cnt, LE_LINK); + +- tmp = cnt; +- while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { ++ tmp = *cnt; ++ while (*cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { + u32 priority = (skb_peek(&chan->data_q))->priority; + while (quote-- && (skb = skb_peek(&chan->data_q))) { + BT_DBG("chan %p skb %p len %d priority %u", chan, skb, +@@ -4903,7 +4903,7 @@ static void hci_sched_le(struct hci_dev *hdev) + hci_send_frame(hdev, skb); + hdev->le_last_tx = jiffies; + +- cnt--; ++ (*cnt)--; + chan->sent++; + chan->conn->sent++; + +@@ -4913,12 +4913,7 @@ static void hci_sched_le(struct hci_dev *hdev) + } + } + +- if (hdev->le_pkts) +- hdev->le_cnt = cnt; +- else +- hdev->acl_cnt = cnt; +- +- if (cnt != tmp) ++ if (*cnt != tmp) + hci_prio_recalculate(hdev, LE_LINK); + } + +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index 8f1162961836a..f59775973cdf7 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -2967,6 +2967,10 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, + * will be kept and this function does nothing. + */ + p = hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type); ++ if (!p) { ++ err = -EIO; ++ goto unlock; ++ } + + if (p->auto_connect == HCI_AUTO_CONN_EXPLICIT) + p->auto_connect = HCI_AUTO_CONN_DISABLED; +diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c +index f688f941c40c4..629d25bc7f671 100644 +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -913,7 +913,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, + * Confirms and the responder Enters the passkey. + */ + if (smp->method == OVERLAP) { +- if (hcon->role == HCI_ROLE_MASTER) ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) + smp->method = CFM_PASSKEY; + else + smp->method = REQ_PASSKEY; +@@ -963,7 +963,7 @@ static u8 smp_confirm(struct smp_chan *smp) + + smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); + +- if (conn->hcon->out) ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) + SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); + else + SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); +@@ -979,7 +979,8 @@ static u8 smp_random(struct smp_chan *smp) + int ret; + + bt_dev_dbg(conn->hcon->hdev, "conn %p %s", conn, +- conn->hcon->out ? "initiator" : "responder"); ++ test_bit(SMP_FLAG_INITIATOR, &smp->flags) ? "initiator" : ++ "responder"); + + ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, + hcon->init_addr_type, &hcon->init_addr, +@@ -993,7 +994,7 @@ static u8 smp_random(struct smp_chan *smp) + return SMP_CONFIRM_FAILED; + } + +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + u8 stk[16]; + __le64 rand = 0; + __le16 ediv = 0; +@@ -1250,14 +1251,15 @@ static void smp_distribute_keys(struct smp_chan *smp) + rsp = (void *) &smp->prsp[1]; + + /* The responder sends its keys first */ +- if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags) && ++ (smp->remote_key_dist & KEY_DIST_MASK)) { + smp_allow_key_dist(smp); + return; + } + + req = (void *) &smp->preq[1]; + +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + keydist = &rsp->init_key_dist; + *keydist &= req->init_key_dist; + } else { +@@ -1426,7 +1428,7 @@ static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16]) + struct hci_conn *hcon = smp->conn->hcon; + u8 *na, *nb, a[7], b[7]; + +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + na = smp->prnd; + nb = smp->rrnd; + } else { +@@ -1454,7 +1456,7 @@ static void sc_dhkey_check(struct smp_chan *smp) + a[6] = hcon->init_addr_type; + b[6] = hcon->resp_addr_type; + +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + local_addr = a; + remote_addr = b; + memcpy(io_cap, &smp->preq[1], 3); +@@ -1533,7 +1535,7 @@ static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op) + /* The round is only complete when the initiator + * receives pairing random. + */ +- if (!hcon->out) { ++ if (!test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, + sizeof(smp->prnd), smp->prnd); + if (smp->passkey_round == 20) +@@ -1561,7 +1563,7 @@ static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op) + + SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); + +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, + sizeof(smp->prnd), smp->prnd); + return 0; +@@ -1572,7 +1574,7 @@ static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op) + case SMP_CMD_PUBLIC_KEY: + default: + /* Initiating device starts the round */ +- if (!hcon->out) ++ if (!test_bit(SMP_FLAG_INITIATOR, &smp->flags)) + return 0; + + bt_dev_dbg(hdev, "Starting passkey round %u", +@@ -1617,7 +1619,7 @@ static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey) + } + + /* Initiator sends DHKey check first */ +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + sc_dhkey_check(smp); + SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); + } else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) { +@@ -1740,7 +1742,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) + struct smp_cmd_pairing rsp, *req = (void *) skb->data; + struct l2cap_chan *chan = conn->smp; + struct hci_dev *hdev = conn->hcon->hdev; +- struct smp_chan *smp; ++ struct smp_chan *smp = chan->data; + u8 key_size, auth, sec_level; + int ret; + +@@ -1749,16 +1751,14 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) + if (skb->len < sizeof(*req)) + return SMP_INVALID_PARAMS; + +- if (conn->hcon->role != HCI_ROLE_SLAVE) ++ if (smp && test_bit(SMP_FLAG_INITIATOR, &smp->flags)) + return SMP_CMD_NOTSUPP; + +- if (!chan->data) ++ if (!smp) { + smp = smp_chan_create(conn); +- else +- smp = chan->data; +- +- if (!smp) +- return SMP_UNSPECIFIED; ++ if (!smp) ++ return SMP_UNSPECIFIED; ++ } + + /* We didn't start the pairing, so match remote */ + auth = req->auth_req & AUTH_REQ_MASK(hdev); +@@ -1940,7 +1940,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) + if (skb->len < sizeof(*rsp)) + return SMP_INVALID_PARAMS; + +- if (conn->hcon->role != HCI_ROLE_MASTER) ++ if (!test_bit(SMP_FLAG_INITIATOR, &smp->flags)) + return SMP_CMD_NOTSUPP; + + skb_pull(skb, sizeof(*rsp)); +@@ -2035,7 +2035,7 @@ static u8 sc_check_confirm(struct smp_chan *smp) + if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) + return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM); + +- if (conn->hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), + smp->prnd); + SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); +@@ -2057,7 +2057,7 @@ static int fixup_sc_false_positive(struct smp_chan *smp) + u8 auth; + + /* The issue is only observed when we're in responder role */ +- if (hcon->out) ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) + return SMP_UNSPECIFIED; + + if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) { +@@ -2093,7 +2093,8 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) + struct hci_dev *hdev = hcon->hdev; + + bt_dev_dbg(hdev, "conn %p %s", conn, +- hcon->out ? "initiator" : "responder"); ++ test_bit(SMP_FLAG_INITIATOR, &smp->flags) ? "initiator" : ++ "responder"); + + if (skb->len < sizeof(smp->pcnf)) + return SMP_INVALID_PARAMS; +@@ -2115,7 +2116,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) + return ret; + } + +- if (conn->hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), + smp->prnd); + SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); +@@ -2150,7 +2151,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) + if (!test_bit(SMP_FLAG_SC, &smp->flags)) + return smp_random(smp); + +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + pkax = smp->local_pk; + pkbx = smp->remote_pk; + na = smp->prnd; +@@ -2163,7 +2164,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) + } + + if (smp->method == REQ_OOB) { +- if (!hcon->out) ++ if (!test_bit(SMP_FLAG_INITIATOR, &smp->flags)) + smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, + sizeof(smp->prnd), smp->prnd); + SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); +@@ -2174,7 +2175,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) + if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) + return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM); + +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + u8 cfm[16]; + + err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk, +@@ -2215,7 +2216,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) + return SMP_UNSPECIFIED; + + if (smp->method == REQ_OOB) { +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + sc_dhkey_check(smp); + SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); + } +@@ -2289,10 +2290,27 @@ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level, + return false; + } + ++static void smp_send_pairing_req(struct smp_chan *smp, __u8 auth) ++{ ++ struct smp_cmd_pairing cp; ++ ++ if (smp->conn->hcon->type == ACL_LINK) ++ build_bredr_pairing_cmd(smp, &cp, NULL); ++ else ++ build_pairing_cmd(smp->conn, &cp, NULL, auth); ++ ++ smp->preq[0] = SMP_CMD_PAIRING_REQ; ++ memcpy(&smp->preq[1], &cp, sizeof(cp)); ++ ++ smp_send_cmd(smp->conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); ++ SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); ++ ++ set_bit(SMP_FLAG_INITIATOR, &smp->flags); ++} ++ + static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) + { + struct smp_cmd_security_req *rp = (void *) skb->data; +- struct smp_cmd_pairing cp; + struct hci_conn *hcon = conn->hcon; + struct hci_dev *hdev = hcon->hdev; + struct smp_chan *smp; +@@ -2341,16 +2359,20 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) + + skb_pull(skb, sizeof(*rp)); + +- memset(&cp, 0, sizeof(cp)); +- build_pairing_cmd(conn, &cp, NULL, auth); ++ smp_send_pairing_req(smp, auth); + +- smp->preq[0] = SMP_CMD_PAIRING_REQ; +- memcpy(&smp->preq[1], &cp, sizeof(cp)); ++ return 0; ++} + +- smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); +- SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); ++static void smp_send_security_req(struct smp_chan *smp, __u8 auth) ++{ ++ struct smp_cmd_security_req cp; + +- return 0; ++ cp.auth_req = auth; ++ smp_send_cmd(smp->conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); ++ SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); ++ ++ clear_bit(SMP_FLAG_INITIATOR, &smp->flags); + } + + int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) +@@ -2421,23 +2443,11 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) + authreq |= SMP_AUTH_MITM; + } + +- if (hcon->role == HCI_ROLE_MASTER) { +- struct smp_cmd_pairing cp; +- +- build_pairing_cmd(conn, &cp, NULL, authreq); +- smp->preq[0] = SMP_CMD_PAIRING_REQ; +- memcpy(&smp->preq[1], &cp, sizeof(cp)); +- +- smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); +- SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); +- } else { +- struct smp_cmd_security_req cp; +- cp.auth_req = authreq; +- smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); +- SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); +- } ++ if (hcon->role == HCI_ROLE_MASTER) ++ smp_send_pairing_req(smp, authreq); ++ else ++ smp_send_security_req(smp, authreq); + +- set_bit(SMP_FLAG_INITIATOR, &smp->flags); + ret = 0; + + unlock: +@@ -2688,8 +2698,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) + + static u8 sc_select_method(struct smp_chan *smp) + { +- struct l2cap_conn *conn = smp->conn; +- struct hci_conn *hcon = conn->hcon; + struct smp_cmd_pairing *local, *remote; + u8 local_mitm, remote_mitm, local_io, remote_io, method; + +@@ -2702,7 +2710,7 @@ static u8 sc_select_method(struct smp_chan *smp) + * the "struct smp_cmd_pairing" from them we need to skip the + * first byte which contains the opcode. + */ +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + local = (void *) &smp->preq[1]; + remote = (void *) &smp->prsp[1]; + } else { +@@ -2771,7 +2779,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) + /* Non-initiating device sends its public key after receiving + * the key from the initiating device. + */ +- if (!hcon->out) { ++ if (!test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + err = sc_send_public_key(smp); + if (err) + return err; +@@ -2833,7 +2841,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) + } + + if (smp->method == REQ_OOB) { +- if (hcon->out) ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) + smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, + sizeof(smp->prnd), smp->prnd); + +@@ -2842,7 +2850,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) + return 0; + } + +- if (hcon->out) ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) + SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); + + if (smp->method == REQ_PASSKEY) { +@@ -2857,7 +2865,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) + /* The Initiating device waits for the non-initiating device to + * send the confirm value. + */ +- if (conn->hcon->out) ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) + return 0; + + err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, +@@ -2891,7 +2899,7 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) + a[6] = hcon->init_addr_type; + b[6] = hcon->resp_addr_type; + +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + local_addr = a; + remote_addr = b; + memcpy(io_cap, &smp->prsp[1], 3); +@@ -2916,7 +2924,7 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) + if (crypto_memneq(check->e, e, 16)) + return SMP_DHKEY_CHECK_FAILED; + +- if (!hcon->out) { ++ if (!test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) { + set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags); + return 0; +@@ -2928,7 +2936,7 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) + + sc_add_ltk(smp); + +- if (hcon->out) { ++ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) { + hci_le_start_enc(hcon, 0, 0, smp->tk, smp->enc_key_size); + hcon->enc_key_size = smp->enc_key_size; + } +@@ -3077,7 +3085,6 @@ static void bredr_pairing(struct l2cap_chan *chan) + struct l2cap_conn *conn = chan->conn; + struct hci_conn *hcon = conn->hcon; + struct hci_dev *hdev = hcon->hdev; +- struct smp_cmd_pairing req; + struct smp_chan *smp; + + bt_dev_dbg(hdev, "chan %p", chan); +@@ -3129,14 +3136,7 @@ static void bredr_pairing(struct l2cap_chan *chan) + + bt_dev_dbg(hdev, "starting SMP over BR/EDR"); + +- /* Prepare and send the BR/EDR SMP Pairing Request */ +- build_bredr_pairing_cmd(smp, &req, NULL); +- +- smp->preq[0] = SMP_CMD_PAIRING_REQ; +- memcpy(&smp->preq[1], &req, sizeof(req)); +- +- smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req); +- SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); ++ smp_send_pairing_req(smp, 0x00); + } + + static void smp_resume_cb(struct l2cap_chan *chan) +diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c +index 9981e0dfdd4d3..d0d41dbbfe382 100644 +--- a/net/bridge/br_netfilter_hooks.c ++++ b/net/bridge/br_netfilter_hooks.c +@@ -602,8 +602,12 @@ static unsigned int br_nf_local_in(void *priv, + if (likely(nf_ct_is_confirmed(ct))) + return NF_ACCEPT; + ++ if (WARN_ON_ONCE(refcount_read(&nfct->use) != 1)) { ++ nf_reset_ct(skb); ++ return NF_ACCEPT; ++ } ++ + WARN_ON_ONCE(skb_shared(skb)); +- WARN_ON_ONCE(refcount_read(&nfct->use) != 1); + + /* We can't call nf_confirm here, it would create a dependency + * on nf_conntrack module. +diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c +index e9ea0695efb42..173ea92124f8c 100644 +--- a/net/core/net-sysfs.c ++++ b/net/core/net-sysfs.c +@@ -214,7 +214,7 @@ static ssize_t speed_show(struct device *dev, + if (!rtnl_trylock()) + return restart_syscall(); + +- if (netif_running(netdev) && netif_device_present(netdev)) { ++ if (netif_running(netdev)) { + struct ethtool_link_ksettings cmd; + + if (!__ethtool_get_link_ksettings(netdev, &cmd)) +diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c +index 53e2ef6ada8f3..1e9e70a633d1c 100644 +--- a/net/ethtool/ioctl.c ++++ b/net/ethtool/ioctl.c +@@ -433,6 +433,9 @@ int __ethtool_get_link_ksettings(struct net_device *dev, + if (!dev->ethtool_ops->get_link_ksettings) + return -EOPNOTSUPP; + ++ if (!netif_device_present(dev)) ++ return -ENODEV; ++ + memset(link_ksettings, 0, sizeof(*link_ksettings)); + return dev->ethtool_ops->get_link_ksettings(dev, link_ksettings); + } +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index ce37c83455796..b37121f872bc9 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -69,11 +69,15 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * + + /* Be paranoid, rather than too clever. */ + if (unlikely(hh_len > skb_headroom(skb)) && dev->header_ops) { ++ /* Make sure idev stays alive */ ++ rcu_read_lock(); + skb = skb_expand_head(skb, hh_len); + if (!skb) { + IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); ++ rcu_read_unlock(); + return -ENOMEM; + } ++ rcu_read_unlock(); + } + + hdr = ipv6_hdr(skb); +@@ -269,11 +273,15 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, + head_room += opt->opt_nflen + opt->opt_flen; + + if (unlikely(head_room > skb_headroom(skb))) { ++ /* Make sure idev stays alive */ ++ rcu_read_lock(); + skb = skb_expand_head(skb, head_room); + if (!skb) { + IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); ++ rcu_read_unlock(); + return -ENOBUFS; + } ++ rcu_read_unlock(); + } + + if (opt) { +@@ -1940,6 +1948,7 @@ int ip6_send_skb(struct sk_buff *skb) + struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); + int err; + ++ rcu_read_lock(); + err = ip6_local_out(net, skb->sk, skb); + if (err) { + if (err > 0) +@@ -1949,6 +1958,7 @@ int ip6_send_skb(struct sk_buff *skb) + IPSTATS_MIB_OUTDISCARDS); + } + ++ rcu_read_unlock(); + return err; + } + +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index d370a71c97520..5955fca601b3a 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1501,7 +1501,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) + tdev = __dev_get_by_index(t->net, p->link); + + if (tdev) { +- dev->hard_header_len = tdev->hard_header_len + t_hlen; ++ dev->needed_headroom = tdev->hard_header_len + ++ tdev->needed_headroom + t_hlen; + mtu = min_t(unsigned int, tdev->mtu, IP6_MAX_MTU); + + mtu = mtu - t_hlen; +@@ -1729,7 +1730,9 @@ ip6_tnl_siocdevprivate(struct net_device *dev, struct ifreq *ifr, + int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) + { + struct ip6_tnl *tnl = netdev_priv(dev); ++ int t_hlen; + ++ t_hlen = tnl->hlen + sizeof(struct ipv6hdr); + if (tnl->parms.proto == IPPROTO_IPV6) { + if (new_mtu < IPV6_MIN_MTU) + return -EINVAL; +@@ -1738,10 +1741,10 @@ int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) + return -EINVAL; + } + if (tnl->parms.proto == IPPROTO_IPV6 || tnl->parms.proto == 0) { +- if (new_mtu > IP6_MAX_MTU - dev->hard_header_len) ++ if (new_mtu > IP6_MAX_MTU - dev->hard_header_len - t_hlen) + return -EINVAL; + } else { +- if (new_mtu > IP_MAX_MTU - dev->hard_header_len) ++ if (new_mtu > IP_MAX_MTU - dev->hard_header_len - t_hlen) + return -EINVAL; + } + dev->mtu = new_mtu; +@@ -1887,12 +1890,11 @@ ip6_tnl_dev_init_gen(struct net_device *dev) + t_hlen = t->hlen + sizeof(struct ipv6hdr); + + dev->type = ARPHRD_TUNNEL6; +- dev->hard_header_len = LL_MAX_HEADER + t_hlen; + dev->mtu = ETH_DATA_LEN - t_hlen; + if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) + dev->mtu -= 8; + dev->min_mtu = ETH_MIN_MTU; +- dev->max_mtu = IP6_MAX_MTU - dev->hard_header_len; ++ dev->max_mtu = IP6_MAX_MTU - dev->hard_header_len - t_hlen; + + dev_hold(dev); + return 0; +diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c +index 5c47be29b9ee9..2e5b090d7c89f 100644 +--- a/net/ipv6/netfilter/nf_conntrack_reasm.c ++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c +@@ -155,6 +155,10 @@ static struct frag_queue *fq_find(struct net *net, __be32 id, u32 user, + }; + struct inet_frag_queue *q; + ++ if (!(ipv6_addr_type(&hdr->daddr) & (IPV6_ADDR_MULTICAST | ++ IPV6_ADDR_LINKLOCAL))) ++ key.iif = 0; ++ + q = inet_frag_find(nf_frag->fqdir, &key); + if (!q) + return NULL; +diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c +index 30fc78236050a..1a88ed72a7a97 100644 +--- a/net/iucv/iucv.c ++++ b/net/iucv/iucv.c +@@ -1090,8 +1090,7 @@ static int iucv_message_receive_iprmdata(struct iucv_path *path, + size = (size < 8) ? size : 8; + for (array = buffer; size > 0; array++) { + copy = min_t(size_t, size, array->length); +- memcpy((u8 *)(addr_t) array->address, +- rmmsg, copy); ++ memcpy(phys_to_virt(array->address), rmmsg, copy); + rmmsg += copy; + size -= copy; + } +diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c +index 5457ca1909801..a3b281f7a99bc 100644 +--- a/net/kcm/kcmsock.c ++++ b/net/kcm/kcmsock.c +@@ -911,6 +911,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + !(msg->msg_flags & MSG_MORE) : !!(msg->msg_flags & MSG_EOR); + int err = -EPIPE; + ++ mutex_lock(&kcm->tx_mutex); + lock_sock(sk); + + /* Per tcp_sendmsg this should be in poll */ +@@ -1059,6 +1060,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + KCM_STATS_ADD(kcm->stats.tx_bytes, copied); + + release_sock(sk); ++ mutex_unlock(&kcm->tx_mutex); + return copied; + + out_error: +@@ -1084,6 +1086,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + sk->sk_write_space(sk); + + release_sock(sk); ++ mutex_unlock(&kcm->tx_mutex); + return err; + } + +@@ -1326,6 +1329,7 @@ static void init_kcm_sock(struct kcm_sock *kcm, struct kcm_mux *mux) + spin_unlock_bh(&mux->lock); + + INIT_WORK(&kcm->tx_work, kcm_tx_work); ++ mutex_init(&kcm->tx_mutex); + + spin_lock_bh(&mux->rx_lock); + kcm_rcv_ready(kcm); +diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c +index a4d3fa14f76b7..1deb3d874a4b9 100644 +--- a/net/mac80211/agg-tx.c ++++ b/net/mac80211/agg-tx.c +@@ -491,7 +491,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) + { + struct tid_ampdu_tx *tid_tx; + struct ieee80211_local *local = sta->local; +- struct ieee80211_sub_if_data *sdata; ++ struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ieee80211_ampdu_params params = { + .sta = &sta->sta, + .action = IEEE80211_AMPDU_TX_START, +@@ -521,7 +521,6 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) + */ + synchronize_net(); + +- sdata = sta->sdata; + params.ssn = sta->tid_seq[tid] >> 4; + ret = drv_ampdu_action(local, sdata, ¶ms); + tid_tx->ssn = params.ssn; +@@ -535,9 +534,6 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) + */ + set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state); + } else if (ret) { +- if (!sdata) +- return; +- + ht_dbg(sdata, + "BA request denied - HW unavailable for %pM tid %d\n", + sta->sta.addr, tid); +diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c +index 120bd9cdf7dfa..48322e45e7ddb 100644 +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -331,9 +331,6 @@ int drv_ampdu_action(struct ieee80211_local *local, + + might_sleep(); + +- if (!sdata) +- return -EIO; +- + sdata = get_bss_sdata(sdata); + if (!check_sdata_in_driver(sdata)) + return -EIO; +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index 6d2b42cb3ad58..d1460b870ed5a 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -1060,6 +1060,20 @@ static void __sta_info_destroy_part2(struct sta_info *sta) + * after _part1 and before _part2! + */ + ++ /* ++ * There's a potential race in _part1 where we set WLAN_STA_BLOCK_BA ++ * but someone might have just gotten past a check, and not yet into ++ * queuing the work/creating the data/etc. ++ * ++ * Do another round of destruction so that the worker is certainly ++ * canceled before we later free the station. ++ * ++ * Since this is after synchronize_rcu()/synchronize_net() we're now ++ * certain that nobody can actually hold a reference to the STA and ++ * be calling e.g. ieee80211_start_tx_ba_session(). ++ */ ++ ieee80211_sta_tear_down_BA_sessions(sta, AGG_STOP_DESTROY_STA); ++ + might_sleep(); + lockdep_assert_held(&local->sta_mtx); + +diff --git a/net/mptcp/diag.c b/net/mptcp/diag.c +index d7ca71c597545..23bd18084c8a2 100644 +--- a/net/mptcp/diag.c ++++ b/net/mptcp/diag.c +@@ -95,7 +95,7 @@ static size_t subflow_get_info_size(const struct sock *sk) + nla_total_size(4) + /* MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ */ + nla_total_size_64bit(8) + /* MPTCP_SUBFLOW_ATTR_MAP_SEQ */ + nla_total_size(4) + /* MPTCP_SUBFLOW_ATTR_MAP_SFSEQ */ +- nla_total_size(2) + /* MPTCP_SUBFLOW_ATTR_SSN_OFFSET */ ++ nla_total_size(4) + /* MPTCP_SUBFLOW_ATTR_SSN_OFFSET */ + nla_total_size(2) + /* MPTCP_SUBFLOW_ATTR_MAP_DATALEN */ + nla_total_size(4) + /* MPTCP_SUBFLOW_ATTR_FLAGS */ + nla_total_size(1) + /* MPTCP_SUBFLOW_ATTR_ID_REM */ +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 9273316cdbde1..148da412ee766 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -2213,7 +2213,7 @@ static struct sock *mptcp_subflow_get_retrans(struct mptcp_sock *msk) + continue; + } + +- if (subflow->backup) { ++ if (subflow->backup || subflow->request_bkup) { + if (!backup) + backup = ssk; + continue; +diff --git a/net/netfilter/nf_flow_table_inet.c b/net/netfilter/nf_flow_table_inet.c +index 6783ea220f8fe..7f746acb4b027 100644 +--- a/net/netfilter/nf_flow_table_inet.c ++++ b/net/netfilter/nf_flow_table_inet.c +@@ -17,6 +17,9 @@ nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb, + + switch (skb->protocol) { + case htons(ETH_P_8021Q): ++ if (!pskb_may_pull(skb, skb_mac_offset(skb) + sizeof(*veth))) ++ return NF_ACCEPT; ++ + veth = (struct vlan_ethhdr *)skb_mac_header(skb); + proto = veth->h_vlan_encapsulated_proto; + break; +diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c +index f3227f9316969..8fa16be0def2a 100644 +--- a/net/netfilter/nf_flow_table_ip.c ++++ b/net/netfilter/nf_flow_table_ip.c +@@ -254,6 +254,9 @@ static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto, + + switch (skb->protocol) { + case htons(ETH_P_8021Q): ++ if (!pskb_may_pull(skb, skb_mac_offset(skb) + sizeof(*veth))) ++ return false; ++ + veth = (struct vlan_ethhdr *)skb_mac_header(skb); + if (veth->h_vlan_encapsulated_proto == proto) { + *offset += VLAN_HLEN; +diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c +index 6ac1ebe17456d..d8cb304f809e5 100644 +--- a/net/netfilter/nf_flow_table_offload.c ++++ b/net/netfilter/nf_flow_table_offload.c +@@ -830,8 +830,8 @@ static int nf_flow_offload_tuple(struct nf_flowtable *flowtable, + struct list_head *block_cb_list) + { + struct flow_cls_offload cls_flow = {}; ++ struct netlink_ext_ack extack = {}; + struct flow_block_cb *block_cb; +- struct netlink_ext_ack extack; + __be16 proto = ETH_P_ALL; + int err, i = 0; + +diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c +index 89b16d36da9cf..d5f5b93a99a08 100644 +--- a/net/netfilter/nfnetlink_queue.c ++++ b/net/netfilter/nfnetlink_queue.c +@@ -640,10 +640,41 @@ static bool nf_ct_drop_unconfirmed(const struct nf_queue_entry *entry) + { + #if IS_ENABLED(CONFIG_NF_CONNTRACK) + static const unsigned long flags = IPS_CONFIRMED | IPS_DYING; +- const struct nf_conn *ct = (void *)skb_nfct(entry->skb); ++ struct nf_conn *ct = (void *)skb_nfct(entry->skb); ++ unsigned long status; ++ unsigned int use; + +- if (ct && ((ct->status & flags) == IPS_DYING)) ++ if (!ct) ++ return false; ++ ++ status = READ_ONCE(ct->status); ++ if ((status & flags) == IPS_DYING) + return true; ++ ++ if (status & IPS_CONFIRMED) ++ return false; ++ ++ /* in some cases skb_clone() can occur after initial conntrack ++ * pickup, but conntrack assumes exclusive skb->_nfct ownership for ++ * unconfirmed entries. ++ * ++ * This happens for br_netfilter and with ip multicast routing. ++ * We can't be solved with serialization here because one clone could ++ * have been queued for local delivery. ++ */ ++ use = refcount_read(&ct->ct_general.use); ++ if (likely(use == 1)) ++ return false; ++ ++ /* Can't decrement further? Exclusive ownership. */ ++ if (!refcount_dec_not_one(&ct->ct_general.use)) ++ return false; ++ ++ skb_set_nfct(entry->skb, 0); ++ /* No nf_ct_put(): we already decremented .use and it cannot ++ * drop down to 0. ++ */ ++ return true; + #endif + return false; + } +diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c +index 1b468a16b5237..30b24d002c3d8 100644 +--- a/net/netfilter/nft_counter.c ++++ b/net/netfilter/nft_counter.c +@@ -106,11 +106,16 @@ static void nft_counter_reset(struct nft_counter_percpu_priv *priv, + struct nft_counter *total) + { + struct nft_counter *this_cpu; ++ seqcount_t *myseq; + + local_bh_disable(); + this_cpu = this_cpu_ptr(priv->counter); ++ myseq = this_cpu_ptr(&nft_counter_seq); ++ ++ write_seqcount_begin(myseq); + this_cpu->packets -= total->packets; + this_cpu->bytes -= total->bytes; ++ write_seqcount_end(myseq); + local_bh_enable(); + } + +@@ -264,7 +269,7 @@ static void nft_counter_offload_stats(struct nft_expr *expr, + struct nft_counter *this_cpu; + seqcount_t *myseq; + +- preempt_disable(); ++ local_bh_disable(); + this_cpu = this_cpu_ptr(priv->counter); + myseq = this_cpu_ptr(&nft_counter_seq); + +@@ -272,7 +277,7 @@ static void nft_counter_offload_stats(struct nft_expr *expr, + this_cpu->packets += stats->pkts; + this_cpu->bytes += stats->bytes; + write_seqcount_end(myseq); +- preempt_enable(); ++ local_bh_enable(); + } + + static struct nft_expr_type nft_counter_type; +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 18a38db2b27eb..258d885548ae4 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -128,7 +128,7 @@ static const char *const nlk_cb_mutex_key_strings[MAX_LINKS + 1] = { + "nlk_cb_mutex-MAX_LINKS" + }; + +-static int netlink_dump(struct sock *sk); ++static int netlink_dump(struct sock *sk, bool lock_taken); + + /* nl_table locking explained: + * Lookup and traversal are protected with an RCU read-side lock. Insertion +@@ -2000,7 +2000,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + + if (READ_ONCE(nlk->cb_running) && + atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { +- ret = netlink_dump(sk); ++ ret = netlink_dump(sk, false); + if (ret) { + WRITE_ONCE(sk->sk_err, -ret); + sk_error_report(sk); +@@ -2210,7 +2210,7 @@ static int netlink_dump_done(struct netlink_sock *nlk, struct sk_buff *skb, + return 0; + } + +-static int netlink_dump(struct sock *sk) ++static int netlink_dump(struct sock *sk, bool lock_taken) + { + struct netlink_sock *nlk = nlk_sk(sk); + struct netlink_ext_ack extack = {}; +@@ -2222,7 +2222,8 @@ static int netlink_dump(struct sock *sk) + int alloc_min_size; + int alloc_size; + +- mutex_lock(nlk->cb_mutex); ++ if (!lock_taken) ++ mutex_lock(nlk->cb_mutex); + if (!nlk->cb_running) { + err = -EINVAL; + goto errout_skb; +@@ -2378,9 +2379,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, + WRITE_ONCE(nlk->cb_running, true); + nlk->dump_done_errno = INT_MAX; + +- mutex_unlock(nlk->cb_mutex); +- +- ret = netlink_dump(sk); ++ ret = netlink_dump(sk, true); + + sock_put(sk); + +diff --git a/net/rds/recv.c b/net/rds/recv.c +index 5b426dc3634d1..a316180d3c32e 100644 +--- a/net/rds/recv.c ++++ b/net/rds/recv.c +@@ -424,6 +424,7 @@ static int rds_still_queued(struct rds_sock *rs, struct rds_incoming *inc, + struct sock *sk = rds_rs_to_sk(rs); + int ret = 0; + unsigned long flags; ++ struct rds_incoming *to_drop = NULL; + + write_lock_irqsave(&rs->rs_recv_lock, flags); + if (!list_empty(&inc->i_item)) { +@@ -434,11 +435,14 @@ static int rds_still_queued(struct rds_sock *rs, struct rds_incoming *inc, + -be32_to_cpu(inc->i_hdr.h_len), + inc->i_hdr.h_dport); + list_del_init(&inc->i_item); +- rds_inc_put(inc); ++ to_drop = inc; + } + } + write_unlock_irqrestore(&rs->rs_recv_lock, flags); + ++ if (to_drop) ++ rds_inc_put(to_drop); ++ + rdsdebug("inc %p rs %p still %d dropped %d\n", inc, rs, ret, drop); + return ret; + } +@@ -757,16 +761,21 @@ void rds_clear_recv_queue(struct rds_sock *rs) + struct sock *sk = rds_rs_to_sk(rs); + struct rds_incoming *inc, *tmp; + unsigned long flags; ++ LIST_HEAD(to_drop); + + write_lock_irqsave(&rs->rs_recv_lock, flags); + list_for_each_entry_safe(inc, tmp, &rs->rs_recv_queue, i_item) { + rds_recv_rcvbuf_delta(rs, sk, inc->i_conn->c_lcong, + -be32_to_cpu(inc->i_hdr.h_len), + inc->i_hdr.h_dport); ++ list_move(&inc->i_item, &to_drop); ++ } ++ write_unlock_irqrestore(&rs->rs_recv_lock, flags); ++ ++ list_for_each_entry_safe(inc, tmp, &to_drop, i_item) { + list_del_init(&inc->i_item); + rds_inc_put(inc); + } +- write_unlock_irqrestore(&rs->rs_recv_lock, flags); + } + + /* +diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c +index 08aaa6efc62c8..e0e16b0fdb179 100644 +--- a/net/sched/sch_netem.c ++++ b/net/sched/sch_netem.c +@@ -437,12 +437,10 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct netem_sched_data *q = qdisc_priv(sch); + /* We don't fill cb now as skb_unshare() may invalidate it */ + struct netem_skb_cb *cb; +- struct sk_buff *skb2; ++ struct sk_buff *skb2 = NULL; + struct sk_buff *segs = NULL; + unsigned int prev_len = qdisc_pkt_len(skb); + int count = 1; +- int rc = NET_XMIT_SUCCESS; +- int rc_drop = NET_XMIT_DROP; + + /* Do not fool qdisc_drop_all() */ + skb->prev = NULL; +@@ -471,19 +469,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, + skb_orphan_partial(skb); + + /* +- * If we need to duplicate packet, then re-insert at top of the +- * qdisc tree, since parent queuer expects that only one +- * skb will be queued. ++ * If we need to duplicate packet, then clone it before ++ * original is modified. + */ +- if (count > 1 && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) { +- struct Qdisc *rootq = qdisc_root_bh(sch); +- u32 dupsave = q->duplicate; /* prevent duplicating a dup... */ +- +- q->duplicate = 0; +- rootq->enqueue(skb2, rootq, to_free); +- q->duplicate = dupsave; +- rc_drop = NET_XMIT_SUCCESS; +- } ++ if (count > 1) ++ skb2 = skb_clone(skb, GFP_ATOMIC); + + /* + * Randomized packet corruption. +@@ -495,7 +485,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (skb_is_gso(skb)) { + skb = netem_segment(skb, sch, to_free); + if (!skb) +- return rc_drop; ++ goto finish_segs; ++ + segs = skb->next; + skb_mark_not_on_list(skb); + qdisc_skb_cb(skb)->pkt_len = skb->len; +@@ -521,7 +512,24 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, + /* re-link segs, so that qdisc_drop_all() frees them all */ + skb->next = segs; + qdisc_drop_all(skb, sch, to_free); +- return rc_drop; ++ if (skb2) ++ __qdisc_drop(skb2, to_free); ++ return NET_XMIT_DROP; ++ } ++ ++ /* ++ * If doing duplication then re-insert at top of the ++ * qdisc tree, since parent queuer expects that only one ++ * skb will be queued. ++ */ ++ if (skb2) { ++ struct Qdisc *rootq = qdisc_root_bh(sch); ++ u32 dupsave = q->duplicate; /* prevent duplicating a dup... */ ++ ++ q->duplicate = 0; ++ rootq->enqueue(skb2, rootq, to_free); ++ q->duplicate = dupsave; ++ skb2 = NULL; + } + + qdisc_qstats_backlog_inc(sch, skb); +@@ -592,9 +600,12 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, + } + + finish_segs: ++ if (skb2) ++ __qdisc_drop(skb2, to_free); ++ + if (segs) { + unsigned int len, last_len; +- int nb; ++ int rc, nb; + + len = skb ? skb->len : 0; + nb = skb ? 1 : 0; +diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c +index c964b48eaabae..a004c3ef35c0f 100644 +--- a/net/sunrpc/stats.c ++++ b/net/sunrpc/stats.c +@@ -309,7 +309,7 @@ EXPORT_SYMBOL_GPL(rpc_proc_unregister); + struct proc_dir_entry * + svc_proc_register(struct net *net, struct svc_stat *statp, const struct proc_ops *proc_ops) + { +- return do_register(net, statp->program->pg_name, statp, proc_ops); ++ return do_register(net, statp->program->pg_name, net, proc_ops); + } + EXPORT_SYMBOL_GPL(svc_proc_register); + +diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c +index 8d5897ed2816f..92d88aac2adff 100644 +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -447,8 +447,8 @@ __svc_init_bc(struct svc_serv *serv) + * Create an RPC service + */ + static struct svc_serv * +-__svc_create(struct svc_program *prog, unsigned int bufsize, int npools, +- int (*threadfn)(void *data)) ++__svc_create(struct svc_program *prog, struct svc_stat *stats, ++ unsigned int bufsize, int npools, int (*threadfn)(void *data)) + { + struct svc_serv *serv; + unsigned int vers; +@@ -460,7 +460,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, + serv->sv_name = prog->pg_name; + serv->sv_program = prog; + kref_init(&serv->sv_refcnt); +- serv->sv_stats = prog->pg_stats; ++ serv->sv_stats = stats; + if (bufsize > RPCSVC_MAXPAYLOAD) + bufsize = RPCSVC_MAXPAYLOAD; + serv->sv_max_payload = bufsize? bufsize : 4096; +@@ -522,26 +522,28 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, + struct svc_serv *svc_create(struct svc_program *prog, unsigned int bufsize, + int (*threadfn)(void *data)) + { +- return __svc_create(prog, bufsize, 1, threadfn); ++ return __svc_create(prog, NULL, bufsize, 1, threadfn); + } + EXPORT_SYMBOL_GPL(svc_create); + + /** + * svc_create_pooled - Create an RPC service with pooled threads + * @prog: the RPC program the new service will handle ++ * @stats: the stats struct if desired + * @bufsize: maximum message size for @prog + * @threadfn: a function to service RPC requests for @prog + * + * Returns an instantiated struct svc_serv object or NULL. + */ + struct svc_serv *svc_create_pooled(struct svc_program *prog, ++ struct svc_stat *stats, + unsigned int bufsize, + int (*threadfn)(void *data)) + { + struct svc_serv *serv; + unsigned int npools = svc_pool_map_get(); + +- serv = __svc_create(prog, bufsize, npools, threadfn); ++ serv = __svc_create(prog, stats, bufsize, npools, threadfn); + if (!serv) + goto out_err; + return serv; +@@ -1357,7 +1359,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + goto err_bad_proc; + + /* Syntactic check complete */ +- serv->sv_stats->rpccnt++; ++ if (serv->sv_stats) ++ serv->sv_stats->rpccnt++; + trace_svc_process(rqstp, progp->pg_name); + + /* Build the reply header. */ +@@ -1423,7 +1426,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + goto close_xprt; + + err_bad_rpc: +- serv->sv_stats->rpcbadfmt++; ++ if (serv->sv_stats) ++ serv->sv_stats->rpcbadfmt++; + svc_putnl(resv, 1); /* REJECT */ + svc_putnl(resv, 0); /* RPC_MISMATCH */ + svc_putnl(resv, 2); /* Only RPCv2 supported */ +@@ -1436,7 +1440,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + err_bad_auth: + dprintk("svc: authentication failed (%d)\n", + be32_to_cpu(rqstp->rq_auth_stat)); +- serv->sv_stats->rpcbadauth++; ++ if (serv->sv_stats) ++ serv->sv_stats->rpcbadauth++; + /* Restore write pointer to location of accept status: */ + xdr_ressize_check(rqstp, reply_statp); + svc_putnl(resv, 1); /* REJECT */ +@@ -1446,7 +1451,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + + err_bad_prog: + dprintk("svc: unknown program %d\n", prog); +- serv->sv_stats->rpcbadfmt++; ++ if (serv->sv_stats) ++ serv->sv_stats->rpcbadfmt++; + svc_putnl(resv, RPC_PROG_UNAVAIL); + goto sendit; + +@@ -1454,7 +1460,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + svc_printk(rqstp, "unknown version (%d for prog %d, %s)\n", + rqstp->rq_vers, rqstp->rq_prog, progp->pg_name); + +- serv->sv_stats->rpcbadfmt++; ++ if (serv->sv_stats) ++ serv->sv_stats->rpcbadfmt++; + svc_putnl(resv, RPC_PROG_MISMATCH); + svc_putnl(resv, process.mismatch.lovers); + svc_putnl(resv, process.mismatch.hivers); +@@ -1463,7 +1470,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + err_bad_proc: + svc_printk(rqstp, "unknown procedure (%d)\n", rqstp->rq_proc); + +- serv->sv_stats->rpcbadfmt++; ++ if (serv->sv_stats) ++ serv->sv_stats->rpcbadfmt++; + svc_putnl(resv, RPC_PROC_UNAVAIL); + goto sendit; + +@@ -1472,7 +1480,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + + rpc_stat = rpc_garbage_args; + err_bad: +- serv->sv_stats->rpcbadfmt++; ++ if (serv->sv_stats) ++ serv->sv_stats->rpcbadfmt++; + svc_putnl(resv, ntohl(rpc_stat)); + goto sendit; + } +@@ -1513,7 +1522,8 @@ svc_process(struct svc_rqst *rqstp) + if (dir != 0) { + /* direction != CALL */ + svc_printk(rqstp, "bad direction %d, dropping request\n", dir); +- serv->sv_stats->rpcbadfmt++; ++ if (serv->sv_stats) ++ serv->sv_stats->rpcbadfmt++; + goto out_drop; + } + +diff --git a/net/wireless/core.h b/net/wireless/core.h +index 1720abf36f92a..be186b5a15f3d 100644 +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -217,6 +217,7 @@ void cfg80211_register_wdev(struct cfg80211_registered_device *rdev, + static inline void wdev_lock(struct wireless_dev *wdev) + __acquires(wdev) + { ++ lockdep_assert_held(&wdev->wiphy->mtx); + mutex_lock(&wdev->mtx); + __acquire(wdev->mtx); + } +@@ -224,11 +225,16 @@ static inline void wdev_lock(struct wireless_dev *wdev) + static inline void wdev_unlock(struct wireless_dev *wdev) + __releases(wdev) + { ++ lockdep_assert_held(&wdev->wiphy->mtx); + __release(wdev->mtx); + mutex_unlock(&wdev->mtx); + } + +-#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) ++static inline void ASSERT_WDEV_LOCK(struct wireless_dev *wdev) ++{ ++ lockdep_assert_held(&wdev->wiphy->mtx); ++ lockdep_assert_held(&wdev->mtx); ++} + + static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev) + { +diff --git a/security/apparmor/policy_unpack_test.c b/security/apparmor/policy_unpack_test.c +index 533137f45361c..4951d9bef5794 100644 +--- a/security/apparmor/policy_unpack_test.c ++++ b/security/apparmor/policy_unpack_test.c +@@ -78,14 +78,14 @@ struct aa_ext *build_aa_ext_struct(struct policy_unpack_fixture *puf, + *(buf + 1) = strlen(TEST_U32_NAME) + 1; + strcpy(buf + 3, TEST_U32_NAME); + *(buf + 3 + strlen(TEST_U32_NAME) + 1) = AA_U32; +- *((u32 *)(buf + 3 + strlen(TEST_U32_NAME) + 2)) = TEST_U32_DATA; ++ *((__le32 *)(buf + 3 + strlen(TEST_U32_NAME) + 2)) = cpu_to_le32(TEST_U32_DATA); + + buf = e->start + TEST_NAMED_U64_BUF_OFFSET; + *buf = AA_NAME; + *(buf + 1) = strlen(TEST_U64_NAME) + 1; + strcpy(buf + 3, TEST_U64_NAME); + *(buf + 3 + strlen(TEST_U64_NAME) + 1) = AA_U64; +- *((u64 *)(buf + 3 + strlen(TEST_U64_NAME) + 2)) = TEST_U64_DATA; ++ *((__le64 *)(buf + 3 + strlen(TEST_U64_NAME) + 2)) = cpu_to_le64(TEST_U64_DATA); + + buf = e->start + TEST_NAMED_BLOB_BUF_OFFSET; + *buf = AA_NAME; +@@ -101,7 +101,7 @@ struct aa_ext *build_aa_ext_struct(struct policy_unpack_fixture *puf, + *(buf + 1) = strlen(TEST_ARRAY_NAME) + 1; + strcpy(buf + 3, TEST_ARRAY_NAME); + *(buf + 3 + strlen(TEST_ARRAY_NAME) + 1) = AA_ARRAY; +- *((u16 *)(buf + 3 + strlen(TEST_ARRAY_NAME) + 2)) = TEST_ARRAY_SIZE; ++ *((__le16 *)(buf + 3 + strlen(TEST_ARRAY_NAME) + 2)) = cpu_to_le16(TEST_ARRAY_SIZE); + + return e; + } +diff --git a/security/selinux/avc.c b/security/selinux/avc.c +index 97f4c944a20ff..5e0ed154669b7 100644 +--- a/security/selinux/avc.c ++++ b/security/selinux/avc.c +@@ -332,12 +332,12 @@ static int avc_add_xperms_decision(struct avc_node *node, + { + struct avc_xperms_decision_node *dest_xpd; + +- node->ae.xp_node->xp.len++; + dest_xpd = avc_xperms_decision_alloc(src->used); + if (!dest_xpd) + return -ENOMEM; + avc_copy_xperms_decision(&dest_xpd->xpd, src); + list_add(&dest_xpd->xpd_list, &node->ae.xp_node->xpd_head); ++ node->ae.xp_node->xp.len++; + return 0; + } + +diff --git a/sound/core/timer.c b/sound/core/timer.c +index 38f3b30efae70..ecad57a1bc5b8 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -556,7 +556,7 @@ static int snd_timer_start1(struct snd_timer_instance *timeri, + /* check the actual time for the start tick; + * bail out as error if it's way too low (< 100us) + */ +- if (start) { ++ if (start && !(timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) { + if ((u64)snd_timer_hw_resolution(timer) * ticks < 100000) { + result = -EINVAL; + goto unlock; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 8729896c7f9cd..05fb686ae2508 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -577,7 +577,6 @@ static void alc_shutup_pins(struct hda_codec *codec) + switch (codec->core.vendor_id) { + case 0x10ec0236: + case 0x10ec0256: +- case 0x10ec0257: + case 0x19e58326: + case 0x10ec0283: + case 0x10ec0285: +diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h +index b03d671f218d6..7a15cc260f741 100644 +--- a/sound/usb/quirks-table.h ++++ b/sound/usb/quirks-table.h +@@ -273,6 +273,7 @@ YAMAHA_DEVICE(0x105a, NULL), + YAMAHA_DEVICE(0x105b, NULL), + YAMAHA_DEVICE(0x105c, NULL), + YAMAHA_DEVICE(0x105d, NULL), ++YAMAHA_DEVICE(0x1718, "P-125"), + { + USB_DEVICE(0x0499, 0x1503), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index cf1ba2837d10f..cae8eb5d611b4 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1900,6 +1900,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_GENERIC_IMPLICIT_FB), + DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */ + QUIRK_FLAG_GENERIC_IMPLICIT_FB), ++ DEVICE_FLG(0x2d95, 0x8021, /* VIVO USB-C-XE710 HEADSET */ ++ QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ +diff --git a/tools/include/linux/align.h b/tools/include/linux/align.h +new file mode 100644 +index 0000000000000..14e34ace80dda +--- /dev/null ++++ b/tools/include/linux/align.h +@@ -0,0 +1,12 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#ifndef _TOOLS_LINUX_ALIGN_H ++#define _TOOLS_LINUX_ALIGN_H ++ ++#include <uapi/linux/const.h> ++ ++#define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) ++#define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a) - 1), (a)) ++#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) ++ ++#endif /* _TOOLS_LINUX_ALIGN_H */ +diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h +index 95611df1d26e5..a83ffdf1e2117 100644 +--- a/tools/include/linux/bitmap.h ++++ b/tools/include/linux/bitmap.h +@@ -3,6 +3,7 @@ + #define _PERF_BITOPS_H + + #include <string.h> ++#include <linux/align.h> + #include <linux/bitops.h> + #include <stdlib.h> + #include <linux/kernel.h> +@@ -24,13 +25,14 @@ int __bitmap_intersects(const unsigned long *bitmap1, + #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) + #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) + ++#define bitmap_size(nbits) (ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE) ++ + static inline void bitmap_zero(unsigned long *dst, unsigned int nbits) + { + if (small_const_nbits(nbits)) + *dst = 0UL; + else { +- int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); +- memset(dst, 0, len); ++ memset(dst, 0, bitmap_size(nbits)); + } + } + +@@ -116,7 +118,7 @@ static inline int test_and_clear_bit(int nr, unsigned long *addr) + */ + static inline unsigned long *bitmap_zalloc(int nbits) + { +- return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long)); ++ return calloc(1, bitmap_size(nbits)); + } + + /* +@@ -159,7 +161,6 @@ static inline int bitmap_and(unsigned long *dst, const unsigned long *src1, + #define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long)) + #endif + #define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1) +-#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) + + static inline int bitmap_equal(const unsigned long *src1, + const unsigned long *src2, unsigned int nbits) +diff --git a/tools/testing/selftests/core/close_range_test.c b/tools/testing/selftests/core/close_range_test.c +index aa7d13d91963f..03db3d9cd94b8 100644 +--- a/tools/testing/selftests/core/close_range_test.c ++++ b/tools/testing/selftests/core/close_range_test.c +@@ -567,4 +567,39 @@ TEST(close_range_cloexec_unshare_syzbot) + EXPECT_EQ(close(fd3), 0); + } + ++TEST(close_range_bitmap_corruption) ++{ ++ pid_t pid; ++ int status; ++ struct __clone_args args = { ++ .flags = CLONE_FILES, ++ .exit_signal = SIGCHLD, ++ }; ++ ++ /* get the first 128 descriptors open */ ++ for (int i = 2; i < 128; i++) ++ EXPECT_GE(dup2(0, i), 0); ++ ++ /* get descriptor table shared */ ++ pid = sys_clone3(&args, sizeof(args)); ++ ASSERT_GE(pid, 0); ++ ++ if (pid == 0) { ++ /* unshare and truncate descriptor table down to 64 */ ++ if (sys_close_range(64, ~0U, CLOSE_RANGE_UNSHARE)) ++ exit(EXIT_FAILURE); ++ ++ ASSERT_EQ(fcntl(64, F_GETFD), -1); ++ /* ... and verify that the range 64..127 is not ++ stuck "fully used" according to secondary bitmap */ ++ EXPECT_EQ(dup(0), 64) ++ exit(EXIT_FAILURE); ++ exit(EXIT_SUCCESS); ++ } ++ ++ EXPECT_EQ(waitpid(pid, &status, 0), pid); ++ EXPECT_EQ(true, WIFEXITED(status)); ++ EXPECT_EQ(0, WEXITSTATUS(status)); ++} ++ + TEST_HARNESS_MAIN +diff --git a/tools/testing/selftests/tc-testing/tdc.py b/tools/testing/selftests/tc-testing/tdc.py +index a3e43189d9400..d6a9d97f73c24 100755 +--- a/tools/testing/selftests/tc-testing/tdc.py ++++ b/tools/testing/selftests/tc-testing/tdc.py +@@ -129,7 +129,6 @@ class PluginMgr: + except Exception as ee: + print('exception {} in call to pre_case for {} plugin'. + format(ee, pgn_inst.__class__)) +- print('test_ordinal is {}'.format(test_ordinal)) + print('testid is {}'.format(caseinfo['id'])) + raise + |