From: Gollu Appalanaidu Date: Mon, 11 Jan 2021 18:38:14 +0000 (+0530) Subject: nvme: add support for predictable latency event aggregate log page X-Git-Tag: v1.14~128 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=cd21ddedc6a73f16cb89ec937892a508944527d7;p=users%2Fsagi%2Fnvme-cli.git nvme: add support for predictable latency event aggregate log page This is to add support for LID = 0x0B, Predictable Latency Event Aggregate Log Page, this is used if a Predictable Latency Event has occurred for a particular NVM Set. For More details see NVM Express 1.4 Spec. Section 5.14.1.11 ("Predictable Latency Event Aggregate Log Page (Log Identifier 0Bh)") Max entries supported by this log page are 2044 which is: (min xfer size (4096B) - size of num of entries(8B))/entry size (2B) = 2044 entries Signed-off-by: Gollu Appalanaidu Co-Authored-By: Karthik Balan Reviewed-by: Steven Seungcheol Lee --- diff --git a/Documentation/nvme-pred-lat-event-agg-log.1 b/Documentation/nvme-pred-lat-event-agg-log.1 new file mode 100644 index 00000000..69785cb3 --- /dev/null +++ b/Documentation/nvme-pred-lat-event-agg-log.1 @@ -0,0 +1,117 @@ +'\" t +.\" Title: nvme-pred-lat-event-agg-log +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Date: 01/12/2021 +.\" Manual: NVMe Manual +.\" Source: NVMe +.\" Language: English +.\" +.TH "NVME\-PRED\-LAT\-EVE" "1" "01/12/2021" "NVMe" "NVMe Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nvme-pred-lat-event-agg-log \- Send Predictable Latency Event Aggregate Log Page request, returns result and log +.SH "SYNOPSIS" +.sp +.nf +\fInvme pred\-lat\-event\-agg\-log\fR [\-\-log\-entries= | \-e ] + [\-\-rae | \-r] [\-\-raw\-binary | \-b] + [\-\-output\-format= | \-o ] +.fi +.SH "DESCRIPTION" +.sp +Retrieves the NVMe Predictable Latency Event Aggregate Log Page from an NVMe device and provides the returned structure\&. +.sp +The parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1)\&. +.sp +On success, the returned Predictable Latency Event Aggregate Log Page structure may be returned in one ofseveral ways depending on the option flags; the structure may parsed by the program and printed in a readable format or the raw buffer may be printed to stdout for another program to parse\&. +.SH "OPTIONS" +.PP +\-e , \-\-log\-entries= +.RS 4 +Retrieve the Predictable Latency Event Aggregate Log pending entries\&. This argument is mandatory and its success may depend on the device\(cqs statistics to provide this log For More details see NVM Express 1\&.4 Spec\&. Section 5\&.14\&.1\&.11\&. The maximum number of log entries supported is 2044 for the device\&. +.RE +.PP +\-r, \-\-rae +.RS 4 +Retain an Asynchronous Event\&. +.RE +.PP +\-b, \-\-raw\-binary +.RS 4 +Print the raw Predectible Latency Event Aggregate log buffer to stdout\&. +.RE +.PP +\-o , \-\-output\-format= +.RS 4 +Set the reporting format to +\fInormal\fR, +\fIjson\fR, or +\fIbinary\fR\&. Only one output format can be used at a time\&. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +Print the Predictable Latency Event Aggregate Log page in a human readable format: +.sp +.if n \{\ +.RS 4 +.\} +.nf +# nvme pred\-lat\-event\-agg\-log /dev/nvme0 +.fi +.if n \{\ +.RE +.\} +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +Print the raw Predectible Latency Event Aggregate log to a file: +.sp +.if n \{\ +.RS 4 +.\} +.nf +# nvme pred\-lat\-event\-agg\-log /dev/nvme0 \-\-raw\-binary > pred_lat_agg_log\&.raw +.fi +.if n \{\ +.RE +.\} +.sp +It is probably a bad idea to not redirect stdout when using this mode\&. +.RE +.SH "NVME" +.sp +Part of the nvme\-user suite diff --git a/Documentation/nvme-pred-lat-event-agg-log.html b/Documentation/nvme-pred-lat-event-agg-log.html new file mode 100644 index 00000000..42c370f6 --- /dev/null +++ b/Documentation/nvme-pred-lat-event-agg-log.html @@ -0,0 +1,870 @@ + + + + + + +nvme-pred-lat-event-agg-log(1) + + + + + +
+
+

