Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sbin/nvmectl nvmectl(8): sync with FreeBSD HEAD r316105.
details: https://anonhg.NetBSD.org/src/rev/74e6a0a31003
branches: trunk
changeset: 823613:74e6a0a31003
user: nonaka <nonaka%NetBSD.org@localhost>
date: Sat Apr 29 00:06:40 2017 +0000
description:
nvmectl(8): sync with FreeBSD HEAD r316105.
- Expand the SMART / Health Information Log Page (Page 02) printout based on
NVM Express 1.2.1 Standard.
- Implement Intel-specific log pages.
- Implement HGST-specific log pages.
- Implement wdc-specific nvme control options.
- Add the ability to dump log pages directly in binary to stdout.
diffstat:
sbin/nvmectl/Makefile | 3 +-
sbin/nvmectl/firmware.c | 8 +-
sbin/nvmectl/logpage.c | 773 +++++++++++++++++++++++++++++++++++++++++++----
sbin/nvmectl/nvme.h | 38 +-
sbin/nvmectl/nvmectl.8 | 73 ++++-
sbin/nvmectl/nvmectl.c | 53 +-
sbin/nvmectl/nvmectl.h | 31 +-
7 files changed, 863 insertions(+), 116 deletions(-)
diffs (truncated from 1333 to 300 lines):
diff -r 7c8529350101 -r 74e6a0a31003 sbin/nvmectl/Makefile
--- a/sbin/nvmectl/Makefile Sat Apr 29 00:05:35 2017 +0000
+++ b/sbin/nvmectl/Makefile Sat Apr 29 00:06:40 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.2 2017/02/13 11:16:46 nonaka Exp $
+# $NetBSD: Makefile,v 1.3 2017/04/29 00:06:40 nonaka Exp $
.include <bsd.own.mk>
@@ -11,6 +11,7 @@
SRCS+= perftest.c
SRCS+= power.c
SRCS+= reset.c
+SRCS+= wdc.c
SRCS+= bignum.c
SRCS+= humanize_bignum.c
MAN= nvmectl.8
diff -r 7c8529350101 -r 74e6a0a31003 sbin/nvmectl/firmware.c
--- a/sbin/nvmectl/firmware.c Sat Apr 29 00:05:35 2017 +0000
+++ b/sbin/nvmectl/firmware.c Sat Apr 29 00:06:40 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: firmware.c,v 1.1 2016/06/04 16:29:35 nonaka Exp $ */
+/* $NetBSD: firmware.c,v 1.2 2017/04/29 00:06:40 nonaka Exp $ */
/*-
* Copyright (c) 2013 EMC Corp.
@@ -31,9 +31,9 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: firmware.c,v 1.1 2016/06/04 16:29:35 nonaka Exp $");
+__RCSID("$NetBSD: firmware.c,v 1.2 2017/04/29 00:06:40 nonaka Exp $");
#if 0
-__FBSDID("$FreeBSD: head/sbin/nvmecontrol/firmware.c 258071 2013-11-12 21:14:19Z jimharris $");
+__FBSDID("$FreeBSD: head/sbin/nvmecontrol/firmware.c 313188 2017-02-04 05:52:50Z imp $");
#endif
#endif
@@ -121,7 +121,7 @@
off = 0;
resid = payload_size;
- if ((chunk = malloc(NVME_MAX_XFER_SIZE)) == NULL)
+ if ((chunk = aligned_alloc(PAGE_SIZE, NVME_MAX_XFER_SIZE)) == NULL)
errx(1, "unable to malloc %d bytes", NVME_MAX_XFER_SIZE);
while (resid > 0) {
diff -r 7c8529350101 -r 74e6a0a31003 sbin/nvmectl/logpage.c
--- a/sbin/nvmectl/logpage.c Sat Apr 29 00:05:35 2017 +0000
+++ b/sbin/nvmectl/logpage.c Sat Apr 29 00:06:40 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: logpage.c,v 1.3 2017/02/13 11:16:46 nonaka Exp $ */
+/* $NetBSD: logpage.c,v 1.4 2017/04/29 00:06:40 nonaka Exp $ */
/*-
* Copyright (c) 2013 EMC Corp.
@@ -31,14 +31,15 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: logpage.c,v 1.3 2017/02/13 11:16:46 nonaka Exp $");
+__RCSID("$NetBSD: logpage.c,v 1.4 2017/04/29 00:06:40 nonaka Exp $");
#if 0
-__FBSDID("$FreeBSD: head/sbin/nvmecontrol/logpage.c 285796 2015-07-22 16:10:29Z jimharris $");
+__FBSDID("$FreeBSD: head/sbin/nvmecontrol/logpage.c 314230 2017-02-25 00:09:16Z imp $");
#endif
#endif
#include <sys/param.h>
#include <sys/ioccom.h>
+#include <sys/endian.h>
#include <ctype.h>
#include <err.h>
@@ -58,6 +59,39 @@
typedef void (*print_fn_t)(void *buf, uint32_t size);
+struct kv_name {
+ uint32_t key;
+ const char *name;
+};
+
+static const char *
+kv_lookup(const struct kv_name *kv, size_t kv_count, uint32_t key)
+{
+ static char bad[32];
+ size_t i;
+
+ for (i = 0; i < kv_count; i++, kv++)
+ if (kv->key == key)
+ return kv->name;
+ snprintf(bad, sizeof(bad), "Attribute %#x", key);
+ return bad;
+}
+
+static void
+print_bin(void *data, uint32_t length)
+{
+ write(STDOUT_FILENO, data, length);
+}
+
+/* "Missing" from endian.h */
+static __inline uint64_t
+le48dec(const void *pp)
+{
+ uint8_t const *p = (uint8_t const *)pp;
+
+ return (((uint64_t)le16dec(p + 4) << 32) | le32dec(p));
+}
+
static void *
get_log_buffer(uint32_t size)
{
@@ -178,10 +212,17 @@
}
static void
+print_temp(uint16_t t)
+{
+ printf("%u K, %2.2f C, %3.2f F\n", t, (float)t - 273.15,
+ (float)t * 9 / 5 - 459.67);
+}
+
+static void
print_log_health(void *buf, uint32_t size __unused)
{
struct nvme_health_information_page *health = buf;
- float composite_temperature = health->composite_temperature;
+ int i;
printf("SMART/Health Information Log\n");
printf("============================\n");
@@ -203,10 +244,8 @@
printf(" Volatile memory backup: %d\n",
(uint8_t)__SHIFTOUT(health->critical_warning,
NVME_HEALTH_PAGE_CW_VOLATILE_MEMORY_BACKUP));
- printf("Temperature: %u K, %2.2f C, %3.2f F\n",
- health->composite_temperature,
- composite_temperature - (float)273.15,
- (composite_temperature * (float)9/5) - (float)459.67);
+ printf("Temperature: ");
+ print_temp(health->composite_temperature);
printf("Available spare: %u\n",
health->available_spare);
printf("Available spare threshold: %u\n",
@@ -214,26 +253,28 @@
printf("Percentage used: %u\n",
health->percentage_used);
- print_bignum("Data units (512 byte) read:",
- health->data_units_read, "");
- print_bignum("Data units (512 byte) written:",
- health->data_units_written, "");
- print_bignum("Host read commands:",
- health->host_read_commands, "");
- print_bignum("Host write commands:",
- health->host_write_commands, "");
- print_bignum("Controller busy time (minutes):",
- health->controller_busy_time, "");
- print_bignum("Power cycles:",
- health->power_cycles, "");
- print_bignum("Power on hours:",
- health->power_on_hours, "");
- print_bignum("Unsafe shutdowns:",
- health->unsafe_shutdowns, "");
- print_bignum("Media errors:",
- health->media_errors, "");
+ print_bignum("Data units (512 byte) read:", health->data_units_read, "");
+ print_bignum("Data units (512 byte) written:", health->data_units_written,
+ "");
+ print_bignum("Host read commands:", health->host_read_commands, "");
+ print_bignum("Host write commands:", health->host_write_commands, "");
+ print_bignum("Controller busy time (minutes):", health->controller_busy_time,
+ "");
+ print_bignum("Power cycles:", health->power_cycles, "");
+ print_bignum("Power on hours:", health->power_on_hours, "");
+ print_bignum("Unsafe shutdowns:", health->unsafe_shutdowns, "");
+ print_bignum("Media errors:", health->media_errors, "");
print_bignum("No. error info log entries:",
health->num_error_info_log_entries, "");
+
+ printf("Warning Temp Composite Time: %d\n", health->warning_temp_time);
+ printf("Error Temp Composite Time: %d\n", health->error_temp_time);
+ for (i = 0; i < 7; i++) {
+ if (health->temp_sensor[i] == 0)
+ continue;
+ printf("Temperature Sensor %d: ", i + 1);
+ print_temp(health->temp_sensor[i]);
+ }
}
static void
@@ -265,14 +306,593 @@
}
}
+/*
+ * Intel specific log pages from
+ * http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/ssd-dc-p3700-spec.pdf
+ *
+ * Though the version as of this date has a typo for the size of log page 0xca,
+ * offset 147: it is only 1 byte, not 6.
+ */
+static void
+print_intel_temp_stats(void *buf, uint32_t size __unused)
+{
+ struct intel_log_temp_stats *temp = buf;
+
+ printf("Intel Temperature Log\n");
+ printf("=====================\n");
+
+ printf("Current: ");
+ print_temp(temp->current);
+ printf("Overtemp Last Flags %#jx\n",
+ (uintmax_t)temp->overtemp_flag_last);
+ printf("Overtemp Lifetime Flags %#jx\n",
+ (uintmax_t)temp->overtemp_flag_life);
+ printf("Max Temperature ");
+ print_temp(temp->max_temp);
+ printf("Min Temperature ");
+ print_temp(temp->min_temp);
+ printf("Max Operating Temperature ");
+ print_temp(temp->max_oper_temp);
+ printf("Min Operating Temperature ");
+ print_temp(temp->min_oper_temp);
+ printf("Estimated Temperature Offset: %ju C/K\n",
+ (uintmax_t)temp->est_offset);
+}
+
+/*
+ * Format from Table 22, section 5.7 IO Command Latency Statistics.
+ * Read and write stats pages have identical encoding.
+ */
+static void
+print_intel_read_write_lat_log(void *buf, uint32_t size __unused)
+{
+ const char *walker = buf;
+ int i;
+
+ printf("Major: %d\n", le16dec(walker + 0));
+ printf("Minor: %d\n", le16dec(walker + 2));
+ for (i = 0; i < 32; i++)
+ printf("%4dus-%4dus: %ju\n", i * 32, (i + 1) * 32,
+ (uintmax_t)le32dec(walker + 4 + i * 4));
+ for (i = 1; i < 32; i++)
+ printf("%4dms-%4dms: %ju\n", i, i + 1,
+ (uintmax_t)le32dec(walker + 132 + i * 4));
+ for (i = 1; i < 32; i++)
+ printf("%4dms-%4dms: %ju\n", i * 32, (i + 1) * 32,
+ (uintmax_t)le32dec(walker + 256 + i * 4));
+}
+
+static void
+print_intel_read_lat_log(void *buf, uint32_t size)
+{
+
+ printf("Intel Read Latency Log\n");
+ printf("======================\n");
+ print_intel_read_write_lat_log(buf, size);
+}
+
+static void
+print_intel_write_lat_log(void *buf, uint32_t size)
+{
+
+ printf("Intel Write Latency Log\n");
+ printf("=======================\n");
+ print_intel_read_write_lat_log(buf, size);
+}
+
+/*
+ * Table 19. 5.4 SMART Attributes.
+ * Samsung also implements this and some extra data not documented.
+ */
+static void
+print_intel_add_smart(void *buf, uint32_t size __unused)
+{
+ uint8_t *walker = buf;
+ uint8_t *end = walker + 150;
+ const char *name;
+ uint64_t raw;
+ uint8_t normalized;
+
+ static struct kv_name kv[] = {
+ { 0xab, "Program Fail Count" },
+ { 0xac, "Erase Fail Count" },
+ { 0xad, "Wear Leveling Count" },
+ { 0xb8, "End to End Error Count" },
+ { 0xc7, "CRC Error Count" },
+ { 0xe2, "Timed: Media Wear" },
+ { 0xe3, "Timed: Host Read %" },
+ { 0xe4, "Timed: Elapsed Time" },
+ { 0xea, "Thermal Throttle Status" },
+ { 0xf0, "Retry Buffer Overflows" },
+ { 0xf3, "PLL Lock Loss Count" },
+ { 0xf4, "NAND Bytes Written" },
+ { 0xf5, "Host Bytes Written" },
+ };
+
Home |
Main Index |
Thread Index |
Old Index