From: netdev-bot+sashiko@kernel.org
To: niklas.soderlund+renesas@ragnatech.se
Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
geert+renesas@glider.be, magnus.damm@gmail.com,
richardcochran@gmail.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, vadim.fedorenko@linux.dev,
sergei.shtylyov@gmail.com, linux-renesas-soc@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org
Subject: Re: [PATCH net-next v3 07/10] net: ethernet: ravb: Add callback for gPTP probe
Date: Mon, 07 Sep 2026 02:48:36 +0000 [thread overview]
Message-ID: <178874931650.219967.14780961400523753736@kernel.org> (raw)
In-Reply-To: <20260902084703.3228504-8-niklas.soderlund+renesas@ragnatech.se>
Thank you for your contribution! Sashiko AI review found 4 potential
issue(s) to consider:
Critical: 1 · High: 2 · Medium: 1 · Low: 0
- [Critical] ravb_get_ts_info()
(drivers/net/ethernet/renesas/ravb_main.c:1771-1790) gates on…
- [High] ravb_ptp_stop()
(drivers/net/ethernet/renesas/ravb_ptp.c:368-377) unregisters…
- [High] For the ccc_gac-style generations the PTP clock is registered
from ravb_open() via info->ptp->ndev_open (ravb_main.c:1953-1956,…
- [Medium] The newly propagated ptp_clock_register() error creates
ravb_open() failure paths that leak all DMA ring resources.
--
net: ethernet: ravb: Add callback for gPTP probe
This adds a probe callback to struct ravb_gptp_info so each RAVB
generation can acquire its own gPTP timer clock, removes the last gPTP
specific flag (gptp_ref_clk), and moves the GTI computation into the new
per-generation probe callbacks.
A few questions below about the gPTP clock lifecycle that the ptp callback
structs in this patch select.
> diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
> index 5d5b9c0e2f450..7e53eca5327f5 100644
> --- a/drivers/net/ethernet/renesas/ravb_main.c
> +++ b/drivers/net/ethernet/renesas/ravb_main.c
[ ... ]
> @@ -2668,6 +2668,7 @@ static int ravb_gen2_ptp_set_config_mode(struct net_device *ndev)
> }
>
> static const struct ravb_gptp_info ravb_gen2_ptp_info = {
> + .probe = ravb_gen2_ptp_probe,
> .set_config_mode = ravb_gen2_ptp_set_config_mode,
> .dmac_start = ravb_ptp_init,
> .dmac_stop = ravb_ptp_stop,
> };
[Severity: High]
With dmac_stop = ravb_ptp_stop wired up here, can priv->ptp.clock end up
pointing at a freed object after the interface goes down?
ravb_ptp_stop() in ravb_ptp.c unregisters the clock but never clears the
pointer:
if (priv->ptp.clock)
ptp_clock_unregister(priv->ptp.clock);
The baseline cleared it before unregistering:
WRITE_ONCE(priv->ptp.phc_index, -1);
clock = xchg(&priv->ptp.clock, NULL);
After ip link set <if> down on Gen2/RZ-V2M, ravb_close() -> ravb_stop_dma()
-> dmac_stop = ravb_ptp_stop() leaves the stale pointer, and
ravb_get_ts_info() then reads the freed memory:
info->phc_index = ptp_clock_index(priv->ptp.clock);
drivers/ptp/ptp_clock.c:ptp_clock_index() is just:
return ptp->index;
ETHTOOL_GET_TS_INFO is in the list in dev_ethtool() that skips the
ns_capable(CAP_NET_ADMIN) check, so this read is reachable by any local
user once the interface is down.
Can the same stale pointer also be unregistered twice? In
ravb_tx_timeout_work(), ravb_stop_dma() runs ravb_ptp_stop() (unregister),
and if the following ravb_dmac_init() fails (ravb_ring_init() returning
-ENOMEM, or the OPERATION opmode wait timing out) the function returns via
out_unlock without re-registering, so the later ravb_close() ->
ravb_stop_dma() -> ravb_ptp_stop() calls ptp_clock_unregister() on the
already freed clock.
This was introduced earlier in the series by "net: ethernet: ravb:
Propagate error from ptp_clock_register()" and ravb_ptp_stop() is still
unchanged at the end of the series (941e688), where
ravb_gen2_ptp_clock_index() likewise still does
return ptp_clock_index(priv->ptp.clock).
> @@ -2704,6 +2705,7 @@ static int ravb_gen3_ptp_set_config_mode(struct net_device *ndev)
> }
>
> static const struct ravb_gptp_info ravb_gen3_ptp_info = {
> + .probe = ravb_gen2_ptp_probe,
> .set_config_mode = ravb_gen3_ptp_set_config_mode,
> .ndev_open = ravb_ptp_init,
> .ndev_close = ravb_ptp_stop,
> };
[Severity: High]
Since ravb_gen3_ptp_info registers the clock from ndev_open and only tears
it down from ndev_close, is the clock leaked when ravb_open() fails after
that registration?
ravb_open() calls info->ptp->ndev_open() and then ravb_phy_start(), whose
failure path is:
out_ptp_stop:
ravb_stop_dma(ndev);
ravb_stop_dma() only stops PTP through info->ptp->dmac_stop, and
ravb_gen3_ptp_info has no dmac_stop, so nothing unregisters the clock.
ravb_gen4_hw_info uses ravb_gen3_ptp_info at this commit as well.
ravb_phy_start() can fail concretely: ravb_phy_init() returns -ENOENT when
of_phy_connect() fails, and it also propagates
of_phy_register_fixed_link() errors. As ndo_open returned an error the
netdev never goes IFF_UP, so ndo_stop and therefore ndev_close =
ravb_ptp_stop() are never called.
Consequences of that: /dev/ptpN stays registered; a retried open
overwrites priv->ptp.clock in ravb_ptp_init(), losing the old registration
for good; and a later unbind runs ravb_remove() -> free_netdev(ndev)
while the PTP core still has ptp->info pointing into the freed netdev
private area.
The baseline out_ptp_stop label did:
if (info->gptp || info->ccc_gac)
ravb_ptp_stop(ndev);
That was dropped by the series commit "net: ethernet: ravb: Simplify gPTP
start and stop", which added the stop only inside ravb_stop_dma(), so the
"no functional change" claim there does not seem to hold for the ccc_gac
(Gen3/Gen4) case. The gap is still present at 941e688, where out_ptp_stop
only calls ravb_stop_dma() and ravb_gen3_ptp_info still has no dmac_stop.
> @@ -2763,6 +2765,24 @@ static const struct ravb_hw_info ravb_gen4_hw_info = {
> .magic_pkt = 1,
> };
>
> +static int ravb_rzv2m_ptp_probe(struct net_device *ndev)
> +{
> + struct ravb_private *priv = netdev_priv(ndev);
> +
> + priv->gptp_clk = devm_clk_get(&priv->pdev->dev, "gptp");
> + if (IS_ERR(priv->gptp_clk))
> + return PTR_ERR(priv->gptp_clk);
> +
> + return ravb_compute_gti(ndev, priv->gptp_clk);
> +}
> +
> +static const struct ravb_gptp_info ravb_rzv2m_ptp_info = {
> + .probe = ravb_rzv2m_ptp_probe,
> + .set_config_mode = ravb_gen2_ptp_set_config_mode,
> + .dmac_start = ravb_ptp_init,
[Severity: Medium]
With dmac_start = ravb_ptp_init, does a failing ptp_clock_register() leak
the DMA rings?
ravb_dmac_init() first runs info->dmac_init = ravb_dmac_init_rcar(), which
allocates both queues in ravb_ring_init():
priv->rx_pool[q] = page_pool_create(¶ms);
...
priv->tx_ring[q] = dma_alloc_coherent(ndev->dev.parent, ring_size,
&priv->tx_desc_dma[q], GFP_KERNEL);
and only afterwards does:
/* Initialise PTP Clock driver */
if (info->ptp && info->ptp->dmac_start)
return info->ptp->dmac_start(ndev);
If ptp_clock_register() in ravb_ptp_init() fails (for example -ENOMEM under
memory pressure), that error reaches ravb_open(), which jumps to
out_set_reset. Neither out_set_reset nor out_ptp_stop calls
ravb_ring_free(), and since ndo_open returned an error, ravb_close() (the
only ring freeing path) never runs; ravb_remove() does not free them
either.
A later open re-enters ravb_ring_init() and overwrites priv->rx_pool[q],
priv->rx_buffers[q], priv->tx_skb[q], priv->rx_ring[q] and
priv->tx_ring[q], so the previous page pools with their DMA mappings and
the coherent descriptor memory are lost.
For Gen3/Gen4 the equivalent ndev_open failure goes to out_ptp_stop, which
also does not call ravb_ring_free(). The same leak shape already existed
for a failing ravb_set_opmode(CCC_OPC_OPERATION); the new trigger comes
from the series commit "net: ethernet: ravb: Propagate error from
ptp_clock_register()", and the ravb_open() error labels are unchanged at
941e688.
> + .dmac_stop = ravb_ptp_stop,
> +};
> +
> static const struct ravb_hw_info ravb_rzv2m_hw_info = {
> .receive = ravb_rx_rcar,
> .set_rate = ravb_set_rate_rcar,
> @@ -2783,8 +2803,7 @@ static const struct ravb_hw_info ravb_rzv2m_hw_info = {
> .dbat_entry_num = 22,
> .multi_irqs = 1,
> .err_mgmt_irqs = 1,
> - .ptp = &ravb_gen2_ptp_info,
> - .gptp_ref_clk = 1,
> + .ptp = &ravb_rzv2m_ptp_info,
[Severity: Critical]
hw_info->ptp is what ravb_get_ts_info() tests, and it only says the IP
supports gPTP. Can that path dereference a NULL priv->ptp.clock?
ravb_get_ts_info() does:
if (hw_info->ptp) {
...
info->phc_index = ptp_clock_index(priv->ptp.clock);
}
priv->ptp.clock is the zero initialised NULL from alloc_etherdev_mqs()
until the clock is registered, which only happens in the open lifecycle
(Gen2/RZ-V2M via ravb_dmac_init() -> dmac_start = ravb_ptp_init(),
Gen3/Gen4 via ravb_open() -> ndev_open = ravb_ptp_init()), and
ravb_ptp_init() explicitly stores NULL on registration failure:
priv->ptp.clock = ptp_clock_register(&priv->ptp.info, &priv->pdev->dev);
if (IS_ERR(priv->ptp.clock)) {
ret = PTR_ERR(priv->ptp.clock);
priv->ptp.clock = NULL;
With CONFIG_PTP_1588_CLOCK=y, ptp_clock_index() is
return ptp->index;, so ethtool -T on an interface that has never been
opened (the state right after probe and register_netdev) oopses.
ETHTOOL_GET_TS_INFO does not require CAP_NET_ADMIN in dev_ethtool(), so an
unprivileged user can reach it; only CONFIG_PTP_1588_CLOCK=n is safe
because of the inline stub returning -1.
The baseline kept a separate priv->ptp.phc_index initialised to -1 in
ravb_probe() and read it with READ_ONCE(); the series commit "net:
ethernet: ravb: Propagate error from ptp_clock_register()" removed that
field and its -1 initialisation. At 941e688 the callback
ravb_gen2_ptp_clock_index() still does
return ptp_clock_index(priv->ptp.clock) and is installed for gen2, gen3
and rzv2m.
> .nc_queues = 1,
> .magic_pkt = 1,
> };
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260902084703.3228504-1-niklas.soderlund%2Brenesas%40ragnatech.se
next prev parent reply other threads:[~2026-09-07 2:48 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 8:46 [PATCH net-next v3 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
2026-09-02 8:46 ` [PATCH net-next v3 01/10] net: ethernet: ravb: Remove gPTP control from WoL setup and restore Niklas Söderlund
2026-09-03 8:47 ` sashiko-bot
2026-09-03 11:11 ` Niklas Söderlund
2026-09-07 2:48 ` netdev-bot+sashiko
2026-09-02 8:46 ` [PATCH net-next v3 02/10] net: ethernet: ravb: Move programming of gPTP timer interval Niklas Söderlund
2026-09-03 8:47 ` sashiko-bot
2026-09-07 2:48 ` netdev-bot+sashiko
2026-09-02 8:46 ` [PATCH net-next v3 03/10] net: ethernet: ravb: Simplify gPTP start and stop Niklas Söderlund
2026-09-03 8:47 ` sashiko-bot
2026-09-07 2:48 ` netdev-bot+sashiko
2026-09-02 8:46 ` [PATCH net-next v3 04/10] net: ethernet: ravb: Remove redundant argument to ravb_ptp_init() Niklas Söderlund
2026-09-02 8:46 ` [PATCH net-next v3 05/10] net: ethernet: ravb: Propagate error from ptp_clock_register() Niklas Söderlund
2026-09-03 8:47 ` sashiko-bot
2026-09-03 11:35 ` Niklas Söderlund
2026-09-07 2:48 ` netdev-bot+sashiko
2026-09-02 8:46 ` [PATCH net-next v3 06/10] net: ethernet: ravb: Replace gPTP flags with callbacks Niklas Söderlund
2026-09-03 8:47 ` sashiko-bot
2026-09-07 2:48 ` netdev-bot+sashiko
2026-09-02 8:47 ` [PATCH net-next v3 07/10] net: ethernet: ravb: Add callback for gPTP probe Niklas Söderlund
2026-09-03 8:47 ` sashiko-bot
2026-09-07 2:48 ` netdev-bot+sashiko [this message]
2026-09-02 8:47 ` [PATCH net-next v3 08/10] net: ethernet: ravb: Add callback for gPTP clock index Niklas Söderlund
2026-09-03 8:47 ` sashiko-bot
2026-09-07 2:48 ` netdev-bot+sashiko
2026-09-02 8:47 ` [PATCH net-next v3 09/10] dt-bindings: net: renesas,etheravb: Add optional gPTP phandle for Gen4 Niklas Söderlund
2026-09-07 2:48 ` netdev-bot+sashiko
2026-09-02 8:47 ` [PATCH net-next v3 10/10] net: ethernet: ravb: Add gPTP support " Niklas Söderlund
2026-09-03 8:48 ` sashiko-bot
2026-09-07 2:48 ` netdev-bot+sashiko
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=178874931650.219967.14780961400523753736@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=conor+dt@kernel.org \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=geert+renesas@glider.be \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=magnus.damm@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=niklas.soderlund+renesas@ragnatech.se \
--cc=pabeni@redhat.com \
--cc=richardcochran@gmail.com \
--cc=robh@kernel.org \
--cc=sergei.shtylyov@gmail.com \
--cc=vadim.fedorenko@linux.dev \
/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.