Print this page
MFV: illumos-gate@48d370f1e98a10b1bdf160dd83a49e0f49f6c1b7
9809 nvme driver should attach to all NVMe 1.x devices
9810 Update parts of NVMe headers for newer specs
9811 nvmeadm(1M) should have ctf
Reviewed by: Hans Rosenfeld <hans.rosenfeld@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Andy Fiddaman <omnios@citrus-it.co.uk>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: Robert Mustacchi <rm@joyent.com>
NEX-18067 Catch up with illumos 8806 8805
8806 xattr_dir_inactive() releases used vnode with kernel panic
Reviewed by: Marcel Telka <marcel@telka.sk>
Reviewed by: Gordon Ross <gordon.w.ross@gmail.com>
Approved by: Dan McDonald <danmcd@joyent.com>
8805 xattr_dir_lookup() can leak a vnode hold
Reviewed by: Marcel Telka <marcel@telka.sk>
Reviewed by: Gordon Ross <gordon.w.ross@gmail.com>
Approved by: Dan McDonald <danmcd@joyent.com>
NEX-17991 emulated NVMe controller on ESXi 6.7 fails to attach
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-16749 some NVMe controllers get upset about NS ID of 0 when checking "Error Recovery" feature
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-16880 update NVME code
8804 nvme: add alias for pciclass,010802
Reviewed by: Peter Tribble <peter.tribble@gmail.com>
Reviewed by: Michal Nowak <mnowak@startmail.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
8979 nvmeadm(1m): ctl/[ns] -> ctl[/ns]
Reviewed by: Yuri Pankov <yuripv@gmx.com>
Reviewed by: Rich Lowe <richlowe@richlowe.net>
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>
8945 nvme panics when async events are not supported
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Reviewed by: Michal Nowak <mnowak@startmail.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-16549 nvme: "programming error: invalid NS/format" doing 'nvmeadm list' on a controller without namespaces
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-15208 nvme: Software Progress Marker feature is optional
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
NEX-8020 illumos nvme changes
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-7539 nvme fails to get error log page from Samsung PM1725
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-7538 nvme shouldn't ignore namespaces that support extended data LBAs
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-7373 nvme queue DMA attribute count_max is 0-based
Reviewed by: Gordon Ross <gordon.ross@nexenta.com
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-7369 bump nvme admin command timeout to 1s
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-6740 nvme checksum errors with blocksize < 4096
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-7349 nvme ignores interrupt enabling failure
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-7336 nvme initial interrupt issues
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-7322 nvme fix from Tegile needs a fix
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-7321 nvme version number check is broken again
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-7291 several small nvme fixes from Tegile
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-7290 nvme: id_nlbaf field is 0-based
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-7236 nvme shouldn't use ddi_intr_enable/disable to block interrupts
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
NEX-5192 Samsung SSD SM951-NVMe shows checksum errors
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-5792 support NVMe namespace EUI64
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-6132 nvmeadm(1M) get-feature command could use some cleanup
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-6130 basic NVMe 1.1 support
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-5791 support NVMe volatile write cache
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-4431 want NVMe management utility
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-4849 nvme version number check is broken
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Robert Mustacchi <rm@joyent.com>
NEX-4850 off-by-one in nvme_get_logpage()
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Robert Mustacchi <rm@joyent.com>
NEX-4427 blkdev should provide the device_error kstat for iostat -E
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
NEX-4424 kstat module needs cleanup
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
NEX-4420 format(1M) should be able to use device inquiry properties
Reviewed by: Dan McDonald <danmcd@omniti.com>
NEX-4419 blkdev and blkdev drivers should provide inquiry properties
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-2182 need driver for Intel NVM Express (nvme)
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
NEX-2182 need driver for Intel NVM Express (nvme) (preview)
Reviewed by: Dan Fields <dan.fields@nexenta.com>
@@ -8,14 +8,14 @@
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
- * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.
* Copyright 2016 Tegile Systems, Inc. All rights reserved.
* Copyright (c) 2016 The MathWorks, Inc. All rights reserved.
- * Copyright 2017 Joyent, Inc.
+ * Copyright 2018 Joyent, Inc.
*/
/*
* blkdev driver for NVMe compliant storage devices
*
@@ -81,12 +81,12 @@
* Namespace Support:
*
* NVMe devices can have multiple namespaces, each being a independent data
* store. The driver supports multiple namespaces and creates a blkdev interface
* for each namespace found. Namespaces can have various attributes to support
- * thin provisioning and protection information. This driver does not support
- * any of this and ignores namespaces that have these attributes.
+ * protection information. This driver does not support any of this and ignores
+ * namespaces that have these attributes.
*
* As of NVMe 1.1 namespaces can have an 64bit Extended Unique Identifier
* (EUI64). This driver uses the EUI64 if present to generate the devid and
* passes it to blkdev to use it in the device node names. As this is currently
* untested namespaces with EUI64 are ignored by default.
@@ -194,11 +194,11 @@
* Driver Configuration:
*
* The following driver properties can be changed to control some aspects of the
* drivers operation:
* - strict-version: can be set to 0 to allow devices conforming to newer
- * versions or namespaces with EUI64 to be used
+ * major versions to be used
* - ignore-unknown-vendor-status: can be set to 1 to not handle any vendor
* specific command status as a fatal error leading device faulting
* - admin-queue-len: the maximum length of the admin queue (16-4096)
* - io-queue-len: the maximum length of the I/O queues (16-65536)
* - async-event-limit: the maximum number of asynchronous event requests to be
@@ -256,14 +256,35 @@
#endif
#include "nvme_reg.h"
#include "nvme_var.h"
+/*
+ * Assertions to make sure that we've properly captured various aspects of the
+ * packed structures and haven't broken them during updates.
+ */
+CTASSERT(sizeof (nvme_identify_ctrl_t) == 0x1000);
+CTASSERT(offsetof(nvme_identify_ctrl_t, id_oacs) == 256);
+CTASSERT(offsetof(nvme_identify_ctrl_t, id_sqes) == 512);
+CTASSERT(offsetof(nvme_identify_ctrl_t, id_subnqn) == 768);
+CTASSERT(offsetof(nvme_identify_ctrl_t, id_nvmof) == 1792);
+CTASSERT(offsetof(nvme_identify_ctrl_t, id_psd) == 2048);
+CTASSERT(offsetof(nvme_identify_ctrl_t, id_vs) == 3072);
+CTASSERT(sizeof (nvme_identify_nsid_t) == 0x1000);
+CTASSERT(offsetof(nvme_identify_nsid_t, id_fpi) == 32);
+CTASSERT(offsetof(nvme_identify_nsid_t, id_nguid) == 104);
+CTASSERT(offsetof(nvme_identify_nsid_t, id_lbaf) == 128);
+CTASSERT(offsetof(nvme_identify_nsid_t, id_vs) == 384);
+
+CTASSERT(sizeof (nvme_identify_primary_caps_t) == 0x1000);
+CTASSERT(offsetof(nvme_identify_primary_caps_t, nipc_vqfrt) == 32);
+CTASSERT(offsetof(nvme_identify_primary_caps_t, nipc_vifrt) == 64);
+
+
/* NVMe spec version supported */
static const int nvme_version_major = 1;
-static const int nvme_version_minor = 2;
/* tunable for admin command timeout in seconds, default is 1s */
int nvme_admin_cmd_timeout = 1;
/* tunable for FORMAT NVM command timeout in seconds, default is 600s */
@@ -1082,11 +1103,11 @@
case NVME_CQE_SC_GEN_INV_NS:
/* Invalid Namespace or Format */
if (!cmd->nc_dontpanic)
dev_err(cmd->nc_nvme->n_dip, CE_PANIC,
- "programming error: " "invalid NS/format in cmd %p",
+ "programming error: invalid NS/format in cmd %p",
(void *)cmd);
return (EINVAL);
case NVME_CQE_SC_GEN_NVM_LBA_RANGE:
/* LBA Out Of Range */
@@ -1853,44 +1874,53 @@
cmd->nc_callback = nvme_wakeup_cmd;
cmd->nc_sqe.sqe_opc = NVME_OPC_GET_FEATURES;
cmd->nc_sqe.sqe_cdw10 = feature;
cmd->nc_sqe.sqe_cdw11 = *res;
+ /*
+ * For some of the optional features there doesn't seem to be a method
+ * of detecting whether it is supported other than using it. This will
+ * cause "Invalid Field in Command" error, which is normally considered
+ * a programming error. Set the nc_dontpanic flag to override the panic
+ * in nvme_check_generic_cmd_status().
+ */
switch (feature) {
case NVME_FEAT_ARBITRATION:
case NVME_FEAT_POWER_MGMT:
case NVME_FEAT_TEMPERATURE:
- case NVME_FEAT_ERROR:
case NVME_FEAT_NQUEUES:
case NVME_FEAT_INTR_COAL:
case NVME_FEAT_INTR_VECT:
case NVME_FEAT_WRITE_ATOM:
case NVME_FEAT_ASYNC_EVENT:
- case NVME_FEAT_PROGRESS:
break;
+ case NVME_FEAT_ERROR:
+ /*
+ * Per-namespace Deallocated or Unwritten Logical Block
+ * Error Enable (DULBE) feature was added after initial NVMe
+ * specification, but we currently only check this feature with
+ * NS ID of 0 (the controller itself), and some controllers get
+ * upset, reporting the error. For the moment, override the
+ * panic by setting the nc_dontpanic flag.
+ */
+ cmd->nc_dontpanic = B_TRUE;
+ break;
+
case NVME_FEAT_WRITE_CACHE:
if (!nvme->n_write_cache_present)
goto fail;
break;
case NVME_FEAT_LBA_RANGE:
if (!nvme->n_lba_range_supported)
goto fail;
- /*
- * The LBA Range Type feature is optional. There doesn't seem
- * be a method of detecting whether it is supported other than
- * using it. This will cause a "invalid field in command" error,
- * which is normally considered a programming error and causes
- * panic in nvme_check_generic_cmd_status().
- */
cmd->nc_dontpanic = B_TRUE;
cmd->nc_sqe.sqe_nsid = nsid;
ASSERT(bufsize != NULL);
*bufsize = NVME_LBA_RANGE_BUFSIZE;
-
break;
case NVME_FEAT_AUTO_PST:
if (!nvme->n_auto_pst_supported)
goto fail;
@@ -1897,10 +1927,17 @@
ASSERT(bufsize != NULL);
*bufsize = NVME_AUTO_PST_BUFSIZE;
break;
+ case NVME_FEAT_PROGRESS:
+ if (!nvme->n_progress_supported)
+ goto fail;
+
+ cmd->nc_dontpanic = B_TRUE;
+ break;
+
default:
goto fail;
}
if (bufsize != NULL && *bufsize != 0) {
@@ -1931,19 +1968,38 @@
}
nvme_admin_cmd(cmd, nvme_admin_cmd_timeout);
if ((ret = nvme_check_cmd_status(cmd)) != 0) {
- if (feature == NVME_FEAT_LBA_RANGE &&
- cmd->nc_cqe.cqe_sf.sf_sct == NVME_CQE_SCT_GENERIC &&
- cmd->nc_cqe.cqe_sf.sf_sc == NVME_CQE_SC_GEN_INV_FLD)
+ boolean_t known = B_TRUE;
+
+ /* Check if this is unsupported optional feature */
+ if (cmd->nc_cqe.cqe_sf.sf_sct == NVME_CQE_SCT_GENERIC &&
+ cmd->nc_cqe.cqe_sf.sf_sc == NVME_CQE_SC_GEN_INV_FLD) {
+ switch (feature) {
+ case NVME_FEAT_LBA_RANGE:
nvme->n_lba_range_supported = B_FALSE;
- else
+ break;
+ case NVME_FEAT_PROGRESS:
+ nvme->n_progress_supported = B_FALSE;
+ break;
+ default:
+ known = B_FALSE;
+ break;
+ }
+ } else {
+ known = B_FALSE;
+ }
+
+ /* Report the error otherwise */
+ if (!known) {
dev_err(nvme->n_dip, CE_WARN,
"!GET FEATURES %d failed with sct = %x, sc = %x",
feature, cmd->nc_cqe.cqe_sf.sf_sct,
cmd->nc_cqe.cqe_sf.sf_sc);
+ }
+
goto fail;
}
if (bufsize != NULL && *bufsize != 0) {
ASSERT(buf != NULL);
@@ -2197,20 +2253,17 @@
if (ns->ns_best_block_size < nvme->n_min_block_size)
ns->ns_best_block_size = nvme->n_min_block_size;
/*
* We currently don't support namespaces that use either:
- * - thin provisioning
* - protection information
* - illegal block size (< 512)
*/
- if (idns->id_nsfeat.f_thin ||
- idns->id_dps.dp_pinfo) {
+ if (idns->id_dps.dp_pinfo) {
dev_err(nvme->n_dip, CE_WARN,
- "!ignoring namespace %d, unsupported features: "
- "thin = %d, pinfo = %d", nsid,
- idns->id_nsfeat.f_thin, idns->id_dps.dp_pinfo);
+ "!ignoring namespace %d, unsupported feature: "
+ "pinfo = %d", nsid, idns->id_dps.dp_pinfo);
ns->ns_ignore = B_TRUE;
} else if (ns->ns_block_size < 512) {
dev_err(nvme->n_dip, CE_WARN,
"!ignoring namespace %d, unsupported block size %"PRIu64,
nsid, (uint64_t)ns->ns_block_size);
@@ -2242,14 +2295,13 @@
nvme->n_version.v_major = vs.b.vs_mjr;
nvme->n_version.v_minor = vs.b.vs_mnr;
dev_err(nvme->n_dip, CE_CONT, "?NVMe spec version %d.%d",
nvme->n_version.v_major, nvme->n_version.v_minor);
- if (NVME_VERSION_HIGHER(&nvme->n_version,
- nvme_version_major, nvme_version_minor)) {
- dev_err(nvme->n_dip, CE_WARN, "!no support for version > %d.%d",
- nvme_version_major, nvme_version_minor);
+ if (nvme->n_version.v_major > nvme_version_major) {
+ dev_err(nvme->n_dip, CE_WARN, "!no support for version > %d.x",
+ nvme_version_major);
if (nvme->n_strict_version)
goto fail;
}
/* retrieve controller configuration */
@@ -2519,13 +2571,26 @@
if (NVME_VERSION_ATLEAST(&nvme->n_version, 1, 1))
nvme->n_auto_pst_supported =
nvme->n_idctl->id_apsta.ap_sup == 0 ? B_FALSE : B_TRUE;
/*
+ * Assume Software Progress Marker feature is supported. If it isn't
+ * this will be set to B_FALSE by nvme_get_features().
+ */
+ nvme->n_progress_supported = B_TRUE;
+
+ /*
* Identify Namespaces
*/
nvme->n_namespace_count = nvme->n_idctl->id_nn;
+
+ if (nvme->n_namespace_count == 0) {
+ dev_err(nvme->n_dip, CE_WARN,
+ "!controllers without namespaces are not supported");
+ goto fail;
+ }
+
if (nvme->n_namespace_count > NVME_MINOR_MAX) {
dev_err(nvme->n_dip, CE_WARN,
"!too many namespaces: %d, limiting to %d\n",
nvme->n_namespace_count, NVME_MINOR_MAX);
nvme->n_namespace_count = NVME_MINOR_MAX;