[openwrt/openwrt] lantiq: Fix an sleeping function called from invalid context

LEDE Commits lede-commits at lists.infradead.org
Mon Oct 9 15:23:09 PDT 2023


hauke pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/66f6c20e45aa0eb2649d1e0552eab9e138e38601

commit 66f6c20e45aa0eb2649d1e0552eab9e138e38601
Author: Hauke Mehrtens <hauke at hauke-m.de>
AuthorDate: Mon Oct 9 02:06:55 2023 +0200

    lantiq: Fix an sleeping function called from invalid context
    
    The ifx_pcie_bus_enum_hack() function is called in
    ifx_pcie_read_config() while holding the ifx_pcie_lock spinlock. The
    ifx_pcie_bus_enum_hack() function calls pci_get_slot() which could
    sleep. Add a new function for pci_get_slot() which does not use a
    semaphore, the mutex should be sufficient. This fixes the sleep in
    atomic context which could cause a hang of the system.
    
    This fixes the following warning seen with
    CONFIG_KERNEL_DEBUG_ATOMIC_SLEEP=y.
    
    [   12.264300] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
    [   12.272226] BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1487
    [   12.280684] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 9, name: kworker/u4:0
    [   12.288781] CPU: 0 PID: 9 Comm: kworker/u4:0 Not tainted 5.15.134 #0
    [   12.295135] Workqueue: events_unbound deferred_probe_work_func
    [   12.300964] Stack : 80e70000 8008ac80 00000000 00000004 807c776c 8145b9ec 81424c00 800520ec
    [   12.309316]         808a0000 8145ba2b 8145b844 8145b838 80414178 00000001 8145b9f8 81439ea0
    [   12.317674]         00000000 00000000 807c776c 8145b838 ffffefff 00000000 00000000 ffffffea
    [   12.326030]         00000081 8145b844 00000081 808a6f50 807c776c 00000000 00000000 80910000
    [   12.334391]         00111bef 00000000 00000001 00000000 00000018 00000030 00000000 80e40000
    [   12.342741]         ...
    [   12.345177] Call Trace:
    [   12.347613] [<8000c1d0>] show_stack+0x28/0xf0
    [   12.351974] [<8038ba1c>] dump_stack_lvl+0x60/0x80
    [   12.356667] [<8005eefc>] ___might_sleep+0x124/0x138
    [   12.361547] [<806daf30>] down_read+0x24/0x88
    [   12.365807] [<803cdd20>] pci_get_slot+0x2c/0xc0
    [   12.370333] [<806d56ac>] ifx_pcie_read_config+0x164/0x330
    [   12.375735] [<803be610>] pci_bus_read_config_dword+0x6c/0xd0
    [   12.381399] [<803c20cc>] pci_bus_generic_read_dev_vendor_id+0x3c/0x1a8
    [   12.387915] [<803c27ec>] pci_scan_single_device+0x88/0x154
    [   12.393404] [<803c2928>] pci_scan_slot+0x70/0x134
    [   12.398099] [<803c3bf0>] pci_scan_child_bus_extend+0x5c/0x320
    [   12.403849] [<803c4178>] pci_scan_root_bus_bridge+0xd0/0xec
    [   12.409414] [<806d45a8>] pcibios_scanbus+0xe4/0x21c
    [   12.414293] [<806d4908>] register_pci_controller+0xb8/0x11c
    [   12.419858] [<806d5f9c>] ifx_pcie_bios_probe+0x724/0x940
    [   12.425174] [<80417574>] platform_probe+0x38/0x90
    [   12.429868] [<80414d68>] really_probe.part.0+0xac/0x354
    [   12.435103] [<80415298>] driver_probe_device+0x4c/0x154
    [   12.440313] [<80415904>] __device_attach_driver+0xd0/0x15c
    [   12.445802] [<804129d8>] bus_for_each_drv+0x70/0xb0
    [   12.450676] [<80415610>] __device_attach+0xdc/0x194
    [   12.455545] [<80413ca8>] bus_probe_device+0x9c/0xb8
    [   12.460419] [<8041420c>] deferred_probe_work_func+0x94/0xd4
    [   12.465995] [<8004fcb4>] process_one_work+0x27c/0x4c8
    [   12.471044] [<80050710>] worker_thread+0x34c/0x5f8
    [   12.475825] [<800587a8>] kthread+0x168/0x18c
    [   12.480090] [<80006ef8>] ret_from_kernel_thread+0x14/0x1c
    
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../0001-MIPS-lantiq-add-pcie-driver.patch         | 57 +++++++++++++++++++---
 1 file changed, 51 insertions(+), 6 deletions(-)

