Skip to content

femu/nand: let a read preempt an in-flight program or erase - #204

Open
wnsah814 wants to merge 1 commit into
MoatLab:masterfrom
wnsah814:nand-pe-suspend
Open

wnsah814 wants to merge 1 commit into
MoatLab:masterfrom
wnsah814:nand-pe-suspend

Conversation

@wnsah814

Copy link
Copy Markdown
Contributor

Description

nand-media.c already has a program/erase suspend model (policy.pe_suspend, timing.tsusp_ns: a read that finds its LUN mid-P/E starts after a suspend overhead and the P/E resumes after it, as NAND P/E suspension does, cf. Wu & He, FAST '12). Nothing could use it: no device property set the fields, and the branch existed only in the opt-in staged channel path. On the default gates every read on a busy LUN queues behind whatever the LUN is doing, and for bbssd that is a whole line GC, which parks all 64 LUNs for one burst (~56 ms here) and any read that lands in it.

This applies the same arithmetic on the plain gates (the lock-free LUN gate and the plane / lun+plane gates) and exposes the knobs: pe_suspend / tsusp_ns for bbssd, zns_pe_suspend / zns_tsusp_ns for ZNS. Only reads preempt. Both default to off, so existing configurations are bit-identical; README lists the knobs.

bbssd, 8ch × 8 LUN, 40/200 µs, 2 ms erase, op 25 %, aged by two full sequential passes; 4 KiB QD1 random reads for 40 s with four QD16 random-write jobs driving GC:

pe_suspend=0 pe_suspend=1, tsusp_ns=10000
read p50 / p99 / p99.99 150 / 55,837 / 111,673 µs 51 / 140 / 2,671 µs
read mean / IOPS 1,295 µs / 766 55 µs / 16,378
background write IOPS 8,329 8,195

Off, p99 is exactly one GC burst and p99.99 two. On, the same GC runs and the write side is unchanged; a read costs tsusp + tR.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Code refactoring

Testing

  • I have tested my changes locally
  • I have added tests that prove my fix is effective or that my feature works
  • All existing tests pass
  • I have tested across multiple FEMU modes (if applicable)

FEMU Modes Tested

  • BlackBox SSD (BBSSD)
  • WhiteBox SSD (OCSSD)
  • Zoned Namespace SSD (ZNSSD)
  • NoSSD
  • Not applicable

Platform Testing

  • Ubuntu 20.04/22.04
  • Other distributions (specify): ___________
  • Build verification completed

Checklist

  • My code follows QEMU coding standards
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new compiler warnings
  • I have updated documentation if necessary
  • No trailing whitespace or C++ style comments in C files

The media layer carries a program/erase suspend model: a read that
finds its LUN mid-P/E starts after a suspend overhead instead of
waiting the operation out, and the suspended operation resumes after
the read. Nothing could use it. The two fields, policy.pe_suspend and
timing.tsusp_ns, had no device property and no controller set them,
and the branch sat only in the staged channel path, which is opt-in
and off in the default configuration. Every read on a busy LUN queued
behind whatever the LUN was doing.

For the plain gates that is a full line of garbage collection. bbssd
puts a line's copies and erases on all its LUNs at once, so one GC
holds every LUN for the length of the burst (about 90 ms with a 64-LUN
line at 40/200 us and 2 ms erase) and a host read arriving during it
waits for the rest of the burst. Real controllers localize collection
and suspend the array for host reads, and the model FEMU already had
written down does exactly that.

Apply the same arithmetic on the plain gates: on the lock-free LUN
gate inside the CAS loop, and on the plane and lun+plane gates by
pushing back each timeline that was busy at the read's arrival. Only
reads preempt; programs and erases still queue. Expose the knobs as
pe_suspend / tsusp_ns (bbssd) and zns_pe_suspend / zns_tsusp_ns (ZNS),
named like the other timing knobs, both off by default, so existing
configurations stay bit-identical. A negative ZNS overhead is refused
at realize like the other ZNS timing values.

In an F2FS multi-device YCSB-A run whose CNS share put the device into
sustained line GC, the same run with reads preempting GC kept the GC
copy volume (263-318 GB per run) and recovered throughput from -24%
to -2% of the no-GC configuration, with the mean read latency back at
its no-GC value. The unit test covers off, the LUN gate, the plane
gate, that a program does not preempt, and the staged path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant