Background
While porting an AT45DB641E to the current LevelX NAND implementation, we initially exposed the physical geometry directly:
total_blocks = 4096
pages_per_block = 8
bytes_per_page = 256
This geometry caused repeated calls to _lx_nand_flash_metadata_allocate() while _lx_nand_flash_metadata_build() was writing a complete metadata snapshot.
We later grouped four physical erase blocks into one virtual LevelX block:
total_blocks = 1024
pages_per_block = 32
bytes_per_page = 256
The driver erases all four physical erase blocks when LevelX requests an erase of one virtual block.
Metadata snapshot size
_lx_nand_flash_metadata_build() writes:
- One device-information page
- The erase-count table
- The block-mapping table
- The block-status table
The required number of pages is:
snapshot_pages =
1
+ ceil(erase_count_table_size / bytes_per_page)
+ ceil(block_mapping_table_size / bytes_per_page)
+ ceil(block_status_table_size / bytes_per_page)
The table sizes are determined by the NAND geometry and are at least one page:
erase_count_table_size =
max(bytes_per_page, total_blocks * sizeof(UCHAR))
block_mapping_table_size =
max(bytes_per_page, total_blocks * sizeof(USHORT))
block_status_table_size =
max(bytes_per_page, total_blocks * sizeof(USHORT))
For the original 4096 × 8 geometry:
Device information: 1 page
Erase-count table: 16 pages
Block-mapping table: 32 pages
Block-status table: 32 pages
--------------------------------
Complete snapshot: 81 pages
The snapshot cannot fit into a LevelX block containing only eight pages.
For the virtual 1024 × 32 geometry:
Device information: 1 page
Erase-count table: 4 pages
Block-mapping table: 8 pages
Block-status table: 8 pages
--------------------------------
Complete snapshot: 21 pages
The snapshot fits into a 32-page LevelX block.
Problem
When the metadata chain reaches LX_NAND_FLASH_MAX_METADATA_BLOCKS, _lx_nand_flash_metadata_allocate() rebuilds the complete metadata snapshot by calling _lx_nand_flash_metadata_build().
_lx_nand_flash_metadata_write() calls _lx_nand_flash_metadata_allocate() whenever the current metadata block becomes full. If the snapshot does not fit, metadata allocation can therefore be entered again while a metadata rebuild is already in progress.
The current control flow also writes a block-link record after the snapshot. At least one additional page should remain available for a subsequent metadata update. This leads to the following apparent geometry requirement:
snapshot_pages + 2 <= pages_per_block
Equivalently, for integer page counts:
snapshot_pages < pages_per_block - 1
The original geometry violates this requirement:
The virtual geometry satisfies it:
With small pages_per_block, metadata blocks also fill very frequently. Every rebuild writes the complete snapshot to both the primary and backup metadata chains. An 81-page snapshot therefore requires at least 162 page programs, excluding block-link records, block allocations and erases.
Increasing LX_NAND_FLASH_MAX_METADATA_BLOCKS only postpones the rebuild. It does not make a geometry valid when the snapshot cannot fit into the block used during the rebuild.
Proposed change
Besides documenting this geometry requirement, lx_nand_flash_format_extended() and lx_nand_flash_open_extended() should calculate the snapshot size and reject unsupported geometries early with a clear error.
For example:
if snapshot_pages + 2 > pages_per_block:
return LX_NOT_SUPPORTED
This would prevent a configuration from formatting successfully or appearing to work until a later metadata-chain rebuild encounters the unsupported geometry.
The documentation should also explain that devices with small physical erase blocks may need to expose larger virtual LevelX blocks. If G physical erase blocks are grouped:
virtual_total_blocks = physical_total_blocks / G
virtual_pages_per_block = physical_pages_per_block * G
The driver must consistently map virtual pages and erase, verify and report the status of every physical block in the group.
For the AT45DB641E, grouping four physical blocks changes:
to:
1024 LevelX blocks × 32 pages
Regression tests
Maybe the following regression tests should be added:
-
A valid boundary geometry where:
snapshot_pages + 2 == pages_per_block
Formatting, opening and a metadata-chain rebuild should succeed.
-
An invalid geometry where:
snapshot_pages + 2 > pages_per_block
For example, the 4096 × 8 geometry with 256-byte pages requires an 81-page snapshot. Formatting and opening should reject this geometry with LX_NOT_SUPPORTED before writing metadata or entering recursive metadata allocation.
Background
While porting an AT45DB641E to the current LevelX NAND implementation, we initially exposed the physical geometry directly:
This geometry caused repeated calls to
_lx_nand_flash_metadata_allocate()while_lx_nand_flash_metadata_build()was writing a complete metadata snapshot.We later grouped four physical erase blocks into one virtual LevelX block:
The driver erases all four physical erase blocks when LevelX requests an erase of one virtual block.
Metadata snapshot size
_lx_nand_flash_metadata_build()writes:The required number of pages is:
The table sizes are determined by the NAND geometry and are at least one page:
For the original
4096 × 8geometry:The snapshot cannot fit into a LevelX block containing only eight pages.
For the virtual
1024 × 32geometry:The snapshot fits into a 32-page LevelX block.
Problem
When the metadata chain reaches
LX_NAND_FLASH_MAX_METADATA_BLOCKS,_lx_nand_flash_metadata_allocate()rebuilds the complete metadata snapshot by calling_lx_nand_flash_metadata_build()._lx_nand_flash_metadata_write()calls_lx_nand_flash_metadata_allocate()whenever the current metadata block becomes full. If the snapshot does not fit, metadata allocation can therefore be entered again while a metadata rebuild is already in progress.The current control flow also writes a block-link record after the snapshot. At least one additional page should remain available for a subsequent metadata update. This leads to the following apparent geometry requirement:
Equivalently, for integer page counts:
The original geometry violates this requirement:
The virtual geometry satisfies it:
With small
pages_per_block, metadata blocks also fill very frequently. Every rebuild writes the complete snapshot to both the primary and backup metadata chains. An 81-page snapshot therefore requires at least 162 page programs, excluding block-link records, block allocations and erases.Increasing
LX_NAND_FLASH_MAX_METADATA_BLOCKSonly postpones the rebuild. It does not make a geometry valid when the snapshot cannot fit into the block used during the rebuild.Proposed change
Besides documenting this geometry requirement,
lx_nand_flash_format_extended()andlx_nand_flash_open_extended()should calculate the snapshot size and reject unsupported geometries early with a clear error.For example:
This would prevent a configuration from formatting successfully or appearing to work until a later metadata-chain rebuild encounters the unsupported geometry.
The documentation should also explain that devices with small physical erase blocks may need to expose larger virtual LevelX blocks. If
Gphysical erase blocks are grouped:The driver must consistently map virtual pages and erase, verify and report the status of every physical block in the group.
For the AT45DB641E, grouping four physical blocks changes:
to:
Regression tests
Maybe the following regression tests should be added:
A valid boundary geometry where:
Formatting, opening and a metadata-chain rebuild should succeed.
An invalid geometry where:
For example, the
4096 × 8geometry with 256-byte pages requires an 81-page snapshot. Formatting and opening should reject this geometry withLX_NOT_SUPPORTEDbefore writing metadata or entering recursive metadata allocation.