[RFC PATCH 0/8] mtd: spi-nor: read while write support

Miquel Raynal miquel.raynal at bootlin.com
Wed May 25 09:31:00 PDT 2022


Hello folks,

I've been thinking lately about a solution to make mtd a little bit less
serialized in order to gain performances in different situations, and
today I am focusing on enabling reads during writes on a multi-bank
SPI-NOR chip. I've had the I/O scheduler feature in mind for a long time
but the more I thought about it, the less relevant it became. While
drafting ideas on paper and looking at the actual spi-nor code (which by
the way is much _much_ cleaner these days than it was before, thanks for
all that work!), it appeared to me that just playing a little bit with
the locking mechanism could save us from a massively incompatible
mtd-wide series, and so this is the path I took.

This RFC really is an attempt at supporting Macronix read-while-write
feature. It has not yet been tested, I am waiting to receive the
relevant hardware, but the main idea should remain the same over the
iterations, unless something big gets discovered in the mean time.

There is nothing Macronix specific in the implementation, the operations
and opcodes are exactly the same as before. The only difference being:
we may consider the chip usable when it is in the busy state during a
write or an erase. Any chip with an internal split allowing to perform
parallel operations might possibly leverage the benefits of this
implementation.

The first patches are just refactoring and preparation work, there is
almost no functional change, it's just a way to prepare the introduction
of the new locking mechanism and hopefully provide the cleanest and
simplest diff possible for this new feature. The actual change is all
contained in "mtd: spi-nor: Enhance locking to support reads while
writes". The logic is described in the commit log and copy/pasted here
for clarity:

"
The following constraints have to be taken into account:
1#: A single operation can be performed in a given bank.
2#: Only a single program or erase operation can happen on the entire chip.
3#: The I/O bus is unique and thus is the most constrained resource, all
    spi-nor operations requiring access to the spi bus (through the spi
    controller) must be serialized until the bus exchanges are over. So
    we must ensure a single operation can be "sent" at a time.
4#: Any other operation that would not be either a read or a write or an
    erase is considered requiring access to the full chip and cannot be
    parallelized, we then need to ensure the full chip is in the idle
    state when this occurs.

All these constraints can easily be managed with a proper locking model:
1#: Is protected by a per-bank mutex. Only a single operation can happen
    in a specific bank at any times. If the bank mutex is not available,
    the operation cannot start.
2#: Is handled by the pe_mode mutex which is acquired before any write
    or erase, and is released only at the very end of the
    operation. This way, no other destructive operation on the chip can
    start during this time frame.
3#: A device-wide mutex is introduced in order to capture and serialize
    bus accessed. This is the one being released "sooner" than before,
    because we only need to protect the chip against other SPI accesses
    during the I/O phase, which for the destructive operations is the
    beginning of the operation (when we send the command cycles and
    eventually the data), while the second part of the operation (the
    erase delay or the programmation delay) is when we can do something
    else with another bank.
4#: Is handled by the "generic" helpers which existed before, where
    basically all the locks are taken before the operation can start,
    and all locks are released once done.

As many devices still do not support this feature, the original lock is
also kept in a union: either the feature is available and we initialize
and use the new locks, or it is not and we keep using the previous
logic.
"

I am not 100% sure yet this approach is the right one, nor if the
results will be outstanding. For now I've prepared a patch [1] for the
flash_speed.c test tool in order to measure the impact.

Feedback, remarks and thoughs are welcome!

[1] https://github.com/miquelraynal/mtd-utils/compare/master...rww

Cheers,
Miquèl

Miquel Raynal (8):
  mtd: spi-nor: Create macros to define chip IDs and geometries
  mtd: spi-nor: Introduce the concept of bank
  mtd: spi-nor: Add a macro to define more banks
  mtd: spi-nor: Reorder the preparation vs locking steps
  mtd: spi-nor: Separate preparation and locking
  mtd: spi-nor: Prepare the introduction of a new locking mechanism
  mtd: spi-nor: Add a RWW flag
  mtd: spi-nor: Enhance locking to support reads while writes

 drivers/mtd/spi-nor/core.c  | 217 ++++++++++++++++++++++++++++++++----
 drivers/mtd/spi-nor/core.h  |  61 +++++-----
 include/linux/mtd/spi-nor.h |  12 +-
 3 files changed, 240 insertions(+), 50 deletions(-)

-- 
2.34.1




More information about the linux-mtd mailing list