From: mingming cao <mmc@linux.ibm.com>
To: Jakub Kicinski <kuba@kernel.org>
Cc: netdev@vger.kernel.org, davem@davemloft.net, edumazet@google.com,
pabeni@redhat.com, andrew+netdev@lunn.ch, nnac123@linux.ibm.com,
maddy@linux.ibm.com, mpe@ellerman.id.au,
linuxppc-dev@lists.ozlabs.org, haren@linux.ibm.com,
ricklind@linux.ibm.com, davemarq@linux.ibm.com,
bjking1@linux.ibm.com, shaik.abdulla1@ibm.com
Subject: Re: [PATCH net-next v5 04/15] ibmveth: Refactor buffer pool management for per-queue MQ RX
Date: Mon, 31 Aug 2026 11:20:49 -0700 [thread overview]
Message-ID: <ca132b73-5fd9-428f-af41-cfabedf0e0b4@linux.ibm.com> (raw)
In-Reply-To: <20260818014721.3854017-1-kuba@kernel.org>
On 8/17/26 6:47 PM, Jakub Kicinski wrote:
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> ---
> ibmveth: Refactor buffer pool management for per-queue MQ RX
>
> This moves the five RX buffer pools to a per-queue array and introduces
> ibmveth_alloc_buffer_pools() / ibmveth_free_buffer_pools() plus the
> per-queue helpers, wiring them into open() and close(). Queue 0 stays the
> template for pool geometry and activation, and runtime is still
> single-queue.
>
> A few questions below about the new unwind paths and about two of the
> new comments.
>
>> diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
>> index 168940bfa1094..1a428ee60d58c 100644
>> --- a/drivers/net/ethernet/ibm/ibmveth.c
>> +++ b/drivers/net/ethernet/ibm/ibmveth.c
>> @@ -627,6 +627,142 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter,
>> }
>> }
>>
>> +/**
>> + * ibmveth_free_queue_buffer_pools - Free buffer pools for a single queue
> [ ... ]
>
>> +/**
>> + * ibmveth_alloc_queue_buffer_pools - Allocate buffer pools for a single queue
>> + * @adapter: ibmveth adapter structure
>> + * @queue: queue index
>> + *
>> + * Allocates backing storage for each active pool on @queue.
>> + * Inactive pools (!active) are skipped. Pool metadata must be
>> + * initialized before calling this function.
>> + *
>> + * Return: 0 on success, negative error code on failure
>> + */
>> +static int ibmveth_alloc_queue_buffer_pools(struct ibmveth_adapter *adapter,
>> + int queue)
>> +{
>> + struct net_device *netdev = adapter->netdev;
>> + int i;
>> +
>> + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
>> + struct ibmveth_buff_pool *bpool =
>> + &adapter->rx_buff_pool[queue][i];
>> +
>> + if (!bpool->active)
>> + continue;
>> +
>> + if (ibmveth_alloc_buffer_pool(bpool)) {
>> + netdev_err(netdev,
>> + "queue %d pool %d alloc failed (size=%u count=%u)\n",
>> + queue, i,
>> + bpool->buff_size,
>> + bpool->size);
>> + bpool->active = 0;
>> + /* Free by allocation presence, not active — the
>> + * failing pool cleared active first and would be
>> + * skipped by an active-only unwind.
>> + */
> [Severity: Low]
> Is the stated rationale in this comment accurate? Freeing by allocation
> presence is a fine policy for the later resize paths, but the specific
> claim that an active-only unwind would skip the failing pool and leak it
> does not seem to hold here, because ibmveth_alloc_buffer_pool() already
> undoes its own partial allocations before returning -1:
>
> drivers/net/ethernet/ibm/ibmveth.c:ibmveth_alloc_buffer_pool() {
> pool->dma_addr = kzalloc_objs(dma_addr_t, pool->size);
> if (!pool->dma_addr) {
> kfree(pool->free_map);
> pool->free_map = NULL;
> return -1;
> }
>
> pool->skbuff = kcalloc(pool->size, sizeof(void *), GFP_KERNEL);
>
> if (!pool->skbuff) {
> kfree(pool->dma_addr);
> pool->dma_addr = NULL;
>
> kfree(pool->free_map);
> pool->free_map = NULL;
> return -1;
> }
> ...
> }
>
> By the time bpool->active = 0 runs, free_map/dma_addr/skbuff are all NULL
> for the failing pool, so there is nothing for an active-only unwind to
> miss. The same claim appears in the changelog ("v4 fail path freed by
> active and skipped the failing pool", "open-fail cannot leak partially
> allocated pools"). Could the comment and changelog instead justify
> free-by-presence purely in terms of the later resize paths?
Agreed. v6 retargets the comment and changelog to the later resize
paths. Policy is unchanged.
>> + ibmveth_free_queue_buffer_pools(adapter, queue);
>> + return -ENOMEM;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
> [ ... ]
>
>> + /* Allocate actual buffers for all queues */
>> + for (q = 0; q < adapter->num_rx_queues; q++) {
>> + rc = ibmveth_alloc_queue_buffer_pools(adapter, q);
>> + if (rc) {
>> + /* Free pools for all previous queues */
>> + while (--q >= 0)
>> + ibmveth_free_queue_buffer_pools(adapter, q);
>> + return rc;
>> + }
>> + }
>> +
>> + netdev_dbg(netdev, "allocated buffer pools for %d queue(s)\n",
>> + adapter->num_rx_queues);
> [Severity: Low]
> This isn't a bug, but adapter->num_rx_queues is declared as
> "unsigned int num_rx_queues;" in drivers/net/ethernet/ibm/ibmveth.h, so
> should these two new messages use %u rather than %d? The same applies to
> the netdev_dbg() in ibmveth_free_buffer_pools() below.
Yes, Both count prints use %u in v6.
>> + return 0;
>> +}
>> +
>> +/**
>> + * ibmveth_free_buffer_pools - Free buffer pools for all queues
>> + * @adapter: ibmveth adapter structure
>> + *
>> + * Frees buffer pools for all queues using the helper function.
>> + */
>> +static void
>> +ibmveth_free_buffer_pools(struct ibmveth_adapter *adapter)
>> +{
>> + int q;
>> +
>> + /* Free buffer pools for all queues */
>> + for (q = 0; q < adapter->num_rx_queues; q++)
>> + ibmveth_free_queue_buffer_pools(adapter, q);
>> +
>> + netdev_dbg(adapter->netdev, "freed buffer pools for %d queue(s)\n",
>> + adapter->num_rx_queues);
>> +}
>> +
>> /**
>> * ibmveth_remove_buffer_from_pool - remove a buffer from a pool
>> * @adapter: adapter instance
>> @@ -851,16 +987,9 @@ static int ibmveth_open(struct net_device *netdev)
>> goto out_free_tx_ltb;
>> }
>>
>> - for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
>> - if (!adapter->rx_buff_pool[0][i].active)
>> - continue;
>> - if (ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[0][i])) {
>> - netdev_err(netdev, "unable to alloc pool\n");
>> - adapter->rx_buff_pool[0][i].active = 0;
>> - rc = -ENOMEM;
>> - goto out_free_buffer_pools;
>> - }
>> - }
>> + rc = ibmveth_alloc_buffer_pools(adapter);
>> + if (rc)
>> + goto out_free_tx_ltb;
> [Severity: Medium]
> This isn't a gap introduced by this patch (the old inline pool loop fell
> through to the same labels), but since the edge is being rewritten here:
> this goto is taken after ibmveth_register_logical_lan() has already
> succeeded, and the unwind it lands on never issues h_free_logical_lan():
>
> out_free_tx_ltb:
> while (--i >= 0)
> ibmveth_free_tx_ltb(adapter, i);
> ibmveth_cleanup_rx_resources(adapter);
> out_free_filter_list:
> ibmveth_free_filter_list(adapter);
>
> ibmveth_cleanup_rx_resources() does the dma_unmap_single() of
> buffer_list_dma[], the dma_free_coherent() of the RX completion queue and
> the free_page() of the buffer-list page, and ibmveth_free_filter_list()
> releases the filter list, all while PHYP still holds those addresses. The
> adjacent request_irq() failure path does perform the handshake the driver
> otherwise considers mandatory:
>
> do {
> lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
> } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY));
>
> Can PHYP write the rx_no_buffer counter into the freed buffer-list page, or
> post a completion into the freed RX queue, after this path returns? The
> h_vio_signal(VIO_IRQ_DISABLE) issued just before registration also is not
> rebalanced here.
>
> Later patches in this series do repair this: "ibmveth: Refactor TX resource
> allocation in open/close paths" retargets this edge to out_unregister_lan,
> and by the end of the series ibmveth_open() allocates the pools before
> ibmveth_register_rx_queues() and routes post-registration failures through
> ibmveth_free_all_queues() -> h_free_logical_lan(). Would it be reasonable
> to point this goto at a label that unregisters the logical LAN already in
> this patch, so the intermediate commit is not bisect-visible?
Yes it can, at this point. Not retargeted here: the missing hcall
belongs with the TX open/close unwind (patch 6), and pools-before-
register is the register-helpers patch (7). Pointing this goto at a
new unregister label here would just be removed again in patch 6 when
out_unregister_lan replaces it — churn for no net gain. The
intermediate state is real but not a bisect hazard: num_rx_queues is
still 1 and this path is only reachable after a successful
h_register_logical_lan(), which is the same exposure the baseline had.
>>
>> netdev_dbg(netdev, "registering irq 0x%x\n", netdev->irq);
>> rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name,
>> @@ -885,11 +1014,7 @@ static int ibmveth_open(struct net_device *netdev)
>> return 0;
>>
>> out_free_buffer_pools:
>> - while (--i >= 0) {
>> - if (adapter->rx_buff_pool[0][i].active)
>> - ibmveth_free_buffer_pool(adapter,
>> - &adapter->rx_buff_pool[0][i]);
>> - }
>> + ibmveth_free_buffer_pools(adapter);
>> out_free_tx_ltb:
>> while (--i >= 0)
>> ibmveth_free_tx_ltb(adapter, i);
> [Severity: Medium]
> This is a pre-existing issue rather than one introduced here, but does this
> hunk silently fix a TX long-term-buffer leak?
>
> In the parent commit the pool unwind consumed i:
>
> out_free_buffer_pools:
> while (--i >= 0) {
> if (adapter->rx_buff_pool[0][i].active)
> ibmveth_free_buffer_pool(adapter,
> &adapter->rx_buff_pool[0][i]);
> }
> out_free_tx_ltb:
> while (--i >= 0)
> ibmveth_free_tx_ltb(adapter, i);
>
> so on reaching out_free_tx_ltb by fall-through, i was already -1 and the
> first test of --i evaluated to -2, meaning no tx_ltb_ptr[]/tx_ltb_dma[]
> buffer was released. With the pool unwind now a helper call that does not
> touch i, i still holds the TX queue count from the completed TX allocation
> loop, so the TX LTBs are freed.
>
> Every PAGE_ALIGN(IBMVETH_MAX_TX_BUF_SIZE) TX buffer plus its DMA mapping was
> leaked on each failing open, and it repeats per attempt ("ip link set <dev>
> up" under memory pressure, or the close+open pair inside veth_pool_store(),
> ibmveth_change_mtu() and ibmveth_reset()).
>
> Would it make sense to split this out as its own patch with a Fixes: tag so
> stable trees pick it up, or at least describe it in the changelog?
Yes, as a side effect of pulling the pool loop out. v6 names it in the
commit message. Not split out: adding it at the head would make the
series 16 patches, exceeding the netdev limit.
Thanks,
Mingming
next prev parent reply other threads:[~2026-08-31 18:21 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 7:36 [PATCH net-next v5 00/15] ibmveth: Add multi-queue RX support Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 01/15] ibmveth: Add MQ RX hypercall wrappers and call definitions Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 17:58 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 02/15] ibmveth: Prepare MQ RX adapter data structures Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 18:03 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 03/15] ibmveth: Refactor RX resource allocation for MQ RX bring-up Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 18:12 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 04/15] ibmveth: Refactor buffer pool management for per-queue MQ RX Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 18:20 ` mingming cao [this message]
2026-08-14 7:36 ` [PATCH net-next v5 05/15] ibmveth: Refactor RX interrupt control for MQ RX queues Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 18:24 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 06/15] ibmveth: Refactor TX resource allocation in open/close paths Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 18:46 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 07/15] ibmveth: Add RX queue register helpers for MQ Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 18:54 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 08/15] ibmveth: Add queue-aware RX buffer submit helper " Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 19:00 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 09/15] ibmveth: Harden RX poll path with helpers Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 19:06 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 10/15] ibmveth: Enable multi-queue RX receive path Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 19:10 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 11/15] ibmveth: Add per-queue RX and TX statistics collection Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 19:12 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 12/15] ibmveth: Report MQ-aware RX counts in ethtool get_channels Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 19:19 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 13/15] ibmveth: Expose per-queue buffer pool details via debugfs Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 19:20 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 14/15] ibmveth: Implement incremental MQ RX queue resize Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 19:22 ` mingming cao
2026-08-14 7:36 ` [PATCH net-next v5 15/15] ibmveth: Wire ethtool set_channels to " Mingming Cao
2026-08-18 1:47 ` Jakub Kicinski
2026-08-31 19:24 ` mingming cao
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=ca132b73-5fd9-428f-af41-cfabedf0e0b4@linux.ibm.com \
--to=mmc@linux.ibm.com \
--cc=andrew+netdev@lunn.ch \
--cc=bjking1@linux.ibm.com \
--cc=davem@davemloft.net \
--cc=davemarq@linux.ibm.com \
--cc=edumazet@google.com \
--cc=haren@linux.ibm.com \
--cc=kuba@kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=mpe@ellerman.id.au \
--cc=netdev@vger.kernel.org \
--cc=nnac123@linux.ibm.com \
--cc=pabeni@redhat.com \
--cc=ricklind@linux.ibm.com \
--cc=shaik.abdulla1@ibm.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