From 4f7f3baa461c124c4bb999a8d5e4265b3d82ccfe Mon Sep 17 00:00:00 2001 From: Hangtian Zhu Date: Tue, 12 May 2026 10:17:08 +0800 Subject: [PATCH 1/2] FROMLIST: genirq: export irq_can_set_affinity() for module drivers Export irq_can_set_affinity() for loadable drivers that need a runtime check for IRQ affinity capability. In hierarchical IRQ setups where the effective irqchip path lacks .irq_set_affinity(), drivers may need to switch to a fallback policy. Without this export, module drivers cannot use the core helper and have to open-code equivalent checks. Signed-off-by: Hangtian Zhu Link: https://lore.kernel.org/all/20260519011627.713068-1-hangtian.zhu@oss.qualcomm.com/ --- kernel/irq/manage.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index c09751b7a0c49..e1875dc5c1dd8 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -159,6 +159,7 @@ int irq_can_set_affinity(unsigned int irq) { return __irq_can_set_affinity(irq_to_desc(irq)); } +EXPORT_SYMBOL_GPL(irq_can_set_affinity); /** * irq_can_set_affinity_usr - Check if affinity of a irq can be set from user space From 36101204d792aab9d8eb448e90468bcb85f585df Mon Sep 17 00:00:00 2001 From: Hangtian Zhu Date: Tue, 12 May 2026 10:17:08 +0800 Subject: [PATCH 2/2] FROMLIST: wifi: ath12k: enable threaded NAPI when DP IRQ affinity is unavailable Determine threaded NAPI policy from runtime IRQ capability of the DP MSI IRQ. If irq_can_set_affinity() reports that affinity cannot be set, enable threaded NAPI for DP interrupt groups so datapath processing is not constrained by a single-CPU softirq context. On RB3Gen2, where IRQ affinity is unavailable in the effective IRQ path, EHT160 UDP downlink throughput improved from 802 Mbps to 2.58 Gbps after enabling threaded NAPI. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0.c2-00074-QCACOLSWPL_V1_TO_SILICONZ-1 Signed-off-by: Hangtian Zhu Link: https://lore.kernel.org/all/20260519011627.713068-1-hangtian.zhu@oss.qualcomm.com/ --- drivers/net/wireless/ath/ath12k/pci.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 375277ca2b892..065449806ea9b 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -537,6 +538,8 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab) int i, j, n, ret, num_vectors = 0; u32 user_base_data = 0, base_vector = 0, base_idx; struct ath12k_ext_irq_grp *irq_grp; + bool threaded_napi = false; + int irq; base_idx = ATH12K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX; ret = ath12k_pci_get_user_msi_assignment(ab, "DP", @@ -546,6 +549,10 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab) if (ret < 0) return ret; + irq = ath12k_pci_get_msi_irq(ab->dev, base_vector); + if (irq >= 0) + threaded_napi = !irq_can_set_affinity(irq); + for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { irq_grp = &ab->ext_irq_grp[i]; u32 num_irq = 0; @@ -560,6 +567,8 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab) netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi, ath12k_pci_ext_grp_napi_poll); + if (threaded_napi) + netif_threaded_enable(irq_grp->napi_ndev); if (ab->hw_params->ring_mask->tx[i] || ab->hw_params->ring_mask->rx[i] || @@ -578,7 +587,7 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab) for (j = 0; j < irq_grp->num_irq; j++) { int irq_idx = irq_grp->irqs[j]; int vector = (i % num_vectors) + base_vector; - int irq = ath12k_pci_get_msi_irq(ab->dev, vector); + irq = ath12k_pci_get_msi_irq(ab->dev, vector); ab->irq_num[irq_idx] = irq;