summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorjimharris <jimharris@FreeBSD.org>2013-03-26 19:50:46 +0000
committerjimharris <jimharris@FreeBSD.org>2013-03-26 19:50:46 +0000
commit93fd264895a68a10d395cb75c7f67339f8811d4a (patch)
tree82359dedd1ed281aa3fd524aef64c2d6bb5a5a28 /sbin
parentbd33256583e92ae27c4215f57aa7bbdee3d50799 (diff)
downloadFreeBSD-src-93fd264895a68a10d395cb75c7f67339f8811d4a.zip
FreeBSD-src-93fd264895a68a10d395cb75c7f67339f8811d4a.tar.gz
Add controller reset capability to nvme(4) and ability to explicitly
invoke it from nvmecontrol(8). Controller reset will be performed in cases where I/O are repeatedly timing out, the controller reports an unrecoverable condition, or when explicitly requested via IOCTL or an nvme consumer. Since the controller may be in such a state where it cannot even process queue deletion requests, we will perform a controller reset without trying to clean up anything on the controller first. Sponsored by: Intel Reviewed by: carl
Diffstat (limited to 'sbin')
-rw-r--r--sbin/nvmecontrol/nvmecontrol.812
-rw-r--r--sbin/nvmecontrol/nvmecontrol.c41
2 files changed, 51 insertions, 2 deletions
diff --git a/sbin/nvmecontrol/nvmecontrol.8 b/sbin/nvmecontrol/nvmecontrol.8
index e726cbc..7e26240 100644
--- a/sbin/nvmecontrol/nvmecontrol.8
+++ b/sbin/nvmecontrol/nvmecontrol.8
@@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 17, 2012
+.Dd March 26, 2013
.Dt NVMECONTROL 8
.Os
.Sh NAME
@@ -54,7 +54,10 @@
.Op Fl p
.Aq Fl s Ar size_in_bytes
.Aq Fl t Ar time_in_sec
-.Aq device id
+.Aq namespace id
+.Nm
+.Ic reset
+.Aq controller id
.Sh DESCRIPTION
NVM Express (NVMe) is a storage protocol standard, for SSDs and other
high-speed storage devices over PCI Express.
@@ -62,6 +65,7 @@ high-speed storage devices over PCI Express.
.Dl nvmecontrol devlist
.Pp
Display a list of NVMe controllers and namespaces along with their device nodes.
+.Pp
.Dl nvmecontrol identify nvme0
.Pp
Display a human-readable summary of the nvme0 IDENTIFY_CONTROLLER data.
@@ -76,6 +80,10 @@ Display a hexadecimal dump of the nvme0 IDENTIFY_NAMESPACE data for namespace
Run a performance test on nvme0ns1 using 32 kernel threads for 30 seconds. Each
thread will issue a single 512 byte read command. Results are printed to
stdout when 30 seconds expires.
+.Pp
+.Dl nvmecontrol reset nvme0
+.Pp
+Perform a controller-level reset of the nvme0 controller.
.Sh AUTHORS
.An -nosplit
.Nm
diff --git a/sbin/nvmecontrol/nvmecontrol.c b/sbin/nvmecontrol/nvmecontrol.c
index 6abd3f5..b6b6908 100644
--- a/sbin/nvmecontrol/nvmecontrol.c
+++ b/sbin/nvmecontrol/nvmecontrol.c
@@ -56,6 +56,9 @@ __FBSDID("$FreeBSD$");
" <-i intr|wait> [-f refthread] [-p]\n" \
" <namespace id>\n"
+#define RESET_USAGE \
+" nvmecontrol reset <controller id>\n"
+
static void perftest_usage(void);
static void
@@ -64,6 +67,7 @@ usage(void)
fprintf(stderr, "usage:\n");
fprintf(stderr, DEVLIST_USAGE);
fprintf(stderr, IDENTIFY_USAGE);
+ fprintf(stderr, RESET_USAGE);
fprintf(stderr, PERFTEST_USAGE);
exit(EX_USAGE);
}
@@ -580,6 +584,41 @@ perftest(int argc, char *argv[])
exit(EX_OK);
}
+static void
+reset_ctrlr(int argc, char *argv[])
+{
+ struct stat devstat;
+ char path[64];
+ int ch, fd;
+
+ while ((ch = getopt(argc, argv, "")) != -1) {
+ switch ((char)ch) {
+ default:
+ usage();
+ }
+ }
+
+ sprintf(path, "/dev/%s", argv[optind]);
+
+ if (stat(path, &devstat) != 0) {
+ printf("Invalid device node '%s'.\n", path);
+ exit(EX_IOERR);
+ }
+
+ fd = open(path, O_RDWR);
+ if (fd < 0) {
+ printf("Could not open %s.\n", path);
+ exit(EX_NOPERM);
+ }
+
+ if (ioctl(fd, NVME_RESET_CONTROLLER) == -1) {
+ printf("ioctl to %s failed.\n", path);
+ exit(EX_IOERR);
+ }
+
+ exit(EX_OK);
+}
+
int
main(int argc, char *argv[])
{
@@ -593,6 +632,8 @@ main(int argc, char *argv[])
identify(argc-1, &argv[1]);
else if (strcmp(argv[1], "perftest") == 0)
perftest(argc-1, &argv[1]);
+ else if (strcmp(argv[1], "reset") == 0)
+ reset_ctrlr(argc-1, &argv[1]);
usage();
OpenPOWER on IntegriCloud