Re: [PATCH v2 3/3] mtd: spi-nor: take the flash lock in spi_nor_remove()
From: Miquel Raynal
Date: Mon Sep 14 2026 - 08:57:38 EST
On 14/09/2026 at 11:11:49 +03, Itai Handler <itai.handler@xxxxxxxxx> wrote:
> spi_nor_remove() restores the addressing mode with the same unlocked
> call to spi_nor_restore() that spi_nor_shutdown() used before the
> previous patch, and it is exposed the same way: the MTD device is still
> registered at that point, so an unbind can run the restore while another
> thread is in the middle of an operation. A busy flash silently ignores
> the restore, and a restore that lands between two chunks of a read
> switches the chip to 3-byte addressing while the driver keeps sending
> 4 address bytes.
>
> Moving the restore after mtd_device_unregister() would not fix this.
> Since commit 19bfa9ebebb5 ("mtd: use refcount to prevent corruption")
> del_mtd_device() drops a reference instead of refusing with -EBUSY when
> the device is in use, so unregistering returns right away and does not
> wait for an operation that is already running.
>
> Take nor->lock for the restore, as spi_nor_shutdown() now does. The
> unregister stays unconditional, so a flash whose restore had to be
> skipped is still torn down.
>
> Fixes: 59b356ffd0b0 ("mtd: m25p80: restore the status of SPI flash when exiting")
> Signed-off-by: Itai Handler <itai.handler@xxxxxxxxx>
> ---
> drivers/mtd/spi-nor/core.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 647bf8dce719..8d0302565445 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -3852,8 +3852,14 @@ static int spi_nor_probe(struct spi_mem *spimem)
> static int spi_nor_remove(struct spi_mem *spimem)
> {
> struct spi_nor *nor = spi_mem_get_drvdata(spimem);
> + int ret;
>
> - spi_nor_restore(nor);
> + /* As in spi_nor_shutdown(), do not restore under an operation. */
> + ret = spi_nor_prep_and_lock(nor);
> + if (!ret) {
> + spi_nor_restore(nor);
> + spi_nor_unlock_and_unprep(nor);
> + }
Why isn't this folded into patch 2? You are fixing the same race, but
you do it in two steps which makes step 1 incomplete. I don't get it.
You are making things overly complicated for no reason. You commit logs
are overly verbose and the comments are also superfluous.
Thanks,
Miquèl