Date: Mon, 29 Jun 2020 00:31:17 +0000 (UTC) From: Chuck Tuffli <chuck@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r362746 - head/usr.sbin/bhyve Message-ID: <202006290031.05T0VHcn046225@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: chuck Date: Mon Jun 29 00:31:17 2020 New Revision: 362746 URL: https://svnweb.freebsd.org/changeset/base/362746 Log: bhyve: implement NVMe Flush command This adds support for the NVMe I/O command Flush. For block-based devices, submit a DIOCGFLUSH to the backing storage. Otherwise, command is treated like a NOP and completes with a Successful status. Tested by: Jason Tubnor MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D24880 Modified: head/usr.sbin/bhyve/pci_nvme.c Modified: head/usr.sbin/bhyve/pci_nvme.c ============================================================================== --- head/usr.sbin/bhyve/pci_nvme.c Mon Jun 29 00:31:14 2020 (r362745) +++ head/usr.sbin/bhyve/pci_nvme.c Mon Jun 29 00:31:17 2020 (r362746) @@ -58,6 +58,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/errno.h> #include <sys/types.h> #include <net/ieee_oui.h> @@ -1387,7 +1388,47 @@ pci_nvme_io_partial(struct blockif_req *br, int err) pthread_cond_signal(&req->cv); } +/* + * Implements the Flush command. The specification states: + * If a volatile write cache is not present, Flush commands complete + * successfully and have no effect + * in the description of the Volatile Write Cache (VWC) field of the Identify + * Controller data. Therefore, set status to Success if the command is + * not supported (i.e. RAM or as indicated by the blockif). + */ static bool +nvme_opc_flush(struct pci_nvme_softc *sc, + struct nvme_command *cmd, + struct pci_nvme_blockstore *nvstore, + struct pci_nvme_ioreq *req, + uint16_t *status) +{ + bool pending = false; + + if (nvstore->type == NVME_STOR_RAM) { + pci_nvme_status_genc(status, NVME_SC_SUCCESS); + } else { + int err; + + req->io_req.br_callback = pci_nvme_io_done; + + err = blockif_flush(nvstore->ctx, &req->io_req); + switch (err) { + case 0: + pending = true; + break; + case EOPNOTSUPP: + pci_nvme_status_genc(status, NVME_SC_SUCCESS); + break; + default: + pci_nvme_status_genc(status, NVME_SC_INTERNAL_DEVICE_ERROR); + } + } + + return (pending); +} + +static bool nvme_opc_write_read(struct pci_nvme_softc *sc, struct nvme_command *cmd, struct pci_nvme_blockstore *nvstore, @@ -1682,7 +1723,8 @@ pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint switch (cmd->opc) { case NVME_OPC_FLUSH: - pci_nvme_status_genc(&status, NVME_SC_SUCCESS); + pending = nvme_opc_flush(sc, cmd, &sc->nvstore, + req, &status); break; case NVME_OPC_WRITE: case NVME_OPC_READ:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202006290031.05T0VHcn046225>