From: Simon Horman <horms@kernel.org>
To: Mingming Cao <mmc@linux.ibm.com>
Cc: netdev@vger.kernel.org, bjking1@linux.ibm.com,
haren@linux.ibm.com, ricklind@linux.ibm.com, kuba@kernel.org,
edumazet@google.com, pabeni@redhat.com,
linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com,
mpe@ellerman.id.au, Dave Marquardt <davemarq@linux.ibm.com>
Subject: Re: [PATCH net-next v3 08/15] ibmveth: Refactor open/close into MQ-ready resource pipeline
Date: Tue, 14 Jul 2026 13:47:36 +0100 [thread overview]
Message-ID: <20260714124736.GK1364329@horms.kernel.org> (raw)
In-Reply-To: <20260706193603.8039-9-mmc@linux.ibm.com>
On Mon, Jul 06, 2026 at 12:35:56PM -0700, Mingming Cao wrote:
...
> diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
...
> /**
> * ibmveth_register_logical_lan_queue - Register subordinate queue with hypervisor
> * @adapter: ibmveth adapter structure
> @@ -1466,208 +1479,108 @@ ibmveth_register_rx_queues(struct ibmveth_adapter *adapter, u64 mac_address)
> static int ibmveth_open(struct net_device *netdev)
> {
> struct ibmveth_adapter *adapter = netdev_priv(netdev);
> - u64 mac_address;
> + u64 mac_address = ether_addr_to_u64(netdev->dev_addr);
> int rxq_entries = 1;
> - unsigned long lpar_rc;
> int rc;
> - union ibmveth_buf_desc rxq_desc;
> int i;
> - struct device *dev;
>
> netdev_dbg(netdev, "open starting\n");
>
> - napi_enable(&adapter->napi[0]);
> -
> - for(i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
> + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
> rxq_entries += adapter->rx_buff_pool[0][i].size;
>
> - rc = -ENOMEM;
> - adapter->buffer_list_addr[0] = (void *)get_zeroed_page(GFP_KERNEL);
> - if (!adapter->buffer_list_addr[0]) {
> - netdev_err(netdev, "unable to allocate list pages\n");
> + rc = ibmveth_alloc_rx_qstats(adapter);
> + if (rc)
> goto out;
> - }
>
> - adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
> - if (!adapter->filter_list_addr) {
> - netdev_err(netdev, "unable to allocate filter pages\n");
> - goto out_free_buffer_list;
> - }
> -
> - dev = &adapter->vdev->dev;
> + rc = ibmveth_alloc_filter_list(adapter);
> + if (rc)
> + goto out_free_rx_qstats;
>
> - adapter->rx_queue[0].queue_len = sizeof(struct ibmveth_rx_q_entry) *
> - rxq_entries;
> - adapter->rx_queue[0].queue_addr =
> - dma_alloc_coherent(dev, adapter->rx_queue[0].queue_len,
> - &adapter->rx_queue[0].queue_dma, GFP_KERNEL);
> - if (!adapter->rx_queue[0].queue_addr)
> + rc = ibmveth_alloc_rx_queues(adapter, rxq_entries);
> + if (rc)
> goto out_free_filter_list;
>
> - adapter->buffer_list_dma[0] = dma_map_single(dev,
> - adapter->buffer_list_addr[0],
> - 4096, DMA_BIDIRECTIONAL);
> - if (dma_mapping_error(dev, adapter->buffer_list_dma[0])) {
> - netdev_err(netdev, "unable to map buffer list pages\n");
> + rc = ibmveth_alloc_buffer_pools(adapter);
> + if (rc)
> goto out_free_queue_mem;
> - }
>
> - adapter->filter_list_dma = dma_map_single(dev,
> - adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL);
> - if (dma_mapping_error(dev, adapter->filter_list_dma)) {
> - netdev_err(netdev, "unable to map filter list pages\n");
> - goto out_unmap_buffer_list;
> - }
> + rc = ibmveth_register_rx_queues(adapter, mac_address);
> + if (rc)
> + goto out_free_buffer_pools;
>
> - for (i = 0; i < netdev->real_num_tx_queues; i++) {
> - if (ibmveth_allocate_tx_ltb(adapter, i))
> - goto out_free_tx_ltb;
> + rc = netif_set_real_num_rx_queues(netdev, adapter->num_rx_queues);
> + if (rc) {
> + netdev_err(netdev, "failed to set number of rx queues\n");
> + goto out_unregister_queues;
> }
>
> - adapter->rx_queue[0].index = 0;
> - adapter->rx_queue[0].num_slots = rxq_entries;
> - adapter->rx_queue[0].toggle = 1;
> -
> - mac_address = ether_addr_to_u64(netdev->dev_addr);
> -
> - rxq_desc.fields.flags_len = IBMVETH_BUF_VALID |
> - adapter->rx_queue[0].queue_len;
> - rxq_desc.fields.address = adapter->rx_queue[0].queue_dma;
> -
> - netdev_dbg(netdev, "buffer list @ 0x%p\n", adapter->buffer_list_addr[0]);
> - netdev_dbg(netdev, "filter list @ 0x%p\n", adapter->filter_list_addr);
> - netdev_dbg(netdev, "receive q @ 0x%p\n", adapter->rx_queue[0].queue_addr);
> -
> - h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE);
> -
> - lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address);
> -
> - if (lpar_rc != H_SUCCESS) {
> - netdev_err(netdev, "h_register_logical_lan failed with %ld\n",
> - lpar_rc);
> - netdev_err(netdev, "buffer TCE:0x%llx filter TCE:0x%llx rxq "
> - "desc:0x%llx MAC:0x%llx\n",
> - adapter->buffer_list_dma[0],
> - adapter->filter_list_dma,
> - rxq_desc.desc,
> - mac_address);
> - rc = -ENONET;
> - goto out_unmap_filter_list;
> - }
> + rc = ibmveth_setup_rx_interrupts(adapter);
> + if (rc)
> + goto out_unregister_queues;
>
> - 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;
> + if (adapter->num_rx_queues > 1) {
> + for (i = 0; i < adapter->num_rx_queues; i++) {
> + netdev_dbg(netdev, "initial replenish cycle for queue %d\n", i);
> + ibmveth_replenish_task(adapter, i);
ibmveth_replenish_task() only has one parameter
until a later patch in this series.
> }
> + } else {
> + netdev_dbg(netdev, "initial replenish cycle\n");
> + ibmveth_interrupt(adapter->queue_irq[0], &adapter->napi[0]);
> }
>
> - netdev_dbg(netdev, "registering irq 0x%x\n", netdev->irq);
> - rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name,
> - netdev);
> - if (rc != 0) {
> - netdev_err(netdev, "unable to request irq 0x%x, rc %d\n",
> - netdev->irq, rc);
> - do {
> - lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
> - } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY));
> -
> - goto out_free_buffer_pools;
> - }
> -
> - rc = -ENOMEM;
> -
> - netdev_dbg(netdev, "initial replenish cycle\n");
> - ibmveth_interrupt(netdev->irq, netdev);
> + rc = ibmveth_alloc_tx_resources(adapter);
> + if (rc)
> + goto out_cleanup_rx_interrupts;
>
> netif_tx_start_all_queues(netdev);
>
> netdev_dbg(netdev, "open complete\n");
> -
> return 0;
>
> +out_cleanup_rx_interrupts:
> + ibmveth_cleanup_rx_interrupts(adapter);
> +out_free_tx_resources:
> + ibmveth_free_tx_resources(adapter);
The out_free_tx_resources label is unused until a later patch of this
series, so it should be added in that patch rather than this one.
And it's not clear to me that ibmveth_free_tx_resources() should
be called when jumping to out_cleanup_rx_interrupts as
in that case ibmveth_alloc_tx_resources() hasn't run successfully.
The AI-generated review on sashiko.dev also highlights the error handling
here:
"Are the unwind labels ordered incorrectly here?
"If ibmveth_setup_rx_interrupts() fails, it jumps to
out_unregister_queues, which is placed after out_free_buffer_pools. Does
this mean we skip freeing the buffer pools and leak memory?
"Also, if ibmveth_alloc_tx_resources() fails, it internally frees
partially allocated LTBs. It then jumps to out_cleanup_rx_interrupts and
falls through to out_free_tx_resources. Because ibmveth_free_tx_ltb()
calls dma_unmap_single() unconditionally without checking or zeroing
tx_ltb_dma, will this cause a double free and an invalid DMA unmap?
"Finally, in the fall-through path from out_cleanup_rx_interrupts,
out_free_buffer_pools is executed before out_unregister_queues (which
calls ibmveth_free_all_queues() to unregister the logical LAN). Does this
free and unmap the RX buffers while the hypervisor's logical LAN is still
active, potentially allowing the hypervisor to DMA incoming packets into
freed memory?
> 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_unmap_filter_list:
> - dma_unmap_single(dev, adapter->filter_list_dma, 4096,
> - DMA_BIDIRECTIONAL);
> -
> -out_free_tx_ltb:
> - while (--i >= 0) {
> - ibmveth_free_tx_ltb(adapter, i);
> - }
> -
> -out_unmap_buffer_list:
> - dma_unmap_single(dev, adapter->buffer_list_dma[0], 4096,
> - DMA_BIDIRECTIONAL);
> + ibmveth_free_buffer_pools(adapter);
> +out_unregister_queues:
> + ibmveth_dispose_subordinate_irq_mappings(adapter);
> + ibmveth_free_all_queues(adapter);
> out_free_queue_mem:
> - dma_free_coherent(dev, adapter->rx_queue[0].queue_len,
> - adapter->rx_queue[0].queue_addr,
> - adapter->rx_queue[0].queue_dma);
> + ibmveth_cleanup_rx_resources(adapter);
> out_free_filter_list:
> - free_page((unsigned long)adapter->filter_list_addr);
> -out_free_buffer_list:
> - free_page((unsigned long)adapter->buffer_list_addr[0]);
> + ibmveth_free_filter_list(adapter);
> +out_free_rx_qstats:
> + ibmveth_free_rx_qstats(adapter);
> out:
> - napi_disable(&adapter->napi[0]);
> return rc;
> }
...
next prev parent reply other threads:[~2026-07-14 12:47 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-06 19:35 [PATCH net-next v3 00/15] ibmveth: Add multi-queue RX support Mingming Cao
2026-07-06 19:35 ` [PATCH net-next v3 01/15] ibmveth: Add MQ RX hypercall wrappers and call definitions Mingming Cao
2026-07-06 19:35 ` [PATCH net-next v3 02/15] ibmveth: Prepare MQ RX adapter and statistics structures Mingming Cao
2026-07-06 19:35 ` [PATCH net-next v3 03/15] ibmveth: Refactor RX resource allocation for MQ RX bring-up Mingming Cao
2026-07-06 19:35 ` [PATCH net-next v3 04/15] ibmveth: Refactor buffer pool management for per-queue MQ RX Mingming Cao
2026-07-06 19:35 ` [PATCH net-next v3 05/15] ibmveth: Refactor RX interrupt control for MQ RX queues Mingming Cao
2026-07-14 12:43 ` Simon Horman
2026-07-06 19:35 ` [PATCH net-next v3 06/15] ibmveth: Refactor TX resource allocation in open/close paths Mingming Cao
2026-07-06 19:35 ` [PATCH net-next v3 07/15] ibmveth: Add RX queue register/deregister helpers for MQ Mingming Cao
2026-07-14 12:43 ` Simon Horman
2026-07-06 19:35 ` [PATCH net-next v3 08/15] ibmveth: Refactor open/close into MQ-ready resource pipeline Mingming Cao
2026-07-14 12:47 ` Simon Horman [this message]
2026-07-06 19:35 ` [PATCH net-next v3 09/15] ibmveth: Add queue-aware RX buffer submit helper for MQ Mingming Cao
2026-07-14 12:50 ` Simon Horman
2026-07-06 19:35 ` [PATCH net-next v3 10/15] ibmveth: Enable multi-queue RX receive path Mingming Cao
2026-07-14 12:55 ` Simon Horman
2026-07-06 19:35 ` [PATCH net-next v3 11/15] ibmveth: Add per-queue RX and TX statistics collection and reporting Mingming Cao
2026-07-14 12:59 ` Simon Horman
2026-07-06 19:36 ` [PATCH net-next v3 12/15] ibmveth: Expose per-queue buffer pool details via sysfs Mingming Cao
2026-07-14 13:01 ` Simon Horman
2026-07-06 19:36 ` [PATCH net-next v3 13/15] ibmveth: Implement incremental MQ RX queue resize Mingming Cao
2026-07-14 13:03 ` Simon Horman
2026-07-06 19:36 ` [PATCH net-next v3 14/15] ibmveth: Wire ethtool set_channels to " Mingming Cao
2026-07-14 13:07 ` Simon Horman
2026-07-06 19:36 ` [PATCH net-next v3 15/15] ibmveth: Fix MQ RX poll and shutdown hangs after " Mingming Cao
2026-07-14 13:10 ` 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=20260714124736.GK1364329@horms.kernel.org \
--to=horms@kernel.org \
--cc=bjking1@linux.ibm.com \
--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=mmc@linux.ibm.com \
--cc=mpe@ellerman.id.au \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=ricklind@linux.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 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.