Netdev List
 help / color / mirror / Atom feed
From: netdev-bot+sashiko@kernel.org
To: daniel@makrotopia.org
Cc: jiri@resnulli.us, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, horms@kernel.org,
	corbet@lwn.net, skhan@linuxfoundation.org, rdunlap@infradead.org,
	gregkh@linuxfoundation.org, rafael@kernel.org, dakr@kernel.org,
	andrew@lunn.ch, olteanv@gmail.com, netdev@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	driver-core@lists.linux.dev
Subject: Re: [PATCH net-next v15 4/6] net: dsa: mxl862xx: add devlink flash_update and info_get
Date: Mon, 14 Sep 2026 18:34:55 +0000	[thread overview]
Message-ID: <178941089525.22033.5761455207730360931@kernel.org> (raw)
In-Reply-To: <377a73c5ff437600212eb2323f13cea450cedc81.1789175618.git.daniel@makrotopia.org>

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

Critical: 0 · High: 1 · Medium: 0 · Low: 1

- [High] AB-BA deadlock between the devlink instance lock and the driver-
  core device lock.
- [Low] drivers/net/dsa/mxl862xx/Kconfig does not `select CRC32` although
  the new mxl862xx-fw.c calls crc32_le() twice in…

--

net: dsa: mxl862xx: add devlink flash_update and info_get

This adds devlink dev info version reporting (asic.id, asic.rev and the
running/stored firmware version) and devlink dev flash support for the
MxL862xx switch, transferring a validated image over the SB PDI protocol
after rebooting the switch into its MCUboot loader and then scheduling a
deferred re-probe.

> diff --git a/drivers/net/dsa/mxl862xx/mxl862xx-fw.c b/drivers/net/dsa/mxl862xx/mxl862xx-fw.c
> new file mode 100644
> index 0000000000000..119792eb7bd58
> --- /dev/null
> +++ b/drivers/net/dsa/mxl862xx/mxl862xx-fw.c
> @@ -0,0 +1,648 @@

[ ... ]

> +#include <linux/crc32.h>

[ ... ]

> +	if (size1) {
> +		crc = ~crc32_le(~0U, payload, size1);
> +		if (crc != le32_to_cpu(hdr->image_checksum_1)) {
> +			dev_err(&priv->mdiodev->dev,
> +				"flash: image 1 CRC mismatch (got %08x, expected %08x)\n",
> +				crc, le32_to_cpu(hdr->image_checksum_1));
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (size2) {
> +		crc = ~crc32_le(~0U, payload + size1, size2);

[Severity: Low]

Should drivers/net/dsa/mxl862xx/Kconfig also select CRC32 for these two
new crc32_le() users in mxl862xx_flash_validate()?

The driver's Kconfig currently has:

config NET_DSA_MXL862
	tristate "MaxLinear MxL862xx"
	depends on NET_DSA
	select CRC16
	select NET_DSA_TAG_MXL_862XX

CRC16 is selected for the crc16() user in mxl862xx-host.c, but nothing
selects CRC32. In lib/crc/Kconfig, CRC32 is a bare tristate with no prompt
and no default:

config CRC32
	tristate
	select BITREVERSE
	help
	  The CRC32 library functions.  Select this if your module uses any of
	  the functions from <linux/crc32.h> or <linux/crc32c.h>.

and lib/crc/Makefile builds crc32.o under obj-$(CONFIG_CRC32), so with
CONFIG_CRC32=n (or CRC32=m while NET_DSA_MXL862=y) does this fail to link
with an undefined crc32_le? The select is still missing at the end of the
series.

[ ... ]

> +int mxl862xx_devlink_flash_update(struct dsa_switch *ds,
> +				  struct devlink_flash_update_params *params,
> +				  struct netlink_ext_ack *extack)
> +{

[ ... ]

> +	mutex_lock_nested(&priv->mdiodev->bus->mdio_lock, MDIO_MUTEX_NESTED);
> +	priv->flash_owner = NULL;
> +	priv->block_host = false;
> +	priv->skip_teardown = true;
> +	mutex_unlock(&priv->mdiodev->bus->mdio_lock);
> +
> +	/* Reinitialise through a deferred re-probe: remove() runs with
> +	 * skip_teardown set, then a fresh probe() starts against whatever
> +	 * the switch now runs. The core skips the re-probe if the device
> +	 * is unbound or shut down before it fires.
> +	 */
> +	err = device_schedule_reprobe(ds->dev, MXL862XX_FW_REPROBE_DELAY_MS);

[Severity: High]

Can this call deadlock against a concurrent unbind of the same mdio
device?

.devlink_flash_update runs with the devlink instance lock held by the
netlink core:

devlink_nl_pre_doit()
  __devlink_nl_pre_doit()
    devlink_get_from_attrs_lock()
      devl_dev_lock(devlink, false)   /* devl_lock() only */

and device_schedule_reprobe() then takes device_lock() synchronously in
that context:

drivers/base/dd.c:device_schedule_reprobe() {
	...
	device_lock(dev);
	parent = dev->parent;
	if (!dev->bus || !dev->p || dev->p->dead ||
	    !device_is_registered(dev) || !dev->driver) {
	...
}

So this path is devl_lock -> device_lock.

The opposite order exists in the unbind path, where the driver core holds
device_lock across ->remove():

device_release_driver_internal()   /* holds device_lock(&mdiodev->dev) */
  mxl862xx_remove()
    dsa_unregister_switch()
      dsa_switch_teardown()
        dsa_switch_devlink_unregister()
          devlink_unregister()
            devl_lock()

devlink itself documents the same order in net/devlink/devl_internal.h:

static inline void devl_dev_lock(struct devlink *devlink, bool dev_lock)
{
	if (dev_lock && devlink->dev)
		device_lock(devlink->dev);
	devl_lock(devlink);
}

For DSA, devlink->dev is ds->dev, i.e. &mdiodev->dev, so both locks in
the cycle are the same two objects. If a sysfs unbind or rmmod runs while
devlink dev flash is in progress, does one thread end up holding
device_lock and waiting on devl_lock while the flash thread holds
devl_lock for the whole transfer and then waits on device_lock?

Both are plain mutexes with no trylock or timeout here, and
device_initialize() marks dev->mutex with lockdep_set_novalidate_class(),
so would lockdep report this cycle at all?

Would scheduling the re-probe from a context that does not hold the
devlink instance lock, or a variant of the helper that does not take
device_lock in the caller's context, avoid the inversion?

> +
> +	return ret ? ret : err;
> +}

Please double check this analysis, and thanks for your time reviewing it.

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/cover.1789175618.git.daniel%40makrotopia.org

             reply	other threads:[~2026-09-14 18:34 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-14 18:34 netdev-bot+sashiko [this message]
  -- strict thread matches above, loose matches on Subject: below --
2026-09-13 18:00 [PATCH net-next v15 0/6] net: dsa: mxl862xx: devlink flash and rescue Daniel Golle
2026-09-13 18:02 ` [PATCH net-next v15 4/6] net: dsa: mxl862xx: add devlink flash_update and info_get Daniel Golle

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=178941089525.22033.5761455207730360931@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=andrew@lunn.ch \
    --cc=corbet@lwn.net \
    --cc=dakr@kernel.org \
    --cc=daniel@makrotopia.org \
    --cc=davem@davemloft.net \
    --cc=driver-core@lists.linux.dev \
    --cc=edumazet@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=horms@kernel.org \
    --cc=jiri@resnulli.us \
    --cc=kuba@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=rafael@kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=skhan@linuxfoundation.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