]> git.itanic.dy.fi Git - linux-stable/commitdiff
wfx: avoid flush_workqueue(system_highpri_wq) usage
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Mon, 2 May 2022 08:16:06 +0000 (17:16 +0900)
committerKalle Valo <kvalo@kernel.org>
Wed, 4 May 2022 05:29:00 +0000 (08:29 +0300)
Flushing system-wide workqueues is dangerous and will be forbidden.
Replace system_highpri_wq with per "struct wfx_dev" bh_wq.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/f15574a6-aba4-72bc-73af-26fdcdf9fb63@I-love.SAKURA.ne.jp
drivers/net/wireless/silabs/wfx/bh.c
drivers/net/wireless/silabs/wfx/hif_tx.c
drivers/net/wireless/silabs/wfx/main.c
drivers/net/wireless/silabs/wfx/wfx.h

index bcea9d5b119c8e03c9109bc6ce4f7bdd47a05af4..21dfdcf9cc27345e566c5dedcbd618d41283f0f7 100644 (file)
@@ -267,7 +267,7 @@ void wfx_bh_request_rx(struct wfx_dev *wdev)
        wfx_control_reg_read(wdev, &cur);
        prev = atomic_xchg(&wdev->hif.ctrl_reg, cur);
        complete(&wdev->hif.ctrl_ready);
-       queue_work(system_highpri_wq, &wdev->hif.bh);
+       queue_work(wdev->bh_wq, &wdev->hif.bh);
 
        if (!(cur & CTRL_NEXT_LEN_MASK))
                dev_err(wdev->dev, "unexpected control register value: length field is 0: %04x\n",
@@ -280,7 +280,7 @@ void wfx_bh_request_rx(struct wfx_dev *wdev)
 /* Driver want to send data */
 void wfx_bh_request_tx(struct wfx_dev *wdev)
 {
-       queue_work(system_highpri_wq, &wdev->hif.bh);
+       queue_work(wdev->bh_wq, &wdev->hif.bh);
 }
 
 /* If IRQ is not available, this function allow to manually poll the control register and simulate
@@ -295,7 +295,7 @@ void wfx_bh_poll_irq(struct wfx_dev *wdev)
        u32 reg;
 
        WARN(!wdev->poll_irq, "unexpected IRQ polling can mask IRQ");
-       flush_workqueue(system_highpri_wq);
+       flush_workqueue(wdev->bh_wq);
        start = ktime_get();
        for (;;) {
                wfx_control_reg_read(wdev, &reg);
index ae3cc5919dcd5d664d830f2d66a433bb59ba7c1c..2b92c227efbc633ca9b4c91855f8802d35699b81 100644 (file)
@@ -73,7 +73,7 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct wfx_hif_msg *request,
 
        if (no_reply) {
                /* Chip won't reply. Ensure the wq has send the buffer before to continue. */
-               flush_workqueue(system_highpri_wq);
+               flush_workqueue(wdev->bh_wq);
                ret = 0;
                goto end;
        }
index b93b16b900c8430070db5cfaf3bd05d3b7cb5448..bbfd3fa5192118c93ed404cd40518a4c42b9401f 100644 (file)
@@ -345,6 +345,10 @@ int wfx_probe(struct wfx_dev *wdev)
        wdev->pdata.gpio_wakeup = NULL;
        wdev->poll_irq = true;
 
+       wdev->bh_wq = alloc_workqueue("wfx_bh_wq", WQ_HIGHPRI, 0);
+       if (!wdev->bh_wq)
+               return -ENOMEM;
+
        wfx_bh_register(wdev);
 
        err = wfx_init_device(wdev);
@@ -458,6 +462,7 @@ int wfx_probe(struct wfx_dev *wdev)
        wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv);
 bh_unregister:
        wfx_bh_unregister(wdev);
+       destroy_workqueue(wdev->bh_wq);
        return err;
 }
 
@@ -467,6 +472,7 @@ void wfx_release(struct wfx_dev *wdev)
        wfx_hif_shutdown(wdev);
        wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv);
        wfx_bh_unregister(wdev);
+       destroy_workqueue(wdev->bh_wq);
 }
 
 static int __init wfx_core_init(void)
index 6594cc647c2f6892e3bc8e9be4bf55152cf4af23..6f5e95dae21f451acd598bd5ff215fe5f765c835 100644 (file)
@@ -57,6 +57,7 @@ struct wfx_dev {
        struct mutex               rx_stats_lock;
        struct wfx_hif_tx_power_loop_info tx_power_loop_info;
        struct mutex               tx_power_loop_info_lock;
+       struct workqueue_struct    *bh_wq;
 };
 
 struct wfx_vif {