Skip site navigation (1)Skip section navigation (2)
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>