SYNOPSIS

+
+
+
nvme pred-lat-event-agg-log <device> [--log-entries=<log_entries> | -e <log_entries>]
+                        [--rae | -r] [--raw-binary | -b]
+                        [--output-format=<fmt> | -o <fmt>]
+
+
+
+
+
+

DESCRIPTION

+
+

Retrieves the NVMe Predictable Latency Event Aggregate Log Page from an +NVMe device and provides the returned structure.

+

The <device> parameter is mandatory and may be either the NVMe character +device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).

+

On success, the returned Predictable Latency Event Aggregate Log +Page structure may be returned in one ofseveral ways depending on +the option flags; the structure may parsed by the program and printed +in a readable format or the raw buffer may be printed to stdout for +another program to parse.

+
+
+
+

OPTIONS

+
+
+
+-e <log_entries> +
+
+--log-entries=<log_entries> +
+
+

+ Retrieve the Predictable Latency Event Aggregate Log pending entries. + This argument is mandatory and its success may depend on the device’s + statistics to provide this log For More details see NVM Express 1.4 Spec. + Section 5.14.1.11. The maximum number of log entries supported is 2044 + for the device. +

+
+
+-r +
+
+--rae +
+
+

+ Retain an Asynchronous Event. +

+
+
+-b +
+
+--raw-binary +
+
+

+ Print the raw Predectible Latency Event Aggregate log buffer to stdout. +

+
+
+-o <format> +
+
+--output-format=<format> +
+
+

+ Set the reporting format to normal, json, or binary. + Only one output format can be used at a time. +

+
+
+
+
+
+

EXAMPLES

+
+
    +
  • +

    +Print the Predictable Latency Event Aggregate Log page in a human readable format: +

    +
    +
    +
    # nvme pred-lat-event-agg-log /dev/nvme0
    +
    +
  • +
  • +

    +Print the raw Predectible Latency Event Aggregate log to a file: +

    +
    +
    +
    # nvme pred-lat-event-agg-log /dev/nvme0 --raw-binary > pred_lat_agg_log.raw
    +
    +

    It is probably a bad idea to not redirect stdout when using this mode.

    +
  • +
+
+
+
+

NVME

+
+

Part of the nvme-user suite

+
+
+
+

