mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: netdev-bot+sashiko@kernel.org
To: lgs201920130244@gmail.com
Cc: akiyano@amazon.com, darinzon@amazon.com, andrew+netdev@lunn.ch,
	davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, ekffu200098@gmail.com,
	niklas.soderlund+renesas@ragnatech.se, dawei.feng@seu.edu.cn,
	amitbern@amazon.com, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH] net: ena: fix PHC cleanup on probe failure
Date: Thu, 17 Sep 2026 17:31:08 +0000	[thread overview]
Message-ID: <178966626828.22033.11993324516511047736@kernel.org> (raw)
In-Reply-To: <20260916022954.2690322-1-lgs201920130244@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issue(s) to consider:

Critical: 0 · High: 0 · Medium: 2 · Low: 0 (1)

- [Medium] ena_probe() error unwind still omits
  ena_com_mmio_reg_read_request_destroy(), leaking the DMA-coherent…
- [Medium] The commit message's premise is not reachable: during an
  initial ena_probe(), PHC is always disabled, so no PTP clock and no…

Pre-existing issues:
- [Low] ena_probe()'s err_worker_destroy label calls
  timer_delete(&adapter->timer_service)…

--

net: ena: fix PHC cleanup on probe failure

This adds a call to ena_phc_destroy() to the err_device_destroy label in
ena_probe(), so the probe error path mirrors the ena_destroy_device()
teardown before ena_phc_free() runs.

A couple of questions about the changelog and the error path below.

>     The normal removal path calls ena_phc_destroy() through
>     ena_destroy_device() before ena_phc_free(). However, if probe fails
>     after ena_device_init() succeeds, the error path reaches ena_phc_free()
>     without unregistering the PTP clock or destroying the device PHC
>     resources.

[Severity: Medium]
Is there actually a registered PTP clock or allocated device PHC resource
at that point during an initial probe?

Following the state that PHC has when ena_device_init() returns 0:

ena_phc_alloc() vzalloc()s phc_info, so phc_info->enabled is false, and
ena_devlink_configure_params() seeds the driverinit ENABLE_PHC value from
that state:

	value.vbool = ena_phc_is_enabled(adapter);
	devl_param_driverinit_value_set(devlink,
					DEVLINK_PARAM_GENERIC_ID_ENABLE_PHC,
					&value);

ena_device_init() -> ena_devlink_params_get() then reads that value back
and calls ena_phc_enable(adapter, false), so ena_phc_init() takes:

	if (!ena_phc_is_enabled(adapter)) {
		netdev_dbg(netdev, "PHC feature is not enabled by the kernel\n");
		goto err_ena_com_phc_init;
	}

which skips ena_com_phc_init() (phc->virt_addr stays NULL) and
ena_phc_register() (phc_info->clock stays NULL).

Userspace cannot flip the param earlier either, since devlink netlink
lookup rejects instances that are not registered yet
(devlink_get_from_attrs_lock() requires devl_is_registered()), and ENA
only calls ena_devlink_register() at the successful end of ena_probe().

So on every path that can reach the new call, ena_phc_unregister()
returns immediately via ena_phc_is_active() and ena_com_phc_destroy()
returns immediately on !phc->virt_addr. The only path where PHC can
really be active on failure is ena_restore_device(), which already calls
ena_phc_destroy().

Given that, are the Fixes: tag and Cc: stable warranted here, or would
describing this as hardening for symmetry be more accurate?

> diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
> index ea89619039d89..5f0864d16dd3c 100644
> --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
> +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
> @@ -4122,6 +4122,7 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  err_device_destroy:
>  	ena_com_delete_host_info(ena_dev);
>  	ena_com_admin_destroy(ena_dev);
> +	ena_phc_destroy(adapter);

[Severity: Medium]
Does this label still leak the mmio read-less response buffer allocated
by ena_com_mmio_reg_read_request_init()?

ena_device_init() calls ena_com_mmio_reg_read_request_init()
unconditionally, which does:

	mmio_read->read_resp = dma_alloc_coherent(ena_dev->dmadev, sizeof(*mmio_read->read_resp),
						  &mmio_read->read_resp_dma_addr, GFP_KERNEL);

