]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
bhyve: fix NVMe emulation missed interrupts
authorChuck Tuffli <chuck@FreeBSD.org>
Fri, 27 Mar 2020 15:28:22 +0000 (15:28 +0000)
committerChuck Tuffli <chuck@FreeBSD.org>
Fri, 27 Mar 2020 15:28:22 +0000 (15:28 +0000)
commit961be12f6ad2383c20a5ac11d0f3e65fe6d1cc47
tree8cdadcba16d2c3a37ecc40a9d57cd3f1a50b646d
parentf3e46ff9324614bec8e0d96c550eb5409b86a317
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
usr.sbin/bhyve/pci_nvme.c