]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
eth: bnxt: fix deadlock in the mgmt_ops
authorTaehee Yoo <ap420073@gmail.com>
Wed, 2 Apr 2025 13:31:23 +0000 (13:31 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 3 Apr 2025 22:10:52 +0000 (15:10 -0700)
When queue is being reset, callbacks of mgmt_ops are called by
netdev_nl_bind_rx_doit().
The netdev_nl_bind_rx_doit() first acquires netdev_lock() and then calls
callbacks.
So, mgmt_ops callbacks should not acquire netdev_lock() internaly.

The bnxt_queue_{start | stop}() calls napi_{enable | disable}() but they
internally acquire netdev_lock().
So, deadlock occurs.

To avoid deadlock, napi_{enable | disable}_locked() should be used
instead.

Signed-off-by: Taehee Yoo <ap420073@gmail.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Fixes: cae03e5bdd9e ("net: hold netdev instance lock during queue operations")
Link: https://patch.msgid.link/20250402133123.840173-1-ap420073@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/bnxt/bnxt.c

index 1a70605fad388afc992464012395445e95278a1e..28ee12186c375b6efa59e5ba3f2a32a557365f28 100644 (file)
@@ -15909,7 +15909,7 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
                        goto err_reset;
        }
 
-       napi_enable(&bnapi->napi);
+       napi_enable_locked(&bnapi->napi);
        bnxt_db_nq_arm(bp, &cpr->cp_db, cpr->cp_raw_cons);
 
        for (i = 0; i < bp->nr_vnics; i++) {
@@ -15931,7 +15931,7 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
 err_reset:
        netdev_err(bp->dev, "Unexpected HWRM error during queue start rc: %d\n",
                   rc);
-       napi_enable(&bnapi->napi);
+       napi_enable_locked(&bnapi->napi);
        bnxt_db_nq_arm(bp, &cpr->cp_db, cpr->cp_raw_cons);
        bnxt_reset_task(bp, true);
        return rc;
@@ -15971,7 +15971,7 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx)
         * completion is handled in NAPI to guarantee no more DMA on that ring
         * after seeing the completion.
         */
-       napi_disable(&bnapi->napi);
+       napi_disable_locked(&bnapi->napi);
 
        if (bp->tph_mode) {
                bnxt_hwrm_cp_ring_free(bp, rxr->rx_cpr);