and programs that address into the device via
ena_com_mmio_reg_read_request_write_dev_addr(). It is only released
inside ena_device_init() itself, at its err_mmio_read_less label.

The teardown sequence this patch is modelled on does three steps:

drivers/net/ethernet/amazon/ena/ena_netdev.c:ena_destroy_device() {
	...
	ena_com_admin_destroy(ena_dev);

	ena_phc_destroy(adapter);

	ena_com_mmio_reg_read_request_destroy(ena_dev);
	...
}

and ena_restore_device()'s error path pairs them the same way:

	ena_phc_destroy(adapter);
	ena_com_mmio_reg_read_request_destroy(ena_dev);

The new code adds the middle step but not the last one, so once
ena_device_init() has returned 0, any later probe failure walks
err_device_destroy -> ena_devlink_free() ->
ena_com_delete_customer_metrics_buffer() -> ena_phc_free() ->
free_netdev() -> vfree(ena_dev) with mmio_read.read_resp still
allocated. After vfree(ena_dev) the pointer and DMA handle are gone, and
the device's ENA_REGS_MMIO_RESP_LO/HI registers keep the stale address,
since only ena_com_mmio_reg_read_request_destroy() zeroes them:

	writel(0x0, ena_dev->reg_bar + ENA_REGS_MMIO_RESP_LO_OFF);
	writel(0x0, ena_dev->reg_bar + ENA_REGS_MMIO_RESP_HI_OFF);

	dma_free_coherent(ena_dev->dmadev, sizeof(*mmio_read->read_resp), mmio_read->read_resp,
			  mmio_read->read_resp_dma_addr);

Reachable failures include max_num_io_queues == 0 (which also does no
ena_com_dev_reset()), ena_com_init_interrupt_moderation() failure,
ena_enable_msix_and_set_admin_interrupts() failure,
ena_rss_init_default() failure and register_netdev() failure.

Should ena_com_mmio_reg_read_request_destroy(ena_dev) be added right
after the new ena_phc_destroy(adapter) here?

>  ena_devlink_destroy:
>  	ena_devlink_free(devlink);
>  err_metrics_destroy:
>  	ena_com_delete_customer_metrics_buffer(ena_dev);

[Severity: Low]
This is a pre-existing issue and was not introduced by this patch, but
while looking at the labels just above the changed one: does
err_worker_destroy call timer_delete() on an uninitialized timer?

	err_worker_destroy:
		timer_delete(&adapter->timer_service);

timer_service is only ever set up after register_netdev() succeeds:

	timer_setup(&adapter->timer_service, ena_timer_service, 0);
	mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ));

and there is no failure goto after that point, so every path that lands
on err_worker_destroy (MSI-X setup failure, ena_rss_init_default()
failure falling through err_free_msix, register_netdev() failure falling
through err_rss) runs before timer_setup(). The memory is the zeroed
netdev private area from alloc_etherdev_mq().

With CONFIG_DEBUG_OBJECTS_TIMERS, __timer_delete() starts with
debug_assert_init(timer), and timer_is_static_object() requires
entry.next == TIMER_ENTRY_STATIC while the zeroed timer has
entry.next == NULL, so debug_print_object() issues an "assert_init"
warning before timer_fixup_assert_init() installs a stub. Without that
option, timer_pending() is false and the call is a no-op, so this only
shows up as a splat on debug kernels during an already-failing probe.

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260916022954.2690322-1-lgs201920130244%40gmail.com

      parent reply	other threads:[~2026-09-17 17:31 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-16  2:29 Guangshuo Li
2026-09-16  5:44 ` Arthur Kiyanovski
2026-09-17 17:31 ` netdev-bot+sashiko [this message]

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=178966626828.22033.11993324516511047736@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=akiyano@amazon.com \
    --cc=amitbern@amazon.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=darinzon@amazon.com \
    --cc=davem@davemloft.net \
    --cc=dawei.feng@seu.edu.cn \
    --cc=edumazet@google.com \
    --cc=ekffu200098@gmail.com \
    --cc=kuba@kernel.org \
    --cc=lgs201920130244@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=niklas.soderlund+renesas@ragnatech.se \
    --cc=pabeni@redhat.com \
    --cc=stable@vger.kernel.org \
    /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®