[RFC PATCH v12 3/5] mwifiex: Disable wakeup irq handling for pcie
We are going to handle the wakeup irq in the pci core. Signed-off-by: Jeffy Chen --- Changes in v13: None Changes in v12: None Changes in v11: None Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v3: None Changes in v2: None drivers/net/wireless/marvell/mwifiex/main.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index a96bd7e653bf..3cc3403b977a 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -1567,6 +1567,10 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter) goto err_exit; adapter->dt_node = dev->of_node; + + if (adapter->iface_type != MWIFIEX_PCIE) + goto err_exit; + adapter->irq_wakeup = irq_of_parse_and_map(adapter->dt_node, 0); if (!adapter->irq_wakeup) { dev_dbg(dev, "fail to parse irq_wakeup from device tree\n"); -- 2.11.0
[RFC PATCH v12 0/5] PCI: rockchip: Move PCIe WAKE# handling into pci core
Currently we are handling wake irq in mrvl wifi driver. Move it into pci core. Tested on my chromebook bob(with cros 4.4 kernel and mrvl wifi). Changes in v13: Fix compiler error reported by kbuild test robot Changes in v12: Only add irq definitions for PCI devices and rewrite the commit message. Enable the wake irq in noirq stage to avoid possible irq storm. Changes in v11: Address Brian's comments. Only support 1-per-device PCIe WAKE# pin as suggested. Move to pcie port as Brian suggested. Changes in v10: Use device_set_wakeup_capable() instead of device_set_wakeup_enable(), since dedicated wakeirq will be lost in device_set_wakeup_enable(false). Changes in v9: Add section for PCI devices and rewrite the commit message. Fix check error in .cleanup(). Move dedicated wakeirq setup to setup() callback and use device_set_wakeup_enable() to enable/disable. Rewrite the commit message. Changes in v8: Add optional "pci", and rewrite commit message. Add pci-of.c and use platform_pm_ops to handle the PCIe WAKE# signal. Rewrite the commit message. Changes in v7: Move PCIE_WAKE handling into pci core. Changes in v6: Fix device_init_wake error handling, and add some comments. Changes in v5: Move to pci.txt Rebase. Use "wakeup" instead of "wake" Changes in v3: Fix error handling. Changes in v2: Use dev_pm_set_dedicated_wake_irq. Jeffy Chen (5): dt-bindings: PCI: Add definition of PCIe WAKE# irq and PCI irq of/irq: Adjust of_pci_irq parsing for multiple interrupts mwifiex: Disable wakeup irq handling for pcie PCI / PM: Add support for the PCIe WAKE# signal for OF arm64: dts: rockchip: Move PCIe WAKE# irq to pcie port for Gru Documentation/devicetree/bindings/pci/pci.txt | 10 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 11 ++-- drivers/net/wireless/marvell/mwifiex/main.c | 4 ++ drivers/of/of_pci_irq.c | 71 +++-- drivers/pci/Makefile | 1 + drivers/pci/pci-driver.c | 10 drivers/pci/pci-of.c | 75 +++ include/linux/of_pci.h| 9 8 files changed, 183 insertions(+), 8 deletions(-) create mode 100644 drivers/pci/pci-of.c -- 2.11.0
[RFC PATCH v12 3/5] mwifiex: Disable wakeup irq handling for pcie
We are going to handle the wakeup irq in the pci core. Signed-off-by: Jeffy Chen --- Changes in v12: None Changes in v11: None Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v3: None Changes in v2: None drivers/net/wireless/marvell/mwifiex/main.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index a96bd7e653bf..3cc3403b977a 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -1567,6 +1567,10 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter) goto err_exit; adapter->dt_node = dev->of_node; + + if (adapter->iface_type != MWIFIEX_PCIE) + goto err_exit; + adapter->irq_wakeup = irq_of_parse_and_map(adapter->dt_node, 0); if (!adapter->irq_wakeup) { dev_dbg(dev, "fail to parse irq_wakeup from device tree\n"); -- 2.11.0
[RFC PATCH v12 0/5] PCI: rockchip: Move PCIe WAKE# handling into pci core
Currently we are handling wake irq in mrvl wifi driver. Move it into pci core. Tested on my chromebook bob(with cros 4.4 kernel and mrvl wifi). Changes in v12: Enable the wake irq in noirq stage to avoid possible irq storm. Changes in v11: Only add irq definitions for PCI devices and rewrite the commit message. Address Brian's comments. Only support 1-per-device PCIe WAKE# pin as suggested. Move to pcie port as Brian suggested. Changes in v10: Use device_set_wakeup_capable() instead of device_set_wakeup_enable(), since dedicated wakeirq will be lost in device_set_wakeup_enable(false). Changes in v9: Add section for PCI devices and rewrite the commit message. Fix check error in .cleanup(). Move dedicated wakeirq setup to setup() callback and use device_set_wakeup_enable() to enable/disable. Rewrite the commit message. Changes in v8: Add optional "pci", and rewrite commit message. Add pci-of.c and use platform_pm_ops to handle the PCIe WAKE# signal. Rewrite the commit message. Changes in v7: Move PCIE_WAKE handling into pci core. Changes in v6: Fix device_init_wake error handling, and add some comments. Changes in v5: Move to pci.txt Rebase. Use "wakeup" instead of "wake" Changes in v3: Fix error handling. Changes in v2: Use dev_pm_set_dedicated_wake_irq. Jeffy Chen (5): dt-bindings: PCI: Add definition of PCIe WAKE# irq and PCI irq of/irq: Adjust of_pci_irq parsing for multiple interrupts mwifiex: Disable wakeup irq handling for pcie PCI / PM: Add support for the PCIe WAKE# signal for OF arm64: dts: rockchip: Move PCIe WAKE# irq to pcie port for Gru Documentation/devicetree/bindings/pci/pci.txt | 10 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 11 ++-- drivers/net/wireless/marvell/mwifiex/main.c | 4 ++ drivers/of/of_pci_irq.c | 74 -- drivers/pci/Makefile | 1 + drivers/pci/pci-driver.c | 10 drivers/pci/pci-of.c | 75 +++ include/linux/of_pci.h| 9 8 files changed, 186 insertions(+), 8 deletions(-) create mode 100644 drivers/pci/pci-of.c -- 2.11.0
[RFC PATCH v11 3/5] mwifiex: Disable wakeup irq handling for pcie
We are going to handle the wakeup irq in the pci core. Signed-off-by: Jeffy Chen --- Changes in v11: None Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v3: None Changes in v2: None drivers/net/wireless/marvell/mwifiex/main.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index a96bd7e653bf..3cc3403b977a 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -1567,6 +1567,10 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter) goto err_exit; adapter->dt_node = dev->of_node; + + if (adapter->iface_type != MWIFIEX_PCIE) + goto err_exit; + adapter->irq_wakeup = irq_of_parse_and_map(adapter->dt_node, 0); if (!adapter->irq_wakeup) { dev_dbg(dev, "fail to parse irq_wakeup from device tree\n"); -- 2.11.0
[RFC PATCH v11 0/5] PCI: rockchip: Move PCIe WAKE# handling into pci core
Currently we are handling wake irq in mrvl wifi driver. Move it into pci core. Tested on my chromebook bob(with cros 4.4 kernel and mrvl wifi). Changes in v11: Only add irq definitions for PCI devices and rewrite the commit message. Address Brian's comments. Only support 1-per-device PCIe WAKE# pin as suggested. Move to pcie port as Brian suggested. Changes in v10: Use device_set_wakeup_capable() instead of device_set_wakeup_enable(), since dedicated wakeirq will be lost in device_set_wakeup_enable(false). Changes in v9: Add section for PCI devices and rewrite the commit message. Fix check error in .cleanup(). Move dedicated wakeirq setup to setup() callback and use device_set_wakeup_enable() to enable/disable. Rewrite the commit message. Changes in v8: Add optional "pci", and rewrite commit message. Add pci-of.c and use platform_pm_ops to handle the PCIe WAKE# signal. Rewrite the commit message. Changes in v7: Move PCIE_WAKE handling into pci core. Changes in v6: Fix device_init_wake error handling, and add some comments. Changes in v5: Move to pci.txt Rebase. Use "wakeup" instead of "wake" Changes in v3: Fix error handling. Changes in v2: Use dev_pm_set_dedicated_wake_irq. Jeffy Chen (5): dt-bindings: PCI: Add definition of PCIe WAKE# irq and PCI irq of/irq: Adjust of_pci_irq parsing for multiple interrupts mwifiex: Disable wakeup irq handling for pcie PCI / PM: Add support for the PCIe WAKE# signal for OF arm64: dts: rockchip: Move PCIe WAKE# irq to pcie port for Gru Documentation/devicetree/bindings/pci/pci.txt | 10 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 11 +++-- drivers/net/wireless/marvell/mwifiex/main.c | 4 ++ drivers/of/of_pci_irq.c | 71 +-- drivers/pci/pci-driver.c | 10 include/linux/of_pci.h| 9 6 files changed, 107 insertions(+), 8 deletions(-) -- 2.11.0
[RFC PATCH v10 3/7] mwifiex: Disable wakeup irq handling for pcie
We are going to handle the wakeup irq in the pci core. Signed-off-by: Jeffy Chen --- Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v3: None Changes in v2: None drivers/net/wireless/marvell/mwifiex/main.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index ee40b739b289..ba081c16f85c 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -1568,6 +1568,10 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter) goto err_exit; adapter->dt_node = dev->of_node; + + if (adapter->iface_type != MWIFIEX_PCIE) + goto err_exit; + adapter->irq_wakeup = irq_of_parse_and_map(adapter->dt_node, 0); if (!adapter->irq_wakeup) { dev_dbg(dev, "fail to parse irq_wakeup from device tree\n"); -- 2.11.0
[RFC PATCH v10 0/7] PCI: rockchip: Move PCIe WAKE# handling into pci core
Currently we are handling wake irq in mrvl wifi driver. Move it into pci core. Tested on my chromebook bob(with cros 4.4 kernel and mrvl wifi). Changes in v10: Use device_set_wakeup_capable() instead of device_set_wakeup_enable(), since dedicated wakeirq will be lost in device_set_wakeup_enable(false). Changes in v9: Add section for PCI devices and rewrite the commit message. Rewrite the commit message. Fix check error in .cleanup(). Move dedicated wakeirq setup to setup() callback and use device_set_wakeup_enable() to enable/disable. Changes in v8: Add optional "pci", and rewrite commit message. Rewrite the commit message. Add pci-of.c and use platform_pm_ops to handle the PCIe WAKE# signal. Changes in v7: Move PCIE_WAKE handling into pci core. Changes in v6: Fix device_init_wake error handling, and add some comments. Changes in v5: Move to pci.txt Use "wakeup" instead of "wake" Rebase. Changes in v3: Fix error handling. Changes in v2: Use dev_pm_set_dedicated_wake_irq. Jeffy Chen (7): dt-bindings: PCI: Add definition of PCIe WAKE# irq and PCI irq of/irq: Adjust of_pci_irq parsing for multiple interrupts mwifiex: Disable wakeup irq handling for pcie arm64: dts: rockchip: Move PCIe WAKE# irq to pcie driver for Gru PCI: Make pci_platform_pm_ops's callbacks optional PCI / PM: Move acpi wakeup code to pci core PCI / PM: Add support for the PCIe WAKE# signal for OF Documentation/devicetree/bindings/pci/pci.txt | 8 ++ arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 15 +-- drivers/net/wireless/marvell/mwifiex/main.c | 4 + drivers/of/of_pci_irq.c | 13 ++- drivers/pci/Makefile | 2 +- drivers/pci/pci-acpi.c| 121 drivers/pci/pci-driver.c | 9 ++ drivers/pci/pci-of.c | 127 ++ drivers/pci/pci.c | 112 +++ drivers/pci/pci.h | 31 +-- drivers/pci/probe.c | 12 ++- drivers/pci/remove.c | 2 + include/linux/pci.h | 2 + 13 files changed, 361 insertions(+), 97 deletions(-) create mode 100644 drivers/pci/pci-of.c -- 2.11.0
[RFC PATCH v9 3/7] mwifiex: Disable wakeup irq handling for pcie
We are going to handle the wakeup irq in the pci core. Signed-off-by: Jeffy Chen --- Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v3: None Changes in v2: None drivers/net/wireless/marvell/mwifiex/main.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index ee40b739b289..ba081c16f85c 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -1568,6 +1568,10 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter) goto err_exit; adapter->dt_node = dev->of_node; + + if (adapter->iface_type != MWIFIEX_PCIE) + goto err_exit; + adapter->irq_wakeup = irq_of_parse_and_map(adapter->dt_node, 0); if (!adapter->irq_wakeup) { dev_dbg(dev, "fail to parse irq_wakeup from device tree\n"); -- 2.11.0
[RFC PATCH v9 0/7] PCI: rockchip: Move PCIe WAKE# handling into pci core
Currently we are handling wake irq in mrvl wifi driver. Move it into pci core. Tested on my chromebook bob(with cros 4.4 kernel and mrvl wifi). Changes in v9: Add section for PCI devices and rewrite the commit message. Rewrite the commit message. Fix check error in .cleanup(). Move dedicated wakeirq setup to setup() callback and use device_set_wakeup_enable() to enable/disable. Changes in v8: Add optional "pci", and rewrite commit message. Rewrite the commit message. Add pci-of.c and use platform_pm_ops to handle the PCIe WAKE# signal. Changes in v7: Move PCIE_WAKE handling into pci core. Changes in v6: Fix device_init_wake error handling, and add some comments. Changes in v5: Move to pci.txt Use "wakeup" instead of "wake" Rebase. Changes in v3: Fix error handling. Changes in v2: Use dev_pm_set_dedicated_wake_irq. Jeffy Chen (7): dt-bindings: PCI: Add definition of PCIe WAKE# irq and PCI irq of/irq: Adjust of_pci_irq parsing for multiple interrupts mwifiex: Disable wakeup irq handling for pcie arm64: dts: rockchip: Move PCIe WAKE# irq to pcie driver for Gru PCI: Make pci_platform_pm_ops's callbacks optional PCI / PM: Move acpi wakeup code to pci core PCI / PM: Add support for the PCIe WAKE# signal for OF Documentation/devicetree/bindings/pci/pci.txt | 8 ++ arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 15 +-- drivers/net/wireless/marvell/mwifiex/main.c | 4 + drivers/of/of_pci_irq.c | 13 ++- drivers/pci/Makefile | 2 +- drivers/pci/pci-acpi.c| 121 - drivers/pci/pci-driver.c | 9 ++ drivers/pci/pci-of.c | 126 ++ drivers/pci/pci.c | 112 +++ drivers/pci/pci.h | 31 +-- drivers/pci/probe.c | 12 ++- drivers/pci/remove.c | 2 + include/linux/pci.h | 2 + 13 files changed, 360 insertions(+), 97 deletions(-) create mode 100644 drivers/pci/pci-of.c -- 2.11.0
[RFC PATCH v8 0/7] PCI: rockchip: Move PCIe WAKE# handling into pci core
Currently we are handling wake irq in mrvl wifi driver. Move it into pci core. Tested on my chromebook bob(with cros 4.4 kernel and mrvl wifi). Changes in v8: Add optional "pci", and rewrite commit message. Rewrite the commit message. Add pci-of.c and use platform_pm_ops to handle the PCIe WAKE# signal. Changes in v7: Move PCIE_WAKE handling into pci core. Changes in v6: Fix device_init_wake error handling, and add some comments. Changes in v5: Move to pci.txt Use "wakeup" instead of "wake" Rebase. Changes in v3: Fix error handling. Changes in v2: Use dev_pm_set_dedicated_wake_irq. Jeffy Chen (7): dt-bindings: PCI: Add definition of PCIe WAKE# irq and PCI irq mwifiex: Disable wakeup irq handling for pcie arm64: dts: rockchip: Handle PCIe WAKE# signal in pcie driver for Gru of/irq: Adjust of pci irq parsing for multiple interrupts PCI: Make pci_platform_pm_ops's callbacks optional PCI / PM: Move acpi wakeup code to pci core PCI / PM: Add support for the PCIe WAKE# signal for OF Documentation/devicetree/bindings/pci/pci.txt | 3 + arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 15 +-- drivers/net/wireless/marvell/mwifiex/main.c | 4 + drivers/of/of_pci_irq.c | 13 ++- drivers/pci/Makefile | 2 +- drivers/pci/pci-acpi.c| 121 +++ drivers/pci/pci-driver.c | 9 ++ drivers/pci/pci-of.c | 136 ++ drivers/pci/pci.c | 112 + drivers/pci/pci.h | 31 -- drivers/pci/probe.c | 12 ++- drivers/pci/remove.c | 2 + include/linux/pci.h | 2 + 13 files changed, 365 insertions(+), 97 deletions(-) create mode 100644 drivers/pci/pci-of.c -- 2.11.0
[RFC PATCH v8 2/7] mwifiex: Disable wakeup irq handling for pcie
We are going to handle the wakeup irq in the pci core. Signed-off-by: Jeffy Chen --- Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v3: None Changes in v2: None drivers/net/wireless/marvell/mwifiex/main.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index ee40b739b289..ba081c16f85c 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -1568,6 +1568,10 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter) goto err_exit; adapter->dt_node = dev->of_node; + + if (adapter->iface_type != MWIFIEX_PCIE) + goto err_exit; + adapter->irq_wakeup = irq_of_parse_and_map(adapter->dt_node, 0); if (!adapter->irq_wakeup) { dev_dbg(dev, "fail to parse irq_wakeup from device tree\n"); -- 2.11.0
[PATCH v2] mwifiex: uninit wakeup info in the error handling
We inited wakeup info at the beginning of mwifiex_add_card, so we need to uninit it in the error handling. It's much the same as what we did in: 36908c4 mwifiex: uninit wakeup info when removing device Signed-off-by: Jeffy Chen --- Changes in v2: Uninit wakeup when _mwifiex_fw_dpc failed too. drivers/net/wireless/marvell/mwifiex/main.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index f2600b8..097a899 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -665,8 +665,11 @@ static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context) release_firmware(adapter->firmware); adapter->firmware = NULL; } - if (init_failed) + if (init_failed) { + if (adapter->irq_wakeup >= 0) + device_init_wakeup(adapter->dev, false); mwifiex_free_adapter(adapter); + } /* Tell all current and future waiters we're finished */ complete_all(fw_done); @@ -1655,6 +1658,8 @@ mwifiex_add_card(void *card, struct completion *fw_done, mwifiex_shutdown_drv(adapter); } err_kmalloc: + if (adapter->irq_wakeup >= 0) + device_init_wakeup(adapter->dev, false); mwifiex_free_adapter(adapter); err_init_sw: -- 2.1.4
[PATCH] mwifiex: uninit wakeup info when failed to add card
We inited wakeup info at the beginning of mwifiex_add_card, so we need to uninit it in the error handling. It's much the same as what we did in: 36908c4 mwifiex: uninit wakeup info when removing device Signed-off-by: Jeffy Chen --- drivers/net/wireless/marvell/mwifiex/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index f2600b8..17d2cbe 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -1655,6 +1655,8 @@ mwifiex_add_card(void *card, struct completion *fw_done, mwifiex_shutdown_drv(adapter); } err_kmalloc: + if (adapter->irq_wakeup >= 0) + device_init_wakeup(adapter->dev, false); mwifiex_free_adapter(adapter); err_init_sw: -- 2.1.4
[RESEND PATCH v4 2/3] Bluetooth: cmtp: fix possible might sleep error in cmtp_session
It looks like cmtp_session has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen Reviewed-by: Brian Norris Reviewed-by: AL Yu-Chen Cho --- Changes in v4: None Changes in v2: Remove unnecessary memory barrier before wake_up_* functions. net/bluetooth/cmtp/core.c | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 9e59b66..1152ce3 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -280,16 +280,16 @@ static int cmtp_session(void *arg) struct cmtp_session *session = arg; struct sock *sk = session->sock->sk; struct sk_buff *skb; - wait_queue_t wait; + DEFINE_WAIT_FUNC(wait, woken_wake_function); BT_DBG("session %p", session); set_user_nice(current, -15); - init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); while (1) { - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -306,9 +306,8 @@ static int cmtp_session(void *arg) cmtp_process_transmit(session); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); down_write(&cmtp_session_sem); @@ -393,7 +392,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) err = cmtp_attach_device(session); if (err < 0) { atomic_inc(&session->terminate); - wake_up_process(session->task); + wake_up_interruptible(sk_sleep(session->sock->sk)); up_write(&cmtp_session_sem); return err; } @@ -431,7 +430,11 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) /* Stop session thread */ atomic_inc(&session->terminate); - wake_up_process(session->task); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); + + wake_up_interruptible(sk_sleep(session->sock->sk)); } else err = -ENOENT; -- 2.1.4
[RESEND PATCH v4 3/3] Bluetooth: hidp: fix possible might sleep error in hidp_session_thread
It looks like hidp_session_thread has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen Tested-by: AL Yu-Chen Cho Tested-by: Rohit Vaswani --- Changes in v4: 1/ Make hidp_session_wake_function static. 2/ Remove unnecessary default_wake_function. Changes in v2: 1/ Fix could not wake up by wake attempts on original wait queues. 2/ Remove unnecessary memory barrier before wake_up_* functions. net/bluetooth/hidp/core.c | 33 ++--- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 0bec458..1fc0764 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -36,6 +36,7 @@ #define VERSION "1.2" static DECLARE_RWSEM(hidp_session_sem); +static DECLARE_WAIT_QUEUE_HEAD(hidp_session_wq); static LIST_HEAD(hidp_session_list); static unsigned char hidp_keycode[256] = { @@ -1068,12 +1069,12 @@ static int hidp_session_start_sync(struct hidp_session *session) * Wake up session thread and notify it to stop. This is asynchronous and * returns immediately. Call this whenever a runtime error occurs and you want * the session to stop. - * Note: wake_up_process() performs any necessary memory-barriers for us. + * Note: wake_up_interruptible() performs any necessary memory-barriers for us. */ static void hidp_session_terminate(struct hidp_session *session) { atomic_inc(&session->terminate); - wake_up_process(session->task); + wake_up_interruptible(&hidp_session_wq); } /* @@ -1180,7 +1181,9 @@ static void hidp_session_run(struct hidp_session *session) struct sock *ctrl_sk = session->ctrl_sock->sk; struct sock *intr_sk = session->intr_sock->sk; struct sk_buff *skb; + DEFINE_WAIT_FUNC(wait, woken_wake_function); + add_wait_queue(&hidp_session_wq, &wait); for (;;) { /* * This thread can be woken up two ways: @@ -1188,12 +1191,10 @@ static void hidp_session_run(struct hidp_session *session) *session->terminate flag and wakes this thread up. * - Via modifying the socket state of ctrl/intr_sock. This *thread is woken up by ->sk_state_changed(). -* -* Note: set_current_state() performs any necessary -* memory-barriers for us. */ - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -1227,11 +1228,22 @@ static void hidp_session_run(struct hidp_session *session) hidp_process_transmit(session, &session->ctrl_transmit, session->ctrl_sock); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } + remove_wait_queue(&hidp_session_wq, &wait); atomic_inc(&session->terminate); - set_current_state(TASK_RUNNING); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); +} + +static int hidp_session_wake_function(wait_queue_t *wait, + unsigned int mode, + int sync, void *key) +{ + wake_up_interruptible(&hidp_session_wq); + return false; } /* @@ -1244,7 +1256,8 @@ static void hidp_session_run(struct hidp_session *session) static int hidp_session_thread(void *arg) { struct hidp_session *session = arg; - wait_queue_t ctrl_wait, intr_wait; + DEFINE_WAIT_FUNC(ctrl_wait, hidp_session_wake_function); + DEFINE_WAIT_FUNC(intr_wait, hidp_session_wake_function); BT_DBG("session %p", session); @@ -1254,8 +1267,6 @@ static int hidp_session_thread(void *arg) set_user_nice(current, -15); hidp_set_timer(session); - init_waitqueue_entry(&ctrl_wait, current); - init_waitqueue_entry(&intr_wait, current); add_wait_queue(sk_sleep(session->ctrl_sock->sk), &ctrl_wait); add_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); /* This memory barrier is paired with wq_has_sleeper(). See -- 2.1.4
[RESEND PATCH v4 1/3] Bluetooth: bnep: fix possible might sleep error in bnep_session
It looks like bnep_session has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen Reviewed-by: Brian Norris Reviewed-by: AL Yu-Chen Cho --- Changes in v4: None Changes in v2: None net/bluetooth/bnep/core.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index fbf251f..4d6b94d 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -484,16 +484,16 @@ static int bnep_session(void *arg) struct net_device *dev = s->dev; struct sock *sk = s->sock->sk; struct sk_buff *skb; - wait_queue_t wait; + DEFINE_WAIT_FUNC(wait, woken_wake_function); BT_DBG(""); set_user_nice(current, -15); - init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); while (1) { - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&s->terminate)) break; @@ -515,9 +515,8 @@ static int bnep_session(void *arg) break; netif_wake_queue(dev); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); /* Cleanup session */ @@ -666,7 +665,7 @@ int bnep_del_connection(struct bnep_conndel_req *req) s = __bnep_get_session(req->dst); if (s) { atomic_inc(&s->terminate); - wake_up_process(s->task); + wake_up_interruptible(sk_sleep(s->sock->sk)); } else err = -ENOENT; -- 2.1.4
[PATCH 3/3] mwifiex: wake system up when receives a wake irq
Currrently we are disabling this wake irq after receiving it. If this happens before we finish suspend and the pm event check is disabled, the system will continue suspending, and this irq would not work again. We may need to abort system suspend to avoid that. Signed-off-by: Jeffy Chen --- drivers/net/wireless/marvell/mwifiex/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index 5ebca1d..30f4994 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -17,6 +17,8 @@ * this warranty disclaimer. */ +#include + #include "main.h" #include "wmm.h" #include "cfg80211.h" @@ -1509,6 +1511,7 @@ static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv) /* Notify PM core we are wakeup source */ pm_wakeup_event(adapter->dev, 0); + pm_system_wakeup(); return IRQ_HANDLED; } -- 2.1.4
[PATCH v4 3/3] Bluetooth: hidp: fix possible might sleep error in hidp_session_thread
It looks like hidp_session_thread has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen 1/ Fix could not wake up by wake attempts on original wait queues. 2/ Remove unnecessary memory barrier before wake_up_* functions. 1/ Make hidp_session_wake_function static. 2/ Remove unnecessary default_wake_function. --- Changes in v3: None Changes in v2: None net/bluetooth/hidp/core.c | 33 ++--- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 0bec458..1fc0764 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -36,6 +36,7 @@ #define VERSION "1.2" static DECLARE_RWSEM(hidp_session_sem); +static DECLARE_WAIT_QUEUE_HEAD(hidp_session_wq); static LIST_HEAD(hidp_session_list); static unsigned char hidp_keycode[256] = { @@ -1068,12 +1069,12 @@ static int hidp_session_start_sync(struct hidp_session *session) * Wake up session thread and notify it to stop. This is asynchronous and * returns immediately. Call this whenever a runtime error occurs and you want * the session to stop. - * Note: wake_up_process() performs any necessary memory-barriers for us. + * Note: wake_up_interruptible() performs any necessary memory-barriers for us. */ static void hidp_session_terminate(struct hidp_session *session) { atomic_inc(&session->terminate); - wake_up_process(session->task); + wake_up_interruptible(&hidp_session_wq); } /* @@ -1180,7 +1181,9 @@ static void hidp_session_run(struct hidp_session *session) struct sock *ctrl_sk = session->ctrl_sock->sk; struct sock *intr_sk = session->intr_sock->sk; struct sk_buff *skb; + DEFINE_WAIT_FUNC(wait, woken_wake_function); + add_wait_queue(&hidp_session_wq, &wait); for (;;) { /* * This thread can be woken up two ways: @@ -1188,12 +1191,10 @@ static void hidp_session_run(struct hidp_session *session) *session->terminate flag and wakes this thread up. * - Via modifying the socket state of ctrl/intr_sock. This *thread is woken up by ->sk_state_changed(). -* -* Note: set_current_state() performs any necessary -* memory-barriers for us. */ - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -1227,11 +1228,22 @@ static void hidp_session_run(struct hidp_session *session) hidp_process_transmit(session, &session->ctrl_transmit, session->ctrl_sock); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } + remove_wait_queue(&hidp_session_wq, &wait); atomic_inc(&session->terminate); - set_current_state(TASK_RUNNING); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); +} + +static int hidp_session_wake_function(wait_queue_t *wait, + unsigned int mode, + int sync, void *key) +{ + wake_up_interruptible(&hidp_session_wq); + return false; } /* @@ -1244,7 +1256,8 @@ static void hidp_session_run(struct hidp_session *session) static int hidp_session_thread(void *arg) { struct hidp_session *session = arg; - wait_queue_t ctrl_wait, intr_wait; + DEFINE_WAIT_FUNC(ctrl_wait, hidp_session_wake_function); + DEFINE_WAIT_FUNC(intr_wait, hidp_session_wake_function); BT_DBG("session %p", session); @@ -1254,8 +1267,6 @@ static int hidp_session_thread(void *arg) set_user_nice(current, -15); hidp_set_timer(session); - init_waitqueue_entry(&ctrl_wait, current); - init_waitqueue_entry(&intr_wait, current); add_wait_queue(sk_sleep(session->ctrl_sock->sk), &ctrl_wait); add_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); /* This memory barrier is paired with wq_has_sleeper(). See -- 2.1.4
[PATCH v4 2/3] Bluetooth: cmtp: fix possible might sleep error in cmtp_session
It looks like cmtp_session has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen Reviewed-by: Brian Norris Remove unnecessary memory barrier before wake_up_* functions. --- Changes in v3: Add brian's Reviewed-by. Changes in v2: None net/bluetooth/cmtp/core.c | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 9e59b66..1152ce3 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -280,16 +280,16 @@ static int cmtp_session(void *arg) struct cmtp_session *session = arg; struct sock *sk = session->sock->sk; struct sk_buff *skb; - wait_queue_t wait; + DEFINE_WAIT_FUNC(wait, woken_wake_function); BT_DBG("session %p", session); set_user_nice(current, -15); - init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); while (1) { - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -306,9 +306,8 @@ static int cmtp_session(void *arg) cmtp_process_transmit(session); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); down_write(&cmtp_session_sem); @@ -393,7 +392,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) err = cmtp_attach_device(session); if (err < 0) { atomic_inc(&session->terminate); - wake_up_process(session->task); + wake_up_interruptible(sk_sleep(session->sock->sk)); up_write(&cmtp_session_sem); return err; } @@ -431,7 +430,11 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) /* Stop session thread */ atomic_inc(&session->terminate); - wake_up_process(session->task); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); + + wake_up_interruptible(sk_sleep(session->sock->sk)); } else err = -ENOENT; -- 2.1.4
[PATCH v4 1/3] Bluetooth: bnep: fix possible might sleep error in bnep_session
It looks like bnep_session has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen Reviewed-by: Brian Norris --- Changes in v3: Add brian's Reviewed-by. Changes in v2: Remove unnecessary memory barrier before wake_up_* functions. net/bluetooth/bnep/core.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index fbf251f..4d6b94d 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -484,16 +484,16 @@ static int bnep_session(void *arg) struct net_device *dev = s->dev; struct sock *sk = s->sock->sk; struct sk_buff *skb; - wait_queue_t wait; + DEFINE_WAIT_FUNC(wait, woken_wake_function); BT_DBG(""); set_user_nice(current, -15); - init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); while (1) { - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&s->terminate)) break; @@ -515,9 +515,8 @@ static int bnep_session(void *arg) break; netif_wake_queue(dev); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); /* Cleanup session */ @@ -666,7 +665,7 @@ int bnep_del_connection(struct bnep_conndel_req *req) s = __bnep_get_session(req->dst); if (s) { atomic_inc(&s->terminate); - wake_up_process(s->task); + wake_up_interruptible(sk_sleep(s->sock->sk)); } else err = -ENOENT; -- 2.1.4
[PATCH v3 3/3] Bluetooth: hidp: fix possible might sleep error in hidp_session_thread
It looks like hidp_session_thread has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen 1/ Fix could not wake up by wake attempts on original wait queues. 2/ Remove unnecessary memory barrier before wake_up_* functions. --- Changes in v3: None Changes in v2: None net/bluetooth/hidp/core.c | 33 ++--- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 0bec458..076bc50 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -36,6 +36,7 @@ #define VERSION "1.2" static DECLARE_RWSEM(hidp_session_sem); +static DECLARE_WAIT_QUEUE_HEAD(hidp_session_wq); static LIST_HEAD(hidp_session_list); static unsigned char hidp_keycode[256] = { @@ -1068,12 +1069,12 @@ static int hidp_session_start_sync(struct hidp_session *session) * Wake up session thread and notify it to stop. This is asynchronous and * returns immediately. Call this whenever a runtime error occurs and you want * the session to stop. - * Note: wake_up_process() performs any necessary memory-barriers for us. + * Note: wake_up_interruptible() performs any necessary memory-barriers for us. */ static void hidp_session_terminate(struct hidp_session *session) { atomic_inc(&session->terminate); - wake_up_process(session->task); + wake_up_interruptible(&hidp_session_wq); } /* @@ -1180,7 +1181,9 @@ static void hidp_session_run(struct hidp_session *session) struct sock *ctrl_sk = session->ctrl_sock->sk; struct sock *intr_sk = session->intr_sock->sk; struct sk_buff *skb; + DEFINE_WAIT_FUNC(wait, woken_wake_function); + add_wait_queue(&hidp_session_wq, &wait); for (;;) { /* * This thread can be woken up two ways: @@ -1188,12 +1191,10 @@ static void hidp_session_run(struct hidp_session *session) *session->terminate flag and wakes this thread up. * - Via modifying the socket state of ctrl/intr_sock. This *thread is woken up by ->sk_state_changed(). -* -* Note: set_current_state() performs any necessary -* memory-barriers for us. */ - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -1227,11 +1228,22 @@ static void hidp_session_run(struct hidp_session *session) hidp_process_transmit(session, &session->ctrl_transmit, session->ctrl_sock); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } + remove_wait_queue(&hidp_session_wq, &wait); atomic_inc(&session->terminate); - set_current_state(TASK_RUNNING); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); +} + +int hidp_session_wake_function(wait_queue_t *wait, unsigned int mode, + int sync, void *key) +{ + wake_up_interruptible(&hidp_session_wq); + + return default_wake_function(wait, mode, sync, key); } /* @@ -1244,7 +1256,8 @@ static void hidp_session_run(struct hidp_session *session) static int hidp_session_thread(void *arg) { struct hidp_session *session = arg; - wait_queue_t ctrl_wait, intr_wait; + DEFINE_WAIT_FUNC(ctrl_wait, hidp_session_wake_function); + DEFINE_WAIT_FUNC(intr_wait, hidp_session_wake_function); BT_DBG("session %p", session); @@ -1254,8 +1267,6 @@ static int hidp_session_thread(void *arg) set_user_nice(current, -15); hidp_set_timer(session); - init_waitqueue_entry(&ctrl_wait, current); - init_waitqueue_entry(&intr_wait, current); add_wait_queue(sk_sleep(session->ctrl_sock->sk), &ctrl_wait); add_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); /* This memory barrier is paired with wq_has_sleeper(). See -- 2.1.4
[PATCH v3 1/3] Bluetooth: bnep: fix possible might sleep error in bnep_session
It looks like bnep_session has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen Reviewed-by: Brian Norris --- Changes in v3: Add brian's Reviewed-by. Changes in v2: Remove unnecessary memory barrier before wake_up_* functions. net/bluetooth/bnep/core.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index fbf251f..4d6b94d 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -484,16 +484,16 @@ static int bnep_session(void *arg) struct net_device *dev = s->dev; struct sock *sk = s->sock->sk; struct sk_buff *skb; - wait_queue_t wait; + DEFINE_WAIT_FUNC(wait, woken_wake_function); BT_DBG(""); set_user_nice(current, -15); - init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); while (1) { - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&s->terminate)) break; @@ -515,9 +515,8 @@ static int bnep_session(void *arg) break; netif_wake_queue(dev); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); /* Cleanup session */ @@ -666,7 +665,7 @@ int bnep_del_connection(struct bnep_conndel_req *req) s = __bnep_get_session(req->dst); if (s) { atomic_inc(&s->terminate); - wake_up_process(s->task); + wake_up_interruptible(sk_sleep(s->sock->sk)); } else err = -ENOENT; -- 2.1.4
[PATCH v3 2/3] Bluetooth: cmtp: fix possible might sleep error in cmtp_session
It looks like cmtp_session has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen Reviewed-by: Brian Norris Remove unnecessary memory barrier before wake_up_* functions. --- Changes in v3: Add brian's Reviewed-by. Changes in v2: None net/bluetooth/cmtp/core.c | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 9e59b66..1152ce3 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -280,16 +280,16 @@ static int cmtp_session(void *arg) struct cmtp_session *session = arg; struct sock *sk = session->sock->sk; struct sk_buff *skb; - wait_queue_t wait; + DEFINE_WAIT_FUNC(wait, woken_wake_function); BT_DBG("session %p", session); set_user_nice(current, -15); - init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); while (1) { - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -306,9 +306,8 @@ static int cmtp_session(void *arg) cmtp_process_transmit(session); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); down_write(&cmtp_session_sem); @@ -393,7 +392,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) err = cmtp_attach_device(session); if (err < 0) { atomic_inc(&session->terminate); - wake_up_process(session->task); + wake_up_interruptible(sk_sleep(session->sock->sk)); up_write(&cmtp_session_sem); return err; } @@ -431,7 +430,11 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) /* Stop session thread */ atomic_inc(&session->terminate); - wake_up_process(session->task); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); + + wake_up_interruptible(sk_sleep(session->sock->sk)); } else err = -ENOENT; -- 2.1.4
[PATCH v2 3/3] Bluetooth: hidp: fix possible might sleep error in hidp_session_thread
It looks like hidp_session_thread has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen 1/ Fix could not wake up by wake attempts on original wait queues. 2/ Remove unnecessary memory barrier before wake_up_* functions. --- Changes in v2: None net/bluetooth/hidp/core.c | 33 ++--- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 0bec458..076bc50 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -36,6 +36,7 @@ #define VERSION "1.2" static DECLARE_RWSEM(hidp_session_sem); +static DECLARE_WAIT_QUEUE_HEAD(hidp_session_wq); static LIST_HEAD(hidp_session_list); static unsigned char hidp_keycode[256] = { @@ -1068,12 +1069,12 @@ static int hidp_session_start_sync(struct hidp_session *session) * Wake up session thread and notify it to stop. This is asynchronous and * returns immediately. Call this whenever a runtime error occurs and you want * the session to stop. - * Note: wake_up_process() performs any necessary memory-barriers for us. + * Note: wake_up_interruptible() performs any necessary memory-barriers for us. */ static void hidp_session_terminate(struct hidp_session *session) { atomic_inc(&session->terminate); - wake_up_process(session->task); + wake_up_interruptible(&hidp_session_wq); } /* @@ -1180,7 +1181,9 @@ static void hidp_session_run(struct hidp_session *session) struct sock *ctrl_sk = session->ctrl_sock->sk; struct sock *intr_sk = session->intr_sock->sk; struct sk_buff *skb; + DEFINE_WAIT_FUNC(wait, woken_wake_function); + add_wait_queue(&hidp_session_wq, &wait); for (;;) { /* * This thread can be woken up two ways: @@ -1188,12 +1191,10 @@ static void hidp_session_run(struct hidp_session *session) *session->terminate flag and wakes this thread up. * - Via modifying the socket state of ctrl/intr_sock. This *thread is woken up by ->sk_state_changed(). -* -* Note: set_current_state() performs any necessary -* memory-barriers for us. */ - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -1227,11 +1228,22 @@ static void hidp_session_run(struct hidp_session *session) hidp_process_transmit(session, &session->ctrl_transmit, session->ctrl_sock); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } + remove_wait_queue(&hidp_session_wq, &wait); atomic_inc(&session->terminate); - set_current_state(TASK_RUNNING); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); +} + +int hidp_session_wake_function(wait_queue_t *wait, unsigned int mode, + int sync, void *key) +{ + wake_up_interruptible(&hidp_session_wq); + + return default_wake_function(wait, mode, sync, key); } /* @@ -1244,7 +1256,8 @@ static void hidp_session_run(struct hidp_session *session) static int hidp_session_thread(void *arg) { struct hidp_session *session = arg; - wait_queue_t ctrl_wait, intr_wait; + DEFINE_WAIT_FUNC(ctrl_wait, hidp_session_wake_function); + DEFINE_WAIT_FUNC(intr_wait, hidp_session_wake_function); BT_DBG("session %p", session); @@ -1254,8 +1267,6 @@ static int hidp_session_thread(void *arg) set_user_nice(current, -15); hidp_set_timer(session); - init_waitqueue_entry(&ctrl_wait, current); - init_waitqueue_entry(&intr_wait, current); add_wait_queue(sk_sleep(session->ctrl_sock->sk), &ctrl_wait); add_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); /* This memory barrier is paired with wq_has_sleeper(). See -- 2.1.4
[PATCH v2 1/3] Bluetooth: bnep: fix possible might sleep error in bnep_session
It looks like bnep_session has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen --- Changes in v2: Remove unnecessary memory barrier before wake_up_* functions. net/bluetooth/bnep/core.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index fbf251f..4d6b94d 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -484,16 +484,16 @@ static int bnep_session(void *arg) struct net_device *dev = s->dev; struct sock *sk = s->sock->sk; struct sk_buff *skb; - wait_queue_t wait; + DEFINE_WAIT_FUNC(wait, woken_wake_function); BT_DBG(""); set_user_nice(current, -15); - init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); while (1) { - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&s->terminate)) break; @@ -515,9 +515,8 @@ static int bnep_session(void *arg) break; netif_wake_queue(dev); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); /* Cleanup session */ @@ -666,7 +665,7 @@ int bnep_del_connection(struct bnep_conndel_req *req) s = __bnep_get_session(req->dst); if (s) { atomic_inc(&s->terminate); - wake_up_process(s->task); + wake_up_interruptible(sk_sleep(s->sock->sk)); } else err = -ENOENT; -- 2.1.4
[PATCH v2 2/3] Bluetooth: cmtp: fix possible might sleep error in cmtp_session
It looks like cmtp_session has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen Remove unnecessary memory barrier before wake_up_* functions. --- Changes in v2: None net/bluetooth/cmtp/core.c | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 9e59b66..1152ce3 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -280,16 +280,16 @@ static int cmtp_session(void *arg) struct cmtp_session *session = arg; struct sock *sk = session->sock->sk; struct sk_buff *skb; - wait_queue_t wait; + DEFINE_WAIT_FUNC(wait, woken_wake_function); BT_DBG("session %p", session); set_user_nice(current, -15); - init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); while (1) { - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -306,9 +306,8 @@ static int cmtp_session(void *arg) cmtp_process_transmit(session); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); down_write(&cmtp_session_sem); @@ -393,7 +392,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) err = cmtp_attach_device(session); if (err < 0) { atomic_inc(&session->terminate); - wake_up_process(session->task); + wake_up_interruptible(sk_sleep(session->sock->sk)); up_write(&cmtp_session_sem); return err; } @@ -431,7 +430,11 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) /* Stop session thread */ atomic_inc(&session->terminate); - wake_up_process(session->task); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); + + wake_up_interruptible(sk_sleep(session->sock->sk)); } else err = -ENOENT; -- 2.1.4
[PATCH 2/3] Bluetooth: cmtp: fix possible might sleep error in cmtp_session
It looks like cmtp_session has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen --- net/bluetooth/cmtp/core.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 9e59b66..6b03f2b 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -280,16 +280,16 @@ static int cmtp_session(void *arg) struct cmtp_session *session = arg; struct sock *sk = session->sock->sk; struct sk_buff *skb; - wait_queue_t wait; + DEFINE_WAIT_FUNC(wait, woken_wake_function); BT_DBG("session %p", session); set_user_nice(current, -15); - init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); while (1) { - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -306,9 +306,8 @@ static int cmtp_session(void *arg) cmtp_process_transmit(session); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); down_write(&cmtp_session_sem); @@ -393,7 +392,11 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) err = cmtp_attach_device(session); if (err < 0) { atomic_inc(&session->terminate); - wake_up_process(session->task); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); + + wake_up_interruptible(sk_sleep(session->sock->sk)); up_write(&cmtp_session_sem); return err; } @@ -431,7 +434,11 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) /* Stop session thread */ atomic_inc(&session->terminate); - wake_up_process(session->task); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); + + wake_up_interruptible(sk_sleep(session->sock->sk)); } else err = -ENOENT; -- 2.1.4
[PATCH 3/3] Bluetooth: hidp: fix possible might sleep error in hidp_session_thread
It looks like hidp_session_thread has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen --- net/bluetooth/hidp/core.c | 23 +++ 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 0bec458..43d6e6a 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -36,6 +36,7 @@ #define VERSION "1.2" static DECLARE_RWSEM(hidp_session_sem); +static DECLARE_WAIT_QUEUE_HEAD(hidp_session_wq); static LIST_HEAD(hidp_session_list); static unsigned char hidp_keycode[256] = { @@ -1068,12 +1069,15 @@ static int hidp_session_start_sync(struct hidp_session *session) * Wake up session thread and notify it to stop. This is asynchronous and * returns immediately. Call this whenever a runtime error occurs and you want * the session to stop. - * Note: wake_up_process() performs any necessary memory-barriers for us. */ static void hidp_session_terminate(struct hidp_session *session) { atomic_inc(&session->terminate); - wake_up_process(session->task); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); + + wake_up_interruptible(&hidp_session_wq); } /* @@ -1180,7 +1184,9 @@ static void hidp_session_run(struct hidp_session *session) struct sock *ctrl_sk = session->ctrl_sock->sk; struct sock *intr_sk = session->intr_sock->sk; struct sk_buff *skb; + DEFINE_WAIT_FUNC(wait, woken_wake_function); + add_wait_queue(&hidp_session_wq, &wait); for (;;) { /* * This thread can be woken up two ways: @@ -1188,12 +1194,10 @@ static void hidp_session_run(struct hidp_session *session) *session->terminate flag and wakes this thread up. * - Via modifying the socket state of ctrl/intr_sock. This *thread is woken up by ->sk_state_changed(). -* -* Note: set_current_state() performs any necessary -* memory-barriers for us. */ - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -1227,11 +1231,14 @@ static void hidp_session_run(struct hidp_session *session) hidp_process_transmit(session, &session->ctrl_transmit, session->ctrl_sock); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } + remove_wait_queue(&hidp_session_wq, &wait); atomic_inc(&session->terminate); - set_current_state(TASK_RUNNING); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); } /* -- 2.1.4
[PATCH 1/3] Bluetooth: bnep: fix possible might sleep error in bnep_session
It looks like bnep_session has same pattern as the issue reported in old rfcomm: while (1) { set_current_state(TASK_INTERRUPTIBLE); if (condition) break; // may call might_sleep here schedule(); } __set_current_state(TASK_RUNNING); Which fixed at: dfb2fae Bluetooth: Fix nested sleeps So let's fix it at the same way, also follow the suggestion of: https://lwn.net/Articles/628628/ Signed-off-by: Jeffy Chen --- net/bluetooth/bnep/core.c | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index fbf251f..da04d51 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -484,16 +484,16 @@ static int bnep_session(void *arg) struct net_device *dev = s->dev; struct sock *sk = s->sock->sk; struct sk_buff *skb; - wait_queue_t wait; + DEFINE_WAIT_FUNC(wait, woken_wake_function); BT_DBG(""); set_user_nice(current, -15); - init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); while (1) { - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&s->terminate)) break; @@ -515,9 +515,8 @@ static int bnep_session(void *arg) break; netif_wake_queue(dev); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } - __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); /* Cleanup session */ @@ -666,7 +665,11 @@ int bnep_del_connection(struct bnep_conndel_req *req) s = __bnep_get_session(req->dst); if (s) { atomic_inc(&s->terminate); - wake_up_process(s->task); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); + + wake_up_interruptible(sk_sleep(s->sock->sk)); } else err = -ENOENT; -- 2.1.4
[PATCH] Bluetooth: hidp: might sleep error in hidp_session_thread
[ 39.044329] do not call blocking ops when !TASK_RUNNING; state=1 set at [] hidp_session_thread+0x110/0x568 [hidp] ... [ 40.159664] Call trace: [ 40.162122] [] __might_sleep+0x64/0x90 [ 40.167443] [] lock_sock_nested+0x30/0x78 [ 40.173047] [] l2cap_sock_sendmsg+0x90/0xf0 [bluetooth] [ 40.179842] [] sock_sendmsg+0x4c/0x68 [ 40.185072] [] kernel_sendmsg+0x54/0x68 [ 40.190477] [] hidp_send_frame+0x78/0xa0 [hidp] [ 40.196574] [] hidp_process_transmit+0x44/0x98 [hidp] [ 40.203191] [] hidp_session_thread+0x364/0x568 [hidp] Following (https://lwn.net/Articles/628628/). Signed-off-by: Jeffy Chen --- net/bluetooth/hidp/core.c | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 0bec458..bfd3fb8 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -1180,7 +1180,9 @@ static void hidp_session_run(struct hidp_session *session) struct sock *ctrl_sk = session->ctrl_sock->sk; struct sock *intr_sk = session->intr_sock->sk; struct sk_buff *skb; + DEFINE_WAIT_FUNC(wait, woken_wake_function); + add_wait_queue(sk_sleep(intr_sk), &wait); for (;;) { /* * This thread can be woken up two ways: @@ -1188,12 +1190,10 @@ static void hidp_session_run(struct hidp_session *session) *session->terminate flag and wakes this thread up. * - Via modifying the socket state of ctrl/intr_sock. This *thread is woken up by ->sk_state_changed(). -* -* Note: set_current_state() performs any necessary -* memory-barriers for us. */ - set_current_state(TASK_INTERRUPTIBLE); + /* Ensure session->terminate is updated */ + smp_mb__before_atomic(); if (atomic_read(&session->terminate)) break; @@ -1227,11 +1227,14 @@ static void hidp_session_run(struct hidp_session *session) hidp_process_transmit(session, &session->ctrl_transmit, session->ctrl_sock); - schedule(); + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } + remove_wait_queue(sk_sleep(intr_sk), &wait); atomic_inc(&session->terminate); - set_current_state(TASK_RUNNING); + + /* Ensure session->terminate is updated */ + smp_mb__after_atomic(); } /* -- 2.1.4