HomeFreeBSD

bhyve: fix NVMe emulation missed interrupts

Description

bhyve: fix NVMe emulation missed interrupts

The bhyve NVMe emulation has a race in the logic which generates command
completion interrupts. On FreeBSD guests, this manifests as kernel log
messages similar to:

nvme0: Missing interrupt

The NVMe emulation code sets a per-submission queue "busy" flag while
processing the submission queue, and only generates an interrupt when
the submission queue is not busy.

Aside from being counter to the NVMe design (i.e. interrupt properties
are tied to the completion queue) and adding complexity (e.g. exceptions
to not generating an interrupt when "busy"), it causes a race condition
under the following conditions:

  • guest OS has no outstanding interrupts
  • guest OS submits a single NVMe IO command
  • bhyve emulation processes the SQ and sets the "busy" flag
  • bhyve emulation submits the asynchronous IO to the backing storage
  • IO request to the backing storage completes before the SQ processing loop exits and doesn't generate an interrupt because the SQ is "busy"
  • bhyve emulation finishes processing the SQ and clears the "busy" flag

Fix is to remove the "busy" flag and generate an interrupt when the CQ
head and tail pointers do not match.

Reported by: khng300
Reviewed by: jhb, imp
Approved by: jhb (maintainer)
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D24082

Details

Provenance
chuckAuthored on
Reviewer
jhb
Differential Revision
D24082: bhyve: fix NVMe emulation missed interrupts
Parents
rS359365: bhyve: use STAILQ in NVMe emulation
Branches
Unknown
Tags
Unknown