From: Simon Horman <horms@kernel.org>
To: han.junyang@zte.com.cn
Cc: Simon Horman <horms@kernel.org>,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, ran.ming@zte.com.cn,
han.chengfei@zte.com.cn, zhang.yanze@zte.com.cn
Subject: Re: [PATCH net-next v2 2/3] dinghai: add MSI-X interrupt pools
Date: Mon, 14 Sep 2026 08:20:45 +0100 [thread overview]
Message-ID: <20260914072045.232985-1-horms@kernel.org> (raw)
In-Reply-To: <20260911120217310cUI5W_KC5mMJa9d1oIEnh@zte.com.cn>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev/#/patchset/20260911115929435mXJzcTF08xlUAdjnT8qqm@zte.com.cn?part=2
---
dinghai: add MSI-X interrupt pools
This commit introduces a driver for ZTE DingHai Ethernet, specifically
allocating the fixed MSI-X vector layout of the device. It manages the
vectors in per-purpose pools for async event queues and vq queue pairs.
[Severity: Medium]
The commit message states:
manage the vectors in per-purpose pools: one pool for the async event queues
and one for the vq queue pairs, with a range reserved for RDMA in between.
Was the VQ pool allocation omitted from this patch by mistake? Looking at
zxdh_pf_irq_pools_init(), only the async pool is allocated.
> diff --git a/drivers/net/ethernet/zte/dinghai/zxdh_irq.c b/drivers/net/ethernet/zte/dinghai/zxdh_irq.c
> new file mode 100644
> index 0000000000000..437344329c7e8
> --- /dev/null
> +++ b/drivers/net/ethernet/zte/dinghai/zxdh_irq.c
[ ... ]
> +static void zxdh_irq_release(struct kref *kref)
> +{
> + struct zxdh_irq *irq = container_of(kref, struct zxdh_irq, refcount);
> + struct zxdh_irq_pool *pool = irq->pool;
> +
> + lockdep_assert_held(&pool->lock);
> + xa_erase(&pool->irqs, irq->index);
> + /* free_irq() requires the affinity hint to be cleared before it is
> + * called; the asymmetry with the set path in zxdh_irq_alloc() is
> + * intentional.
> + */
> + irq_update_affinity_hint(irq->irqn, NULL);
> + free_cpumask_var(irq->mask);
> + free_irq(irq->irqn, irq);
> + kfree(irq);
> +}
[Severity: High]
Does this code leak the logical counters in pool->irqs_per_cpu?
When an IRQ is allocated, zxdh_irq_pool_request_irq() increments
pool->irqs_per_cpu[cpu]. It seems zxdh_irq_release() misses a call to
zxdh_cpu_put(), which will permanently skew load balancing and trigger the
WARN_ON(pool->irqs_per_cpu[cpu]) during zxdh_irq_pool_free().
[ ... ]
> +static struct zxdh_irq *zxdh_irq_alloc(struct zxdh_irq_pool *pool, int vecidx,
> + const struct cpumask *affinity)
> +{
> + struct zxdh_core_dev *zxdh_dev = pool->dev;
> + struct zxdh_irq *irq;
> + int err;
> + int cpu;
> +
> + irq = kzalloc_obj(*irq, GFP_KERNEL);
> + if (!irq)
> + return ERR_PTR(-ENOMEM);
> +
> + irq->pool = pool;
> + irq->irqn = pci_irq_vector(zxdh_dev->pdev, vecidx);
> + if (irq->irqn < 0) {
> + err = irq->irqn;
> + goto err_irqn;
> + }
> +
> + ATOMIC_INIT_NOTIFIER_HEAD(&irq->nh);
> + snprintf(irq->name, ZXDH_MAX_IRQ_NAME, "async_%d@pci:%s", vecidx,
> + pci_name(zxdh_dev->pdev));
[Severity: Low]
Is this hardcoded name prefix intentional?
This ignores the configured pool->name. If this generic library is reused for
other pools, such as the VQ pool, they will all show up as "async_" in
/proc/interrupts.
> +
> + err = request_irq(irq->irqn, zxdh_irq_int_handler, 0, irq->name, irq);
> + if (err) {
> + dev_err(zxdh_dev->device, "request_irq failed: %d\n", err);
> + goto err_irqn;
> + }
> +
> + if (!zalloc_cpumask_var(&irq->mask, GFP_KERNEL)) {
> + dev_err(zxdh_dev->device, "zalloc_cpumask_var failed\n");
> + err = -ENOMEM;
> + goto err_cpumask;
> + }
> +
> + if (affinity) {
> + cpumask_copy(irq->mask, affinity);
> + } else {
> + /* No preference requested; spread over all online CPUs. */
> + for_each_online_cpu(cpu)
> + cpumask_set_cpu(cpu, irq->mask);
> + }
> + irq_update_affinity_hint(irq->irqn, irq->mask);
[Severity: Medium]
Will this actually configure the SMP hardware routing for the IRQ?
The driver uses irq_update_affinity_hint() which only sets a userspace hint
via procfs. Should this be irq_set_affinity_and_hint() instead to actually
enforce the intended hardware IRQ load balancing?
[ ... ]
> +static struct zxdh_irq *zxdh_irq_pool_request_irq(struct zxdh_irq_pool *pool,
> + const struct cpumask *req_mask)
> +{
> + const struct cpumask *affinity = req_mask;
> + cpumask_var_t auto_mask;
> + struct zxdh_irq *irq;
> + u32 irq_index;
> + int err;
> +
> + if (!zalloc_cpumask_var(&auto_mask, GFP_KERNEL))
> + return ERR_PTR(-ENOMEM);
> +
> + err = xa_alloc(&pool->irqs, &irq_index, NULL, pool->xa_num_irqs,
> + GFP_KERNEL);
[Severity: High]
Will this xa_alloc() call fail unconditionally?
The XArray API strictly forbids NULL entries for allocation because NULL
represents an unallocated slot. Passing NULL as the entry triggers a
WARN_ON_ONCE(!entry) and returns -EINVAL.
[ ... ]
> +void zxdh_irq_pool_free(struct zxdh_irq_pool *pool)
> +{
> + struct zxdh_irq *irq;
> + unsigned long index;
> + u32 cpu;
> +
> + /* On a fast teardown the table may still hold IRQs; release
> + * whatever is left.
> + */
> + mutex_lock(&pool->lock);
> + xa_for_each(&pool->irqs, index, irq)
> + zxdh_irq_release(&irq->refcount);
> + mutex_unlock(&pool->lock);
[Severity: High]
Can this manual iteration bypass the reference counting and cause a
use-after-free?
If zxdh_irq_pool_free() executes while active consumers still hold an IRQ
reference during a fast teardown, it will forcefully execute
zxdh_irq_release() on the irq object. When the consumer eventually calls
zxdh_irq_put() and accesses the freed irq and its freed pool->lock, will
this trigger a use-after-free?
[ ... ]
next prev parent reply other threads:[~2026-09-14 7:20 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 3:56 [PATCH net-next v2 0/3] dinghai: firmware handshake, MSI-X pools and async event queues han.junyang
2026-09-11 3:59 ` [PATCH net-next v2 1/3] dinghai: add firmware version check and RISC-V readiness polling han.junyang
2026-09-14 7:20 ` Simon Horman
2026-09-11 4:02 ` [PATCH net-next v2 2/3] dinghai: add MSI-X interrupt pools han.junyang
2026-09-14 7:20 ` Simon Horman [this message]
2026-09-11 4:05 ` [PATCH net-next v2 3/3] dinghai: add async event queue for firmware notifications han.junyang
2026-09-14 7:20 ` Simon Horman
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=20260914072045.232985-1-horms@kernel.org \
--to=horms@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=han.chengfei@zte.com.cn \
--cc=han.junyang@zte.com.cn \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=ran.ming@zte.com.cn \
--cc=zhang.yanze@zte.com.cn \
/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
all inboxes | Powered by JetHome®