]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
bhyve: fix NVMe emulation missed interrupts
authorchuck <chuck@FreeBSD.org>
Fri, 27 Mar 2020 15:28:22 +0000 (15:28 +0000)
committerchuck <chuck@FreeBSD.org>
Fri, 27 Mar 2020 15:28:22 +0000 (15:28 +0000)
commit83fb88ee4fc00b1347b523a5949f141a949a1810
tree8cdadcba16d2c3a37ecc40a9d57cd3f1a50b646d
parentf4857fcc18f5f70d3262e7f66104bc263bd4e74a
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