Linux wireless drivers development
 help / color / mirror / Atom feed
From: P Praneesh <praneesh.p@oss.qualcomm.com>
To: ath12k@lists.infradead.org
Cc: linux-wireless@vger.kernel.org, praneesh.p@oss.qualcomm.com
Subject: [PATCH ath-next] wifi: ath12k: fix IRQ disable imbalance in AHB ext interrupt handler
Date: Thu, 15 Oct 2026 14:14:45 +0530	[thread overview]
Message-ID: <20261015084445.3045925-1-praneesh.p@oss.qualcomm.com> (raw)

On AHB platforms such as IPQ5332, IRQ group 3 maps multiple hardware
rings to a single NAPI instance. Each ring is assigned its own IRQ
line, but all IRQs in the group share one napi struct and one poll
function.

When two IRQs from the same group fire simultaneously on different
CPUs, both handlers call ath12k_ahb_ext_grp_disable(), which invokes
disable_irq_nosync() for every IRQ in the group. This increments the
interrupt controller's disable reference count for each IRQ twice. The
single NAPI poll that runs calls ath12k_ahb_ext_grp_enable() once,
decrementing each count from 2 to 1. Because the count never reaches 0,
all IRQs in the group remain permanently masked by the interrupt
controller.

With no further interrupts, TX completions stop being reaped from the
WBM release ring. The pending TX descriptor count grows until the WBM
idle link descriptor pool is exhausted. Once full, TX ring allocation
fails and no new packets including management frames can be enqueued.
This causes stations to disassociate with reason 34 (DISASSOC_LOW_ACK)
and ath12k_mac_flush() to time out:
"failed to flush transmit queue, data pkts req N pending N"
where N equals ATH12K_NUM_POOL_TX_DESC(ab).

Fix this by using napi_schedule_prep() to atomically test-and-set
NAPI_STATE_SCHED before disabling IRQs. Only the first CPU to win the
atomic operation disables the group and calls __napi_schedule(). Any
concurrent handler that loses the race skips the disable entirely,
keeping the reference count balanced. Guard the enable_irq() call in
the poll routine with the return value of napi_complete_done() to
prevent an unbalanced enable if the NAPI instance was re-scheduled
before the poll completed.

Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.7-00587-QCAHKSWPL_SILICONZ-1

Fixes: 6cee30f0da75 ("wifi: ath12k: add AHB driver support for IPQ5332")
Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/ahb.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
index 2c55aae06dd0..e5bbfca2b2ac 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.c
+++ b/drivers/net/wireless/ath/ath12k/ahb.c
@@ -602,8 +602,8 @@ static int ath12k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget)
 
 	work_done = ath12k_dp_service_srng(dp, irq_grp, budget);
 	if (work_done < budget) {
-		napi_complete_done(napi, work_done);
-		ath12k_ahb_ext_grp_enable(irq_grp);
+		if (likely(napi_complete_done(napi, work_done)))
+			ath12k_ahb_ext_grp_enable(irq_grp);
 	}
 
 	if (work_done > budget)
@@ -619,9 +619,10 @@ static irqreturn_t ath12k_ahb_ext_interrupt_handler(int irq, void *arg)
 	/* last interrupt received for this group */
 	irq_grp->timestamp = jiffies;
 
-	ath12k_ahb_ext_grp_disable(irq_grp);
-
-	napi_schedule(&irq_grp->napi);
+	if (napi_schedule_prep(&irq_grp->napi)) {
+		ath12k_ahb_ext_grp_disable(irq_grp);
+		__napi_schedule(&irq_grp->napi);
+	}
 
 	return IRQ_HANDLED;
 }

base-commit: cd026e68fdbf88b9cc522b76c7a9d92c9a41f709
-- 
2.43.0


             reply	other threads:[~2026-10-15  8:45 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-15  8:44 P Praneesh [this message]
2026-10-21  5:07 ` [PATCH ath-next] wifi: ath12k: fix IRQ disable imbalance in AHB ext interrupt handler Karthikeyan Periyasamy
2026-10-27 18:29   ` Jeff Johnson
2026-10-27  8:43 ` Baochen Qiang
2026-10-29 22:56 ` Jeff Johnson

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=20261015084445.3045925-1-praneesh.p@oss.qualcomm.com \
    --to=praneesh.p@oss.qualcomm.com \
    --cc=ath12k@lists.infradead.org \
    --cc=linux-wireless@vger.kernel.org \
    /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