Netdev List
 help / color / mirror / Atom feed
From: Myeonghun Pak <mhun512@gmail.com>
To: Ido Schimmel <idosch@nvidia.com>, Petr Machata <petrm@nvidia.com>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S . Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	kernel test robot <lkp@intel.com>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Myeonghun Pak <mhun512@gmail.com>, Ijae Kim <ae878000@gmail.com>
Subject: [PATCH net v2] mlxsw: pci: Quiesce EQ tasklet and CQ NAPI before teardown
Date: Tue, 21 Jul 2026 21:57:53 +0900	[thread overview]
Message-ID: <20260721125753.35944-1-mhun512@gmail.com> (raw)

mlxsw_pci_eq_irq_handler() schedules the EQ tasklet. The tasklet reads
the EQ ring and schedules CQ NAPI instances. The CQ poll callbacks, in
turn, dereference the RDQ or SDQ associated with the CQ.

mlxsw_pci_fini() unregisters the IRQ and immediately tears down the
asynchronous queues in RDQ, SDQ, CQ, EQ order. free_irq() waits for IRQ
handlers, but not for a tasklet already scheduled by one. In addition,
mlxsw_pci_cq_fini() disables each CQ NAPI only after all RDQs and SDQs
have been freed. A pending tasklet or NAPI poll can therefore access
freed queue storage.

Kill the EQ tasklet after free_irq() so it cannot schedule any more CQ
NAPI instances. Disable all CQ NAPI instances before freeing the first
descriptor queue, ensuring their poll callbacks have completed. Track
the enabled state per CQ to avoid disabling a NAPI instance twice when
the CQ is later destroyed, while preserving the partial initialization
unwind.

Fixes: eda6500a987a ("mlxsw: Add PCI bus implementation")
Cc: stable@vger.kernel.org
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
---
v2:
- Fix typo in napi_enabled assignment reported by kernel test robot.

v1: https://lore.kernel.org/r/20260721062105.55014-1-mhun512@gmail.com/

Found by static analysis on v7.2-rc2; not tested on hardware.

 drivers/net/ethernet/mellanox/mlxsw/pci.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index 0da85d36647d..feeb32134d2a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -86,6 +86,7 @@ struct mlxsw_pci_queue {
 			enum mlxsw_pci_cqe_v v;
 			struct mlxsw_pci_queue *dq;
 			struct napi_struct napi;
+			bool napi_enabled;
 			struct page_pool *page_pool;
 		} cq;
 		struct {
@@ -989,6 +990,15 @@ static void mlxsw_pci_cq_napi_teardown(struct mlxsw_pci_queue *q)
 	netif_napi_del(&q->u.cq.napi);
 }
 
+static void mlxsw_pci_cq_napi_disable(struct mlxsw_pci_queue *q)
+{
+	if (!q->u.cq.napi_enabled)
+		return;
+
+	napi_disable(&q->u.cq.napi);
+	q->u.cq.napi_enabled = false;
+}
+
 static int mlxsw_pci_cq_page_pool_init(struct mlxsw_pci_queue *q,
 				       enum mlxsw_pci_cq_type cq_type)
 {
@@ -1064,6 +1074,7 @@ static int mlxsw_pci_cq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
 		goto err_page_pool_init;
 
 	napi_enable(&q->u.cq.napi);
+	q->u.cq.napi_enabled = true;
 	mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q);
 	mlxsw_pci_queue_doorbell_arm_consumer_ring(mlxsw_pci, q);
 	return 0;
@@ -1078,7 +1089,7 @@ static void mlxsw_pci_cq_fini(struct mlxsw_pci *mlxsw_pci,
 {
 	enum mlxsw_pci_cq_type cq_type = mlxsw_pci_cq_type(mlxsw_pci, q);
 
-	napi_disable(&q->u.cq.napi);
+	mlxsw_pci_cq_napi_disable(q);
 	mlxsw_pci_cq_page_pool_fini(q, cq_type);
 	mlxsw_pci_cq_napi_teardown(q);
 	mlxsw_cmd_hw2sw_cq(mlxsw_pci->core, q->num);
@@ -1439,6 +1450,14 @@ err_cqs_init:
 
 static void mlxsw_pci_aqs_fini(struct mlxsw_pci *mlxsw_pci)
 {
+	struct mlxsw_pci_queue_type_group *queue_group;
+	int i;
+
+	queue_group = mlxsw_pci_queue_type_group_get(mlxsw_pci,
+						     MLXSW_PCI_QUEUE_TYPE_CQ);
+	for (i = 0; i < queue_group->count; i++)
+		mlxsw_pci_cq_napi_disable(&queue_group->q[i]);
+
 	mlxsw_pci_queue_group_fini(mlxsw_pci, &mlxsw_pci_rdq_ops);
 	mlxsw_pci_queue_group_fini(mlxsw_pci, &mlxsw_pci_sdq_ops);
 	mlxsw_pci_queue_group_fini(mlxsw_pci, &mlxsw_pci_cq_ops);
@@ -2089,6 +2108,7 @@ static void mlxsw_pci_fini(void *bus_priv)
 	struct mlxsw_pci *mlxsw_pci = bus_priv;
 
 	free_irq(pci_irq_vector(mlxsw_pci->pdev, 0), mlxsw_pci);
+	tasklet_kill(&mlxsw_pci_eq_get(mlxsw_pci)->u.eq.tasklet);
 	mlxsw_pci_aqs_fini(mlxsw_pci);
 	mlxsw_pci_napi_devs_fini(mlxsw_pci);
 	mlxsw_pci_fw_area_fini(mlxsw_pci);
-- 
2.47.1

             reply	other threads:[~2026-07-21 12:58 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-21 12:57 Myeonghun Pak [this message]
2026-07-22  9:20 ` [PATCH net v2] mlxsw: pci: Quiesce EQ tasklet and CQ NAPI before teardown Petr Machata
2026-07-22 10:07 ` Petr Machata

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260721125753.35944-1-mhun512@gmail.com \
    --to=mhun512@gmail.com \
    --cc=ae878000@gmail.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=idosch@nvidia.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=petrm@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox