From: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
To: Karthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com>,
P Praneesh <praneesh.p@oss.qualcomm.com>,
ath12k@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Subject: Re: [PATCH ath-next] wifi: ath12k: fix IRQ disable imbalance in AHB ext interrupt handler
Date: Tue, 27 Oct 2026 11:29:26 -0700 [thread overview]
Message-ID: <d3f34291-bed2-4ddd-af2f-fd994a2d409f@oss.qualcomm.com> (raw)
In-Reply-To: <5e64ab52-c8b3-4b42-81b1-dea844bea6d9@oss.qualcomm.com>
On 10/20/2026 10:07 PM, Karthikeyan Periyasamy wrote:
>
>
> On 10/15/2026 2:14 PM, P Praneesh wrote:
>> 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
>
> Reviewed-by: Karthikeyan Periyasamy
> <karthikeyan.periyasamy@oss.qualcomm.com>
>
I think you meant...
Reviewed-by: Karthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com>
by posting that my tooling will now pick it up.
/jeff
next prev parent reply other threads:[~2026-10-27 18:29 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 8:44 [PATCH ath-next] wifi: ath12k: fix IRQ disable imbalance in AHB ext interrupt handler P Praneesh
2026-10-21 5:07 ` Karthikeyan Periyasamy
2026-10-27 18:29 ` Jeff Johnson [this message]
2026-10-27 8:43 ` Baochen Qiang
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=d3f34291-bed2-4ddd-af2f-fd994a2d409f@oss.qualcomm.com \
--to=jeff.johnson@oss.qualcomm.com \
--cc=ath12k@lists.infradead.org \
--cc=karthikeyan.periyasamy@oss.qualcomm.com \
--cc=linux-wireless@vger.kernel.org \
--cc=praneesh.p@oss.qualcomm.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