Skip to content

femu/zns: key write caches by the request's zone - #195

Open
wnsah814 wants to merge 1 commit into
MoatLab:masterfrom
wnsah814:zns-wc-keying
Open

femu/zns: key write caches by the request's zone#195
wnsah814 wants to merge 1 commit into
MoatLab:masterfrom
wnsah814:zns-wc-keying

Conversation

@wnsah814

Copy link
Copy Markdown
Contributor

Description

The ZNS write cache is looked up with the global active_zone variable, which the NVMe I/O path overwrites on every write and the FTL thread reads asynchronously. Under concurrent writers a request can be matched with a cache bound to a different zone: its LPNs are appended there and later flushed into that zone's block, corrupting the modeled placement, the per-plane statistics, and reset invalidation (zns_invalidate_zone_cache matches by sblk, so pre-reset writes can survive a reset). The cache struct already carries a per-cache sblk binding, so the lookup key was clearly meant to be the request's own zone.

This patch derives the zone from req->slba and uses it for both lookup and binding, and initializes sblk to INVALID_SBLK instead of 0..num_wc-1 (which falsely claimed zones 0..2 at boot).

Measured on current master with FEMU_DEBUG_ZFTL enabled, multipoller_enabled=1, and 3 fio writers on 3 zones (3 zones / 3 caches, so no eviction can occur): 99 of 6,144 writes (1.6%) were appended to a cache bound to a different zone, e.g.

[Misao] ZFTL-Dbg: [W] lpn: 65561 -->wc cache:2   (zone-1 LPN into zone-2's cache)
[Misao] ZFTL-Dbg: [W] lpn:    59 -->wc cache:2   (zone-0 LPN into zone-2's cache)

After the patch the key is derived from the request itself, so the mis-association is impossible by construction.

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)

Repro used for before/after verification (guest):

fio --name=w --filename=/dev/nvme0n1 --direct=1 --ioengine=psync --rw=write \
    --bs=4k --numjobs=3 --offset_increment=<zone_size> --size=<zone_size> \
    --io_size=8m --zonemode=zbd --group_reporting

Before: 1.6% cross-zone cache appends (debug trace). After: none. Write throughput at 1/2/4/8 jobs is unchanged within noise.

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

Related Issues

N/A

Additional Notes

  • Trigger conditions: with a single poller the producer sets active_zone immediately before enqueue and the FTL thread keeps up, so the mis-association is latent there (the same workload showed 0 occurrences); with multipoller_enabled=1, or whenever FTL dequeue lags submission, it is routine. The unsynchronized cross-thread access exists in both configurations.

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