Re: [PATCH RFC 0/3] mtd: spi-nor: allow multiple erase sizes on uniform flashes

From: Mateusz Litwin (Nokia)

Date: Tue Jul 28 2026 - 03:56:57 EST


On 2026-07-22 09:34 +0200, Michael Walle wrote:
> Hi,
>
> On Mon Jul 20, 2026 at 5:12 PM CEST, Mateusz Litwin via B4 Relay wrote:
> > Most SPI NOR flashes advertise several erase sizes (e.g. 4 KiB, 32 KiB and
> > 64 KiB) even when the erase map is uniform across the whole device. The
> > spi-nor driver currently collapses such flashes to a single erase size and
> > uses only that size for every erase request.
> >
> > This is a problem on platforms that need a small exposed erasesize for
> > partition alignment (for example u-boot-env, RouterBoot soft_config, or
> > boot header partitions) while still wanting fast bulk erases. Today the
> > usual workaround is to enable MTD_SPI_NOR_USE_4K_SECTORS, which forces 4 KiB
> > erases for the entire device and hurts erase performance on large regions.
> >
> > This series introduces MTD_SPI_NOR_MULTI_ERASE_SIZE. When enabled, uniform
> > flashes keep multiple erase sizes in the driver erase map and pick the
> > largest suitable erase size for each step of an erase operation, similar to
> > what non-uniform flashes already do. Userspace still sees a single
> > mtd->erasesize (4 KiB when MTD_SPI_NOR_USE_4K_SECTORS is also enabled), but
> > large aligned portions of an erase request can use 32 KiB or 64 KiB erase
> > commands internally.
> >
> > The series also converts all erase-type opcodes to their 4-byte-address
> > variants on uniform flashes, so multi-size erases work correctly on devices
> > larger than 16 MiB.
> >
> > This is an RFC series. Feedback is especially welcome on whether to merge
> > patch 1 alone, patches 1+2, or the full series including the patch 3 PoC.
> >
> > The series is stacked so maintainers can choose how much to take:
> >
> > - Patch 1 adds the Kconfig option, keeps multiple erase types in the
> > uniform region mask, and converts all erase-type opcodes for 4-byte
> > addressing. On its own it routes multi-size uniform erases through
> > spi_nor_erase_multi_sectors().
> > - Patch 2 replaces that routing with a dedicated uniform erase flow
> > (spi_nor_erase_uniform()), reducing CPU and memory overhead.
> > - Patch 3 is a proof-of-concept optimization on top of patch 2: it
> > caches the largest uniform erase type per request to skip redundant
> > spi_nor_find_best_erase_type() calls in bulk-aligned regions.
> >
> > Patch 1 follows an OpenWrt pending patch already used in production:
> >
> > https://github.com/openwrt/openwrt/blob/main/target/linux/generic/pending-6.12/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch
> >
> > MTD_SPI_NOR_MULTI_ERASE_SIZE defaults to N, so existing configurations are
> > unaffected.
>
> No, not a new Kconfig option. Integrate it into the core, adapt the
> current erase handling.

OK. I'll rework the series to integrate multi-size uniform erases
into the core erase path rather than adding a new Kconfig option. These
patches were posted to discuss the approach.

>
> Also, was this assisted by AI tooling?

AI tooling (Cursor) was used only for documentation, grammar, and the
commit message. I forgot to note that in the cover letter; I'll add
attribution in the next revision.

>
> > Tested: backported to a 6.6-based tree on Micron MT25QU02G with
> > MTD_SPI_NOR_MULTI_ERASE_SIZE enabled and MTD_SPI_NOR_USE_4K_SECTORS
>
> Why didn't you test this on the latest kernel?

6.6 is the latest kernel we currently run on this hardware, and these
patches were posted for early feedback. I'll test the final version on the
latest upstream kernel before resubmitting.

>
> > disabled (mtd->erasesize reports 64 KiB). librsu erases the flash with
>
> What is librsu?

A lightly modified Remote System Update (RSU) stack for Agilex:
https://github.com/altera-fpga/intel-rsu

>
> -michael

Sorry for the late reply - my corporate mailbox dropped the message, and
I only found the reply today on mailing list.

Thanks for the review.

Mateusz

>
> > the MEMERASE ioctl on the MTD character device, issuing erase requests
> > smaller than mtd->erasesize (e.g. a 32 KiB boot header region).
> > mtd_erase() does not enforce erasesize alignment, so these requests reach
> > the driver, where the previous uniform path rejected them; they now
> > succeed through spi_nor_is_uniform_erasable() and the multi-size erase
> > path. Verified writes and erases on the 32 KiB region.
> >
> > A few implementation details are worth discussing:
> >
> > 1. The previous uniform erase path only required the length to be a
> > multiple of mtd->erasesize. With MTD_SPI_NOR_MULTI_ERASE_SIZE enabled,
> > spi_nor_is_uniform_erasable() instead checks the address and length
> > against the smallest supported uniform erase size. Requests aligned to
> > mtd->erasesize still pass (it is a multiple of that size), while
> > callers may now issue erases smaller than mtd->erasesize, as the tested
> > librsu path does. Misaligned requests are rejected rather than
> > relying on undefined behavior; please report any regressions.
> >
> > 2. Patch 3 addresses per-step spi_nor_find_best_erase_type() overhead.
> > As a PoC it may be dropped, revised, or split out depending on
> > maintainer feedback.
> >
> > 3. Patch 3 calculates the largest erase size on every request. This could
> > be done once at init. The same applies to the smallest erase size used
> > for request validation. Where to store that data is open for
> > discussion if such a change is needed.
> >
> > 4. spansion_nor_late_init() overrides nor->erase_opcode (and mtd->erasesize)
> > for flashes larger than 16 MiB. With MTD_SPI_NOR_MULTI_ERASE_SIZE enabled,
> > spi_nor_erase_uniform() sets nor->erase_opcode before each erase, so the
> > late_init value is not used on the erase path. If the SFDP table masks
> > unsupported erase types in 4-byte-address mode, this is not an issue;
> > otherwise late_init() or erase-type masking may need changes for
> > Cypress/Spansion parts.
> >
> > 5. Some flashes do not support every erase type with 4-byte-address opcodes.
> > Unsupported types are masked by clearing erase_type[].size, but the
> > corresponding erase_mask bit is not cleared. Erases work correctly, but
> > debugfs can show a set bit in the sector-map erase mask for a type that is
> > not listed under "erase commands". Fixing that is probably best done in
> > a separate patch.
> >
> > Signed-off-by: Mateusz Litwin <mateusz.litwin@xxxxxxxxx>
> > ---
> > Mateusz Litwin (3):
> > mtd: spi-nor: allow multiple erase sizes on uniform flash
> > mtd: spi-nor: add dedicated multi-size uniform erase path
> > mtd: spi-nor: skip erase type search in uniform bulk erase
> >
> > drivers/mtd/spi-nor/Kconfig | 25 +++++
> > drivers/mtd/spi-nor/core.c | 247 +++++++++++++++++++++++++++++++++-----------
> > 2 files changed, 213 insertions(+), 59 deletions(-)
> > ---
> > base-commit: df415c5e1de0f1aeefacb4e6252ff98d38c04437
> > change-id: 20260720-spi_nor_multisize_erase-d644cfd4a5fb
> >
> > Best regards,
>
>