+ + + diff --git a/Documentation/nvme-pred-lat-event-agg-log.txt b/Documentation/nvme-pred-lat-event-agg-log.txt new file mode 100644 index 00000000..d7d998b0 --- /dev/null +++ b/Documentation/nvme-pred-lat-event-agg-log.txt @@ -0,0 +1,72 @@ +nvme-pred-lat-event-agg-log(1) +============================== + +NAME +---- +nvme-pred-lat-event-agg-log - Send Predictable Latency Event Aggregate Log +Page request, returns result and log + +SYNOPSIS +-------- +[verse] +'nvme pred-lat-event-agg-log' [--log-entries= | -e ] + [--rae | -r] [--raw-binary | -b] + [--output-format= | -o ] + +DESCRIPTION +----------- +Retrieves the NVMe Predictable Latency Event Aggregate Log Page from an +NVMe device and provides the returned structure. + +The parameter is mandatory and may be either the NVMe character +device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1). + +On success, the returned Predictable Latency Event Aggregate Log +Page structure may be returned in one ofseveral ways depending on +the option flags; the structure may parsed by the program and printed +in a readable format or the raw buffer may be printed to stdout for +another program to parse. + +OPTIONS +------- +-e :: +--log-entries=:: + Retrieve the Predictable Latency Event Aggregate Log pending entries. + This argument is mandatory and its success may depend on the device's + statistics to provide this log For More details see NVM Express 1.4 Spec. + Section 5.14.1.11. The maximum number of log entries supported is 2044 + for the device. + +-r:: +--rae:: + Retain an Asynchronous Event. + +-b:: +--raw-binary:: + Print the raw Predectible Latency Event Aggregate log buffer to stdout. + +-o :: +--output-format=:: + Set the reporting format to 'normal', 'json', or 'binary'. + Only one output format can be used at a time. + +EXAMPLES +-------- +* Print the Predictable Latency Event Aggregate Log page in a human readable format: ++ +------------ +# nvme pred-lat-event-agg-log /dev/nvme0 +------------ ++ + +* Print the raw Predectible Latency Event Aggregate log to a file: ++ +------------ +# nvme pred-lat-event-agg-log /dev/nvme0 --raw-binary > pred_lat_agg_log.raw +------------ ++ +It is probably a bad idea to not redirect stdout when using this mode. + +NVME +---- +Part of the nvme-user suite diff --git a/completions/_nvme b/completions/_nvme index 6030547a..94ce3fbe 100644 --- a/completions/_nvme +++ b/completions/_nvme @@ -18,6 +18,7 @@ _nvme () { 'list-ctrl:identify all controller(s) attached' 'get-ns-id:get namespace id of opened block device' 'get-log:retrieve any log in raw format' + 'pred-lat-event-agg-log:retrieve predictable latency event aggregate log' 'persistent-event-log:retrieve presistent event log' 'fw-log:retrieve fw log' 'smart-log:retrieve SMART log' @@ -211,6 +212,20 @@ _nvme () { _arguments '*:: :->subcmds' _describe -t commands "persistent-event-log options" _persistenteventlog ;; + (pred-lat-event-agg-log) + local _predlateventagglog + _predlateventagglog=( + /dev/nvme':supply a device to use (required)' + --log-entries=': Number of pending NVM Set Entries log list' + -e':alias to --log-entries' + --rae': Retain an Asynchronous Event' + -r':alias to --rae + --raw-binary':dump infos in binary format' + -b':alias of --raw-binary' + ) + _arguments '*:: :->subcmds' + _describe -t commands "nvme pred-lat-event-agg-log options" _predlateventagglog + ;; (fw-log) local _fwlog _fwlog=( @@ -715,6 +730,7 @@ _nvme () { set-feature format fw-activate fw-download admin-passthru io-passthru security-send security-recv resv-acquire resv-register resv-release resv-report flush compare read write copy show-regs persistent-event-log + pred-lat-event-agg-log ) _arguments '*:: :->subcmds' _describe -t commands "help: infos on a specific nvme command, or provide no option to see a synopsis of all nvme commands" _h diff --git a/completions/bash-nvme-completion.sh b/completions/bash-nvme-completion.sh index 4c308975..ba87f4b7 100644 --- a/completions/bash-nvme-completion.sh +++ b/completions/bash-nvme-completion.sh @@ -4,7 +4,7 @@ _cmds="list id-ctrl id-ns list-ns id-iocs create-ns delete-ns \ attach-ns detach-ns list-ctrl get-ns-id get-log persistent-event-log \ - fw-log smart-log smart-log-add error-log \ + pred-lat-event-agg-log fw-log smart-log smart-log-add error-log \ get-feature set-feature format fw-activate \ fw-download admin-passthru io-passthru security-send \ security-recv resv-acquire resv-register resv-release \ @@ -75,6 +75,10 @@ nvme_list_opts () { opts+=" --action= -a --log-len= -l \ --raw-binary -b --output-format= -o" ;; + "pred-lat-event-agg-log") + opts+=" --log-entries= -e --rae -r \ + --raw-binary -b --output-format= -o" + ;; "fw-log") opts+=" --raw-binary -b --output-format= -o" ;; diff --git a/linux/nvme.h b/linux/nvme.h index ea32c1ab..deb1f392 100644 --- a/linux/nvme.h +++ b/linux/nvme.h @@ -880,6 +880,11 @@ enum nvme_persistent_event_log_actions { NVME_PEVENT_LOG_RELEASE_CTX = 0x2, }; +struct nvme_predlat_event_agg_log_page { + __le64 num_entries; + __le16 entries[]; +}; + enum { NVME_SMART_CRIT_SPARE = 1 << 0, NVME_SMART_CRIT_TEMPERATURE = 1 << 1, @@ -1179,6 +1184,7 @@ enum { NVME_LOG_TELEMETRY_CTRL = 0x08, NVME_LOG_ENDURANCE_GROUP = 0x09, NVME_LOG_ANA = 0x0c, + NVME_LOG_PRELAT_EVENT_AGG = 0x0b, NVME_LOG_PERSISTENT_EVENT = 0x0d, NVME_LOG_DISC = 0x70, NVME_LOG_RESERVATION = 0x80, diff --git a/nvme-builtin.h b/nvme-builtin.h index f2080254..15545cf0 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -33,6 +33,7 @@ COMMAND_LIST( ENTRY("error-log", "Retrieve Error Log, show it", get_error_log) ENTRY("effects-log", "Retrieve Command Effects Log, show it", get_effects_log) ENTRY("endurance-log", "Retrieve Endurance Group Log, show it", get_endurance_log) + ENTRY("pred-lat-event-agg-log", "Retrieve Predictable Latency Event Aggregate Log, show it", get_pred_lat_event_agg_log) ENTRY("persistent-event-log", "Retrieve Presistent Event Log, show it", get_persistent_event_log) ENTRY("get-feature", "Get feature and show the resulting value", get_feature) ENTRY("device-self-test", "Perform the necessary tests to observe the performance", device_self_test) diff --git a/nvme-ioctl.c b/nvme-ioctl.c index 0b668666..452168dd 100644 --- a/nvme-ioctl.c +++ b/nvme-ioctl.c @@ -613,6 +613,14 @@ int nvme_sanitize_log(int fd, struct nvme_sanitize_log_page *sanitize_log) NVME_NO_LOG_LSP, sizeof(*sanitize_log), sanitize_log); } +int nvme_predictable_latency_event_agg_log(int fd, + void *pea_log, bool rae, __u32 size) +{ + return nvme_get_log(fd, NVME_NSID_ALL, + NVME_LOG_PRELAT_EVENT_AGG, rae, NVME_NO_LOG_LSP, + size, pea_log); +} + int nvme_persistent_event_log(int fd, __u8 action, __u32 size, void *pevent_log_info) { diff --git a/nvme-ioctl.h b/nvme-ioctl.h index 9f422236..acdcbd2e 100644 --- a/nvme-ioctl.h +++ b/nvme-ioctl.h @@ -115,6 +115,8 @@ int nvme_ana_log(int fd, void *ana_log, size_t ana_log_len, int rgo); int nvme_effects_log(int fd, struct nvme_effects_log_page *effects_log); int nvme_discovery_log(int fd, struct nvmf_disc_rsp_page_hdr *log, __u32 size); int nvme_sanitize_log(int fd, struct nvme_sanitize_log_page *sanitize_log); +int nvme_predictable_latency_event_agg_log(int fd, void *pea_log, + bool rae, __u32 size); int nvme_persistent_event_log(int fd, __u8 action, __u32 size, void *pevent_log_info); int nvme_endurance_log(int fd, __u16 group_id, diff --git a/nvme-print.c b/nvme-print.c index 03fd37f7..5db44882 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -866,6 +866,63 @@ static void json_sanitize_log(struct nvme_sanitize_log_page *sanitize_log, json_free_object(root); } +void json_predictable_latency_event_agg_log( + struct nvme_predlat_event_agg_log_page *pea_log, + __u64 log_entries) +{ + struct json_object *root; + struct json_object *valid_attrs; + struct json_array *valid; + __u64 num_iter; + __u64 num_entries; + + root = json_create_object(); + num_entries = le64_to_cpu(pea_log->num_entries); + json_object_add_value_uint(root, "num_entries_avail", + num_entries); + valid = json_create_array(); + + num_iter = min(num_entries, log_entries); + for (int i = 0; i < num_iter; i++) { + valid_attrs = json_create_object(); + json_object_add_value_uint(valid_attrs, "entry", + le16_to_cpu(pea_log->entries[i])); + json_array_add_value_object(valid, valid_attrs); + } + json_object_add_value_array(root, "list_of_entries", valid); + json_print_object(root, NULL); + printf("\n"); + json_free_object(root); +} + +void nvme_show_predictable_latency_event_agg_log( + struct nvme_predlat_event_agg_log_page *pea_log, + __u64 log_entries, __u32 size, const char *devname, + enum nvme_print_flags flags) +{ + __u64 num_iter; + __u64 num_entries; + + if (flags & BINARY) + return d_raw((unsigned char *)pea_log, size); + if (flags & JSON) + return json_predictable_latency_event_agg_log(pea_log, + log_entries); + + num_entries = le64_to_cpu(pea_log->num_entries); + printf("Predictable Latency Event Aggregate Log for"\ + " device: %s\n", devname); + + printf("Number of Entries Available: %llu\n", + num_entries); + + num_iter = min(num_entries, log_entries); + for (int i = 0; i < num_iter; i++) { + printf("Entry[%d]: %u\n", i + 1, + le16_to_cpu(pea_log->entries[i])); + } +} + static const char *nvme_show_nss_hw_error(__u16 error_code) { switch(error_code) { diff --git a/nvme-print.h b/nvme-print.h index 6e142d4a..ee1223af 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -37,6 +37,13 @@ void nvme_show_endurance_log(struct nvme_endurance_group_log *endurance_log, __u16 group_id, const char *devname, enum nvme_print_flags flags); void nvme_show_sanitize_log(struct nvme_sanitize_log_page *sanitize, const char *devname, enum nvme_print_flags flags); +void json_predictable_latency_event_agg_log( + struct nvme_predlat_event_agg_log_page *pea_log, + __u64 log_entries); +void nvme_show_predictable_latency_event_agg_log( + struct nvme_predlat_event_agg_log_page *pea_log, + __u64 log_entries, __u32 size, const char *devname, + enum nvme_print_flags flags); void json_persistent_event_log(void *pevent_log_info, __u32 size, enum nvme_print_flags flags); void nvme_show_persistent_event_log(void *pevent_log_info, diff --git a/nvme.c b/nvme.c index a86bc464..a7c9ea18 100644 --- a/nvme.c +++ b/nvme.c @@ -737,6 +737,96 @@ ret: return nvme_status_to_errno(err, false); } +static int get_pred_lat_event_agg_log(int argc, char **argv, + struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Retrieve Predictable Latency Event" \ + "Aggregate Log page and prints it, for the given" \ + "device in either decoded format(default)," \ + "json or binary."; + const char *log_entries = "Number of pending NVM Set" \ + "log Entries list"; + const char *rae = "Retain an Asynchronous Event"; + const char *raw = "use binary output"; + void *pea_log; + struct nvme_id_ctrl ctrl; + enum nvme_print_flags flags; + int err, fd; + __u32 log_size; + + struct config { + __u64 log_entries; + bool rae; + char *output_format; + int raw_binary; + }; + + struct config cfg = { + .log_entries = 2044, + .rae = false, + .output_format = "normal", + }; + + OPT_ARGS(opts) = { + OPT_UINT("log-entries", 'e', &cfg.log_entries, log_entries), + OPT_FLAG("rae", 'r', &cfg.rae, rae), + OPT_FMT("output-format", 'o', &cfg.output_format, output_format), + OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw), + OPT_END() + }; + + err = fd = parse_and_open(argc, argv, desc, opts); + if (fd < 0) + goto ret; + + err = flags = validate_output_format(cfg.output_format); + if (flags < 0) + goto close_fd; + if (cfg.raw_binary) + flags = BINARY; + + if (!cfg.log_entries) { + fprintf(stderr, "non-zero log-entries is required param\n"); + err = -EINVAL; + goto close_fd; + } + + err = nvme_identify_ctrl(fd, &ctrl); + if (err < 0) { + perror("identify controller"); + goto close_fd; + } else if (err) { + nvme_show_status(err); + goto close_fd; + } + + cfg.log_entries = min(cfg.log_entries, le32_to_cpu(ctrl.nsetidmax)); + log_size = sizeof(__u64) + cfg.log_entries * sizeof(__u16); + pea_log = calloc(log_size, 1); + if (!pea_log) { + fprintf(stderr, "could not alloc buffer for predictable " \ + "latency event agggregate log entries\n"); + err = -ENOMEM; + goto close_fd; + } + + err = nvme_predictable_latency_event_agg_log(fd, pea_log, cfg.rae, + log_size); + if (!err) + nvme_show_predictable_latency_event_agg_log(pea_log, cfg.log_entries, + log_size, devicename, flags); + else if (err > 0) + nvme_show_status(err); + else + perror("predictable latency event gggregate log page"); + free(pea_log); + +close_fd: + close(fd); +ret: + return nvme_status_to_errno(err, false); +} + static int get_persistent_event_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) {