Skip to content

drivers/nvme: make interrupt coalescing opt-in, default off for low latency - #1481

Open
gburd wants to merge 1 commit into
cloudius-systems:masterfrom
gburd:pr/nvme-int-coalescing
Open

drivers/nvme: make interrupt coalescing opt-in, default off for low latency#1481
gburd wants to merge 1 commit into
cloudius-systems:masterfrom
gburd:pr/nvme-int-coalescing

Conversation

@gburd

@gburd gburd commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

The NVMe driver unconditionally programmed interrupt coalescing (threshold=20, time=2, a 200us completion-aggregation window) on every non-QEMU controller. Coalescing reduces interrupt load for deep, streaming I/O, but it adds latency to low-queue-depth synchronous I/O: a request that issues a single command and waits for its completion pays the full aggregation-timer delay on every such operation.

This hurts barrier-style operations that dominate database and journaling workloads (an fsync, a filesystem journal commit, a ZFS ZIL commit), where each commit issues one FLUSH and waits for it. With the 200us window, every commit is delayed up to 200us before its completion interrupt fires, capping synchronous write throughput.

Change

  • Default to no interrupt coalescing (lowest completion latency).
  • Opt back in via OSV_NVME_INT_COALESCING="threshold,time100us" for workloads that prefer fewer interrupts (threshold in completions, time in 100us units, matching the NVMe Set Features encoding).
  • The real-controller guard is preserved, since QEMU's emulated controller ignores the feature.

Measured effect

On real NVMe, disabling coalescing measurably improves synchronous-commit write throughput at low-to-moderate concurrency. There is a genuine tradeoff: streaming read throughput benefits from coalescing, so the env knob lets those workloads restore it. Defaulting off favors latency-sensitive workloads, which is the more common surprise when moving from an emulated controller (no coalescing) to real hardware.

…atency

The driver unconditionally programmed NVMe interrupt coalescing with
threshold=20, time=2 (a 200us completion-aggregation window) on every
non-QEMU controller. Coalescing reduces interrupt load for deep, streaming
IO, but it adds latency to low-queue-depth synchronous IO: a request that
issues a single command and waits for its completion (a database fsync, a
filesystem journal or ZFS ZIL commit, and similar barrier operations) pays
the full aggregation-timer delay on every such operation, which caps
synchronous throughput.

Default to no coalescing for the lowest completion latency, and let workloads
that prefer fewer interrupts opt back in with
OSV_NVME_INT_COALESCING="threshold,time100us" (threshold in completions,
time in 100us units, matching the NVMe Set Features encoding). The
real-controller guard is preserved since QEMU's emulated controller ignores
the feature.
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