From f1e890db685274d6c634e4a4dc8347b1e4950c4f Mon Sep 17 00:00:00 2001 From: Leonardo da Cunha Date: Thu, 27 Feb 2025 14:44:34 -0800 Subject: [PATCH 1/3] plugins/solidigm: Added missing log descriptions and uuid support to some logs. Added log descriptions to log-page-directory. Added UUID support to market-log and workload-tracker. Added nvme command printing to verbose mode of modified plugin commands. Signed-off-by: Leonardo da Cunha --- plugins/solidigm/solidigm-log-page-dir.c | 19 +++++-- plugins/solidigm/solidigm-market-log.c | 58 ++++++++++++------- plugins/solidigm/solidigm-nvme.h | 2 +- plugins/solidigm/solidigm-workload-tracker.c | 60 ++++++++++++++------ 4 files changed, 93 insertions(+), 46 deletions(-) diff --git a/plugins/solidigm/solidigm-log-page-dir.c b/plugins/solidigm/solidigm-log-page-dir.c index 886097bf8a..c3f08bb4c8 100644 --- a/plugins/solidigm/solidigm-log-page-dir.c +++ b/plugins/solidigm/solidigm-log-page-dir.c @@ -110,10 +110,12 @@ static struct lid_dir *get_solidigm_lids(struct nvme_supported_log_pages *suppor solidigm_dir.lid[0xDD].str = "VU Marketing Description Log Page"; solidigm_dir.lid[0xEF].str = "Performance Rating and LBA Access Histogram"; solidigm_dir.lid[0xF2].str = "Get Power Usage Log Page"; + solidigm_dir.lid[0xF4].str = "Nand Statistics Log Page"; + solidigm_dir.lid[0xF5].str = "Nand Defects Count Log Page"; solidigm_dir.lid[0xF6].str = "Vt Histo Get Log Page"; solidigm_dir.lid[0xF9].str = "Workload Tracker Get Log Page"; solidigm_dir.lid[0xFD].str = "Garbage Control Collection Log Page"; - solidigm_dir.lid[0xFE].str = "Latency Outlier Log Page"; + solidigm_dir.lid[0xFE].str = "Latency Outlier / SK SMART Log Page"; update_vendor_lid_supported(supported, &solidigm_dir); @@ -131,6 +133,9 @@ static struct lid_dir *get_ocp_lids(struct nvme_supported_log_pages *supported) ocp_dir.lid[0xC3].str = "OCP Latency Monitor"; ocp_dir.lid[0xC4].str = "OCP Device Capabilities"; ocp_dir.lid[0xC5].str = "OCP Unsupported Requirements"; + ocp_dir.lid[0xC6].str = "OCP Hardware Component"; + ocp_dir.lid[0xC7].str = "OCP TCG Configuration"; + ocp_dir.lid[0xC9].str = "OCP Telemetry String Log"; update_vendor_lid_supported(supported, &ocp_dir); @@ -188,10 +193,11 @@ int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *c { const int NO_UUID_INDEX = 0; const char *description = "Retrieves list of supported log pages for each UUID index."; - char *format = "normal"; OPT_ARGS(options) = { - OPT_FMT("output-format", 'o', &format, "output format : normal | json"), + OPT_FMT("output-format", 'o', &nvme_cfg.output_format, + "output format : normal | json"), + OPT_INCR("verbose", 'v', &nvme_cfg.verbose, verbose), OPT_END() }; @@ -244,9 +250,10 @@ int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *c if (!err) { nvme_print_flags_t print_flag; - err = validate_output_format(format, &print_flag); - if (err < 0) { - fprintf(stderr, "Error: Invalid output format specified: %s.\n", format); + err = validate_output_format(nvme_cfg.output_format, &print_flag); + if (err) { + nvme_show_error("Error: Invalid output format specified: %s.\n", + nvme_cfg.output_format); return err; } diff --git a/plugins/solidigm/solidigm-market-log.c b/plugins/solidigm/solidigm-market-log.c index e7e8728db6..e0934df5e5 100644 --- a/plugins/solidigm/solidigm-market-log.c +++ b/plugins/solidigm/solidigm-market-log.c @@ -18,7 +18,9 @@ #include "libnvme.h" #include "plugin.h" #include "nvme-print.h" +#include "solidigm-util.h" +#define MARKET_LOG_LID 0xDD #define MARKET_LOG_MAX_SIZE 512 int sldgm_get_market_log(int argc, char **argv, struct command *command, @@ -26,19 +28,15 @@ int sldgm_get_market_log(int argc, char **argv, struct command *command, { const char *desc = "Get Solidigm Marketing Name log and show it."; const char *raw = "dump output in binary format"; - struct nvme_dev *dev; + _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; char log[MARKET_LOG_MAX_SIZE]; int err; - - struct config { - bool raw_binary; - }; - - struct config cfg = { - }; + __u8 uuid_idx; + bool raw_binary = false; OPT_ARGS(opts) = { - OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw), + OPT_FLAG("raw-binary", 'b', &raw_binary, raw), + OPT_INCR("verbose", 'v', &nvme_cfg.verbose, verbose), OPT_END() }; @@ -46,17 +44,35 @@ int sldgm_get_market_log(int argc, char **argv, struct command *command, if (err) return err; - err = nvme_get_log_simple(dev_fd(dev), 0xdd, sizeof(log), log); - if (!err) { - if (!cfg.raw_binary) - printf("Solidigm Marketing Name Log:\n%s\n", log); - else - d_raw((unsigned char *)&log, sizeof(log)); - } else if (err > 0) - - nvme_show_status(err); - /* Redundant close() to make static code analysis happy */ - close(dev->direct.fd); - dev_close(dev); + sldgm_get_uuid_index(dev, &uuid_idx); + + struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = log, + .args_size = sizeof(args), + .fd = dev_fd(dev), + .uuidx = uuid_idx, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .lid = MARKET_LOG_LID, + .len = sizeof(log), + .nsid = NVME_NSID_ALL, + .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .rae = false, + .ot = false, + }; + + err = nvme_get_log(&args); + if (err) { + nvme_show_status(err); + return err; + } + if (!raw_binary) + printf("Solidigm Marketing Name Log:\n%s\n", log); + else + d_raw((unsigned char *)&log, sizeof(log)); + return err; } diff --git a/plugins/solidigm/solidigm-nvme.h b/plugins/solidigm/solidigm-nvme.h index 4a7e615082..01a967b696 100644 --- a/plugins/solidigm/solidigm-nvme.h +++ b/plugins/solidigm/solidigm-nvme.h @@ -13,7 +13,7 @@ #include "cmd.h" -#define SOLIDIGM_PLUGIN_VERSION "1.11" +#define SOLIDIGM_PLUGIN_VERSION "1.12" PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_VERSION), COMMAND_LIST( diff --git a/plugins/solidigm/solidigm-workload-tracker.c b/plugins/solidigm/solidigm-workload-tracker.c index 14d8458122..f2e3913a6b 100644 --- a/plugins/solidigm/solidigm-workload-tracker.c +++ b/plugins/solidigm/solidigm-workload-tracker.c @@ -197,11 +197,11 @@ struct workloadLog { // Full WL Log Structure struct wltracker { int fd; + __u8 uuid_index; struct workloadLog workload_log; size_t poll_count; bool show_wall_timestamp; __u64 us_epoch_ssd_delta; - unsigned int verbose; __u64 start_time_us; __u64 run_time_us; bool disable; @@ -229,7 +229,7 @@ static void wltracker_print_field_names(struct wltracker *wlt) if (wlt->show_wall_timestamp) printf("%-*s", (int)sizeof("YYYY-MM-DD-hh:mm:ss.uuuuuu"), "wall-time"); - if (wlt->verbose > 1) + if (nvme_cfg.verbose > 1) printf("%s", "entry# "); printf("\n"); @@ -250,7 +250,7 @@ static void wltracker_print_header(struct wltracker *wlt) printf("%-24s %s\n", "Tracker Type:", trk_types[log->config.contentGroup]); printf("%-24s %u\n", "Total log page entries:", le32_to_cpu(log->workloadLogCount)); printf("%-24s %u\n", "Trigger count:", log->triggeredEvents); - if (wlt->verbose > 1) + if (nvme_cfg.verbose > 1) printf("%-24s %ld\n", "Poll count:", wlt->poll_count); if (wlt->poll_count != 0) wltracker_print_field_names(wlt); @@ -275,12 +275,12 @@ int wltracker_config(struct wltracker *wlt, union WorkloadLogEnable *we) { struct nvme_set_features_args args = { .args_size = sizeof(args), - .fd = wlt->fd, + .fd = wlt->fd, .fid = FID, .cdw11 = we->dword, + .uuidx = wlt->uuid_index, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, }; - return nvme_set_features(&args); } @@ -294,7 +294,18 @@ static int wltracker_show_newer_entries(struct wltracker *wlt) __u64 timestamp = 0; union WorkloadLogEnable workloadEnable; - int err = nvme_get_log_simple(wlt->fd, LID, sizeof(struct workloadLog), log); + struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = log, + .args_size = sizeof(args), + .fd = wlt->fd, + .uuidx = wlt->uuid_index, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .lid = LID, + .len = sizeof(*log), + }; + int err = nvme_get_log(&args); if (err > 0) { nvme_show_status(err); @@ -303,7 +314,7 @@ static int wltracker_show_newer_entries(struct wltracker *wlt) if (err < 0) return err; - if (wlt->verbose) + if (nvme_cfg.verbose) wltracker_print_header(wlt); cnt = log->workloadLogCount; @@ -331,7 +342,7 @@ static int wltracker_show_newer_entries(struct wltracker *wlt) // retrieve fresh timestamp to reconstruct wall time union WorkloadLogEnable we = log->config; - if (wlt->verbose > 1) { + if (nvme_cfg.verbose > 1) { printf("Temporarily enabling tracker to find current timestamp\n"); printf("Original config value: 0x%08x\n", we.dword); } @@ -339,7 +350,7 @@ static int wltracker_show_newer_entries(struct wltracker *wlt) we.triggerEnable = false; we.sampleTime = 1; - if (wlt->verbose > 1) + if (nvme_cfg.verbose > 1) printf("Modified config value: 0x%08x\n", we.dword); err = wltracker_config(wlt, &we); @@ -357,7 +368,7 @@ static int wltracker_show_newer_entries(struct wltracker *wlt) we = log->config; we.triggerEnable = false; err = wltracker_config(wlt, &we); - if (wlt->verbose > 1) + if (nvme_cfg.verbose > 1) printf("Restored config value: 0x%08x\n", we.dword); } @@ -395,7 +406,7 @@ static int wltracker_show_newer_entries(struct wltracker *wlt) (uint64_t)(epoch_ts_us % 1000000ULL)); } - if (wlt->verbose > 1) + if (nvme_cfg.verbose > 1) printf("%-*i", (int)sizeof("entry#"), i); printf("\n"); @@ -431,7 +442,7 @@ static int wltracker_show_newer_entries(struct wltracker *wlt) void wltracker_run_time_update(struct wltracker *wlt) { wlt->run_time_us = micros() - wlt->start_time_us; - if (wlt->verbose > 0) + if (nvme_cfg.verbose > 0) printf("run_time: %lluus\n", wlt->run_time_us); } @@ -527,6 +538,7 @@ int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struc join_options(sample_options, samplet, ARRAY_SIZE(samplet)); OPT_ARGS(opts) = { + OPT_BYTE("uuid-index", 'U', &wlt.uuid_index, "specify uuid index"), OPT_FLAG("enable", 'e', &cfg.enable, "tracker enable"), OPT_FLAG("disable", 'd', &cfg.disable, "tracker disable"), OPT_STRING("sample-time", 's', sample_options, &cfg.sample_time, sample_interval), @@ -542,7 +554,7 @@ int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struc "Trigger on delta to stop sampling"), OPT_FLAG("trigger-on-latency", 'L', &cfg.trigger_on_latency, "Use latency tracker to trigger stop sampling"), - OPT_INCR("verbose", 'v', &wlt.verbose, "Increase logging verbosity"), + OPT_INCR("verbose", 'v', &nvme_cfg.verbose, "Increase logging verbosity"), OPT_END() }; @@ -550,6 +562,11 @@ int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struc if (err) return err; + if (wlt.uuid_index > 127) { + nvme_show_error("invalid uuid index param: %u", wlt.uuid_index); + return -1; + } + wlt.fd = dev_fd(dev); if ((cfg.flush_frequency < 1) || (cfg.flush_frequency > MAX_WORKLOAD_LOG_ENTRIES)) { @@ -598,8 +615,15 @@ int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struc we.triggerEnable = true; we.triggerDelta = cfg.trigger_on_delta; we.triggerSynchronous = !cfg.trigger_on_latency; - err = nvme_set_features_data(wlt.fd, 0xf5, 0, cfg.trigger_treshold, 0, 0, NULL, - NULL); + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = wlt.fd, + .fid = 0xf5, + .cdw11 = cfg.trigger_treshold, + .uuidx = wlt.uuid_index, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + }; + err = nvme_set_features(&args); if (err < 0) { nvme_show_error("Trigger Threshold set-feature: %s", nvme_strerror(errno)); return err; @@ -651,7 +675,7 @@ int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struc if (interval > elapsed) { __u64 period_us = min(next_sample_us - wlt.run_time_us, stop_time_us - wlt.run_time_us); - if (wlt.verbose > 1) + if (nvme_cfg.verbose > 1) printf("Sleeping %lluus..\n", period_us); usleep(period_us); wltracker_run_time_update(&wlt); @@ -666,7 +690,7 @@ int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struc if (cfg.disable) { union WorkloadLogEnable we2 = wlt.workload_log.config; - if (wlt.verbose > 1) + if (nvme_cfg.verbose > 1) printf("Original config value: 0x%08x\n", we2.dword); we2.trackerEnable = false; @@ -679,7 +703,7 @@ int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struc nvme_show_status(err); return err; } - if (wlt.verbose > 1) + if (nvme_cfg.verbose > 1) printf("Modified config value: 0x%08x\n", we2.dword); printf("Tracker disabled\n"); return 0; From 7c0deca1649743b069ef7b629c36e62beca05a74 Mon Sep 17 00:00:00 2001 From: Leonardo da Cunha Date: Thu, 10 Apr 2025 11:04:44 -0700 Subject: [PATCH 2/3] Documentation: updated solidigm workload tracker page Added option to choose UUID index. Signed-off-by: Leonardo da Cunha --- Documentation/nvme-solidigm-workload-tracker.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/nvme-solidigm-workload-tracker.txt b/Documentation/nvme-solidigm-workload-tracker.txt index d1f0b3a103..bcce568a1f 100644 --- a/Documentation/nvme-solidigm-workload-tracker.txt +++ b/Documentation/nvme-solidigm-workload-tracker.txt @@ -8,7 +8,8 @@ nvme-solidigm-workload-tracker - Real-time capture of Workload Tracker samples SYNOPSIS -------- [verse] -'nvme solidigm workload-tracker' [--enable | -e] [--disable | -d] +'nvme solidigm workload-tracker' [--uuid-index= | -U ] + [--enable | -e] [--disable | -d] [--sample-time=