diff --git a/target/linux/lantiq/patches-5.15/0001-MIPS-lantiq-add-pcie-driver.patch b/target/linux/lantiq/patches-5.15/0001-MIPS-lantiq-add-pcie-driver.patch
index 9cd3b08b8e..b0995cbccf 100644
--- a/target/linux/lantiq/patches-5.15/0001-MIPS-lantiq-add-pcie-driver.patch
+++ b/target/linux/lantiq/patches-5.15/0001-MIPS-lantiq-add-pcie-driver.patch
@@ -1470,7 +1470,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +
 --- /dev/null
 +++ b/arch/mips/pci/ifxmips_pcie_ar10.h
-@@ -0,0 +1,290 @@
+@@ -0,0 +1,305 @@
 +/****************************************************************************
 +                              Copyright (c) 2010
 +                            Lantiq Deutschland GmbH
@@ -1722,6 +1722,21 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +    return tbus_number;
 +}
 +
++static struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
++{
++	struct pci_dev *dev;
++
++	list_for_each_entry(dev, &bus->devices, bus_list) {
++		if (dev->devfn == devfn)
++			goto out;
++	}
++
++	dev = NULL;
++ out:
++	pci_dev_get(dev);
++	return dev;
++}
++
 +static inline u32
 +ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
 +{
@@ -1729,7 +1744,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +    u32 tvalue = value;
 +
 +    /* Sanity check */
-+    pdev = pci_get_slot(bus, devfn);
++    pdev = ifx_pci_get_slot(bus, devfn);
 +    if (pdev == NULL) {
 +        return tvalue;
 +    }
@@ -3860,7 +3875,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +
 --- /dev/null
 +++ b/arch/mips/pci/ifxmips_pcie_vr9.h
-@@ -0,0 +1,269 @@
+@@ -0,0 +1,284 @@
 +/****************************************************************************
 +                              Copyright (c) 2010
 +                            Lantiq Deutschland GmbH
@@ -4094,6 +4109,21 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +    return tbus_number;
 +}
 +
++static inline struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
++{
++	struct pci_dev *dev;
++
++	list_for_each_entry(dev, &bus->devices, bus_list) {
++		if (dev->devfn == devfn)
++			goto out;
++	}
++
++	dev = NULL;
++ out:
++	pci_dev_get(dev);
++	return dev;
++}
++
 +static inline u32
 +ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
 +{
@@ -4101,7 +4131,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +    u32 tvalue = value;
 +
 +    /* Sanity check */
-+    pdev = pci_get_slot(bus, devfn);
++    pdev = ifx_pci_get_slot(bus, devfn);
 +    if (pdev == NULL) {
 +        return tvalue;
 +    }
@@ -4165,7 +4195,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +EXPORT_SYMBOL(pcibios_1st_host_bus_nr);
 --- /dev/null
 +++ b/arch/mips/pci/pcie-lantiq.h
-@@ -0,0 +1,1301 @@
+@@ -0,0 +1,1316 @@
 +/******************************************************************************
 +**
 +** FILE NAME    : ifxmips_pcie_reg.h
@@ -5431,6 +5461,21 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +    return tbus_number;
 +}
 +
++static struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
++{
++	struct pci_dev *dev;
++
++	list_for_each_entry(dev, &bus->devices, bus_list) {
++		if (dev->devfn == devfn)
++			goto out;
++	}
++
++	dev = NULL;
++ out:
++	pci_dev_get(dev);
++	return dev;
++}
++
 +static inline u32
 +ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
 +{
@@ -5438,7 +5483,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +    u32 tvalue = value;
 +
 +    /* Sanity check */
-+    pdev = pci_get_slot(bus, devfn);
++    pdev = ifx_pci_get_slot(bus, devfn);
 +    if (pdev == NULL) {
 +        return tvalue;
 +    }




More information about the lede-commits mailing list