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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.