Improve storage performance with read pipelining, run lookup, request merging, and counters
This commit is contained in:
1 parent
3d4f846a8f
commit
8e0ab3da8b
11 files changed
+546
-114
No files matched your search
@@ -219,3 +219,37 @@ Drop-in procedure replacements for callers using the old void-returning API. For
|
||||
- `dispatch_next` is an internal procedure called with interrupts disabled. It dequeues the head of the CFIFO, allocates a heap copy via `ioreq_copy` (for ISR safety), and invokes the appropriate `dispatchRead` or `dispatchWrite` on the device. If neither dispatch pointer is set, the request is failed with `eDeviceNotFound`.
|
||||
- The blocking path relies on pointer-dereferenced spin (`puint32(@wait.Done)^`) to prevent FPC from caching the `Done` flag in a register across the `hlt` instruction.
|
||||
- Devices without `dispatchRead`/`dispatchWrite` set (i.e., drivers not yet migrated to Phase 2) will have `submit_io` return `eDeviceNotFound`. Legacy drivers must be migrated before they can use the new I/O path.
|
||||
|
||||
|
||||
## Bounded performance path
|
||||
|
||||
The manager merges up to 32 consecutive queued requests when operation, device,
|
||||
LBA range, and virtual buffer range are contiguous. It never searches past the
|
||||
queue head or delays a lone request to create a merge. Drivers opt in through
|
||||
`mergeMaxSectors`; SATA AHCI advertises 65,536 sectors, while other drivers default
|
||||
to zero (disabled). A merged command delivers one completion to each original
|
||||
request, in FIFO order. A command error fails every member conservatively.
|
||||
|
||||
`storage_get_stats` takes an interrupt-protected snapshot of the device counters.
|
||||
`DISK info <index>` displays accepted/completed/failed logical requests, hardware
|
||||
commands, merged requests, queue-full rejections, queue and active high-water
|
||||
marks, successful read/write sectors, request-size buckets, queue/service ticks,
|
||||
and FAT metadata cache hits/misses. Queue ticks are accumulated per logical
|
||||
request; service ticks are accumulated per hardware command. Tick values use
|
||||
`Counters.c32`, not milliseconds. Counters are unsigned 32-bit values, start at
|
||||
device registration, and wrap; use snapshot differences over bounded benchmark
|
||||
intervals. Size buckets are <=8, 9..256, and >256 sectors.
|
||||
|
||||
FAT32 blocking and async reads share a pooled transfer engine with batches of up
|
||||
to four outstanding reads, capped by device queue depth. Destination slices are
|
||||
disjoint. On any error, the engine drains every accepted request before releasing
|
||||
its context and reports only the contiguous successful byte prefix. Unaligned
|
||||
edges and odd DMA addresses use the context's private scratch sector. Writes
|
||||
remain sequential. Run maps store cumulative file-cluster offsets; an open-file
|
||||
cursor handles sequential locality and binary search handles random seeks.
|
||||
|
||||
`STORPERF` runs memory-backed regression checks (also included in boot unit tests)
|
||||
for reverse completion order, failures, unaligned reads, run lookup, queue
|
||||
rejection, merging limits, and callback accounting. It does not access real disks
|
||||
or measure hardware throughput. Compare counters alongside `STORBENCH` and file
|
||||
benchmarks on contiguous and fragmented files for actual performance validation.
|
||||
Reference in new issue
Block a user