From fc67d3ad9a2903cc33e5cdaedaad51dd86a42236 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 24 Dec 2023 08:57:49 +0100 Subject: Adding upstream version 2.7.1. Signed-off-by: Daniel Baumann --- plugins/solidigm/meson.build | 3 + plugins/solidigm/solidigm-garbage-collection.c | 6 +- plugins/solidigm/solidigm-get-drive-info.c | 79 +++++++++++++++++ plugins/solidigm/solidigm-get-drive-info.h | 8 ++ plugins/solidigm/solidigm-internal-logs.c | 34 +++++--- plugins/solidigm/solidigm-latency-tracking.c | 4 +- plugins/solidigm/solidigm-log-page-dir.c | 46 ++++------ plugins/solidigm/solidigm-nvme.c | 27 +++++- plugins/solidigm/solidigm-nvme.h | 6 +- plugins/solidigm/solidigm-ocp-version.c | 25 ++++++ plugins/solidigm/solidigm-ocp-version.h | 8 ++ plugins/solidigm/solidigm-smart.c | 12 +-- plugins/solidigm/solidigm-telemetry.c | 35 +++++--- plugins/solidigm/solidigm-telemetry/config.c | 2 +- plugins/solidigm/solidigm-telemetry/data-area.c | 2 +- plugins/solidigm/solidigm-telemetry/nlog.c | 5 +- plugins/solidigm/solidigm-temp-stats.c | 108 ++++++++++++++++++++++++ plugins/solidigm/solidigm-temp-stats.h | 8 ++ plugins/solidigm/solidigm-util.h | 2 + 19 files changed, 348 insertions(+), 72 deletions(-) create mode 100644 plugins/solidigm/solidigm-get-drive-info.c create mode 100644 plugins/solidigm/solidigm-get-drive-info.h create mode 100644 plugins/solidigm/solidigm-ocp-version.c create mode 100644 plugins/solidigm/solidigm-ocp-version.h create mode 100644 plugins/solidigm/solidigm-temp-stats.c create mode 100644 plugins/solidigm/solidigm-temp-stats.h (limited to 'plugins/solidigm') diff --git a/plugins/solidigm/meson.build b/plugins/solidigm/meson.build index 84495a1..052afa1 100644 --- a/plugins/solidigm/meson.build +++ b/plugins/solidigm/meson.build @@ -8,6 +8,9 @@ sources += [ 'plugins/solidigm/solidigm-telemetry.c', 'plugins/solidigm/solidigm-internal-logs.c', 'plugins/solidigm/solidigm-market-log.c', + 'plugins/solidigm/solidigm-temp-stats.c', + 'plugins/solidigm/solidigm-get-drive-info.c', + 'plugins/solidigm/solidigm-ocp-version.c', ] subdir('solidigm-telemetry') diff --git a/plugins/solidigm/solidigm-garbage-collection.c b/plugins/solidigm/solidigm-garbage-collection.c index b26d754..a37e9c5 100644 --- a/plugins/solidigm/solidigm-garbage-collection.c +++ b/plugins/solidigm/solidigm-garbage-collection.c @@ -68,6 +68,7 @@ static void vu_gc_log_show(struct garbage_control_collection_log *payload, const int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) { const char *desc = "Get and parse Solidigm vendor specific garbage collection event log."; + enum nvme_print_flags flags; struct nvme_dev *dev; int err; __u8 uuid_index; @@ -89,9 +90,8 @@ int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *c if (err) return err; - enum nvme_print_flags flags = validate_output_format(cfg.output_format); - - if (flags == -EINVAL) { + err = validate_output_format(cfg.output_format, &flags); + if (err) { fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format); dev_close(dev); return -EINVAL; diff --git a/plugins/solidigm/solidigm-get-drive-info.c b/plugins/solidigm/solidigm-get-drive-info.c new file mode 100644 index 0000000..21f59bb --- /dev/null +++ b/plugins/solidigm/solidigm-get-drive-info.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023 Solidigm. + * + * Authors: leonardo.da.cunha@solidigm.com + */ + +#include +#include "nvme-print.h" +#include "nvme-wrap.h" +#include "common.h" + +int sldgm_get_drive_info(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + const char *desc = "Get drive HW information"; + const char *FTL_unit_size_str = "FTL_unit_size"; + char *output_format = "normal"; + enum nvme_print_flags flags; + nvme_root_t r; + nvme_ctrl_t c; + nvme_ns_t n; + struct nvme_id_ns ns = { 0 }; + __u8 flbaf_inUse; + __u16 lba_size; + __u16 ftl_unit_size; + int err; + + OPT_ARGS(opts) = { + OPT_FMT("output-format", 'o', &output_format, "normal|json"), + OPT_END() + }; + + err = parse_and_open(&dev, argc, argv, desc, opts); + if (err) + return err; + + err = validate_output_format(output_format, &flags); + if ((err < 0) || !(flags == NORMAL || flags == JSON)) { + nvme_show_error("Invalid output format"); + return err; + } + + r = nvme_scan(NULL); + c = nvme_scan_ctrl(r, dev->name); + n = c ? nvme_ctrl_first_ns(c) : nvme_scan_namespace(dev->name); + if (!n) { + nvme_show_error("solidigm-vs-drive-info: drive missing namespace"); + return -EINVAL; + } + + err = nvme_ns_identify(n, &ns); + if (err) { + nvme_show_error("identify namespace: %s", nvme_strerror(errno)); + return err; + } + + if (!(ns.nsfeat & 0x10)) { + nvme_show_error("solidigm-vs-drive-info: performance options not available"); + return -EINVAL; + } + + nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &flbaf_inUse); + lba_size = 1 << ns.lbaf[flbaf_inUse].ds; + ftl_unit_size = (le16_to_cpu(ns.npwg) + 1) * lba_size / 1024; + + if (flags == JSON) { + struct json_object *root = json_create_object(); + + json_object_add_value_int(root, FTL_unit_size_str, ftl_unit_size); + json_print_object(root, NULL); + printf("\n"); + json_free_object(root); + } else { + printf("%s: %d\n", FTL_unit_size_str, ftl_unit_size); + } + + return err; +} diff --git a/plugins/solidigm/solidigm-get-drive-info.h b/plugins/solidigm/solidigm-get-drive-info.h new file mode 100644 index 0000000..ffc1bd2 --- /dev/null +++ b/plugins/solidigm/solidigm-get-drive-info.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023 Solidigm. + * + * Author: leonardo.da.cunha@solidigm.com + */ + +int sldgm_get_drive_info(int argc, char **argv, struct command *cmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-internal-logs.c b/plugins/solidigm/solidigm-internal-logs.c index 4730443..236652a 100644 --- a/plugins/solidigm/solidigm-internal-logs.c +++ b/plugins/solidigm/solidigm-internal-logs.c @@ -19,6 +19,7 @@ #include "libnvme.h" #include "plugin.h" #include "nvme-print.h" +#include "solidigm-util.h" #define DWORD_SIZE 4 @@ -427,7 +428,8 @@ static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetr int err = 0, output; __u8 *buffer = NULL; size_t bytes_remaining = 0; - int data_area = NVME_TELEMETRY_DA_3; + enum nvme_telemetry_da da; + size_t max_data_tx; char file_path[PATH_MAX]; char *log_name; @@ -444,6 +446,12 @@ static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetr default: return -EINVAL; } + err = nvme_get_telemetry_max(dev_fd(dev), &da, &max_data_tx); + if (err) + return err; + + if (max_data_tx > DRIVER_MAX_TX_256K) + max_data_tx = DRIVER_MAX_TX_256K; sprintf(file_path, "%s_%s.bin", cfg.file_prefix, log_name); output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); @@ -452,16 +460,16 @@ static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetr switch (ttype) { case HOSTGENNEW: - err = nvme_get_new_host_telemetry(dev_fd(dev), &log, - data_area, &log_size); + err = nvme_get_telemetry_log(dev_fd(dev), true, false, false, max_data_tx, da, + &log, &log_size); break; case HOSTGENOLD: - err = nvme_get_host_telemetry(dev_fd(dev), &log, - data_area, &log_size); + err = nvme_get_telemetry_log(dev_fd(dev), false, false, false, max_data_tx, da, + &log, &log_size); break; case CONTROLLER: - err = nvme_get_ctrl_telemetry(dev_fd(dev), true, &log, - data_area, &log_size); + err = nvme_get_telemetry_log(dev_fd(dev), false, true, true, max_data_tx, da, &log, + &log_size); break; } @@ -546,42 +554,42 @@ int solidigm_get_internal_log(int argc, char **argv, struct command *command, if (err == 0) log_count++; else if (err < 0) - perror("Assert log"); + perror("Error retrieving Assert log"); } if (all || !strcmp(cfg.type, "EVENT")) { err = dump_event_logs(dev, cfg); if (err == 0) log_count++; else if (err < 0) - perror("Eventt log"); + perror("Error retrieving Event log"); } if (all || !strcmp(cfg.type, "NLOG")) { err = dump_nlogs(dev, cfg, -1); if (err == 0) log_count++; else if (err < 0) - perror("Nlog"); + perror("Error retrieving Nlog"); } if (all || !strcmp(cfg.type, "CONTROLLERINITTELEMETRY")) { err = dump_telemetry(dev, cfg, CONTROLLER); if (err == 0) log_count++; else if (err < 0) - perror("Telemetry Controller Initated"); + perror("Error retrieving Telemetry Controller Initiated"); } if (all || !strcmp(cfg.type, "HOSTINITTELEMETRYNOGEN")) { err = dump_telemetry(dev, cfg, HOSTGENOLD); if (err == 0) log_count++; else if (err < 0) - perror("Previously existing Telemetry Host Initated"); + perror("Error retrieving previously existing Telemetry Host Initiated"); } if (all || !strcmp(cfg.type, "HOSTINITTELEMETRY")) { err = dump_telemetry(dev, cfg, HOSTGENNEW); if (err == 0) log_count++; else if (err < 0) - perror("Telemetry Host Initated"); + perror("Error retrieving Telemetry Host Initiated"); } if (log_count == 0) { diff --git a/plugins/solidigm/solidigm-latency-tracking.c b/plugins/solidigm/solidigm-latency-tracking.c index 481a831..66f3c56 100644 --- a/plugins/solidigm/solidigm-latency-tracking.c +++ b/plugins/solidigm/solidigm-latency-tracking.c @@ -411,8 +411,8 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd lt.fd = dev_fd(dev); - lt.print_flags = validate_output_format(lt.cfg.output_format); - if (lt.print_flags == -EINVAL) { + err = validate_output_format(lt.cfg.output_format, <.print_flags); + if (err < 0) { fprintf(stderr, "Invalid output format '%s'\n", lt.cfg.output_format); dev_close(dev); return -EINVAL; diff --git a/plugins/solidigm/solidigm-log-page-dir.c b/plugins/solidigm/solidigm-log-page-dir.c index 111a433..bf272f8 100644 --- a/plugins/solidigm/solidigm-log-page-dir.c +++ b/plugins/solidigm/solidigm-log-page-dir.c @@ -100,38 +100,13 @@ static struct lid_dir *get_standard_lids(struct nvme_supported_log_pages *suppor static struct lid_dir standard_dir = { 0 }; init_lid_dir(&standard_dir); - standard_dir.lid[0x00].str = "Supported Log Pages"; - standard_dir.lid[0x01].str = "Error Information"; - standard_dir.lid[0x02].str = "SMART / Health Information"; - standard_dir.lid[0x03].str = "Firmware Slot Information"; - standard_dir.lid[0x04].str = "Changed Namespace List"; - standard_dir.lid[0x05].str = "Commands Supported and Effects"; - standard_dir.lid[0x06].str = "Device Self Test"; - standard_dir.lid[0x07].str = "Telemetry Host-Initiated"; - standard_dir.lid[0x08].str = "Telemetry Controller-Initiated"; - standard_dir.lid[0x09].str = "Endurance Group Information"; - standard_dir.lid[0x0A].str = "Predictable Latency Per NVM Set"; - standard_dir.lid[0x0B].str = "Predictable Latency Event Aggregate"; - standard_dir.lid[0x0C].str = "Asymmetric Namespace Access"; - standard_dir.lid[0x0D].str = "Persistent Event Log"; - standard_dir.lid[0x0E].str = "Predictable Latency Event Aggregate"; - standard_dir.lid[0x0F].str = "Endurance Group Event Aggregate"; - standard_dir.lid[0x10].str = "Media Unit Status"; - standard_dir.lid[0x11].str = "Supported Capacity Configuration List"; - standard_dir.lid[0x12].str = "Feature Identifiers Supported and Effects"; - standard_dir.lid[0x13].str = "NVMe-MI Commands Supported and Effects"; - standard_dir.lid[0x14].str = "Command and Feature lockdown"; - standard_dir.lid[0x15].str = "Boot Partition"; - standard_dir.lid[0x16].str = "Rotational Media Information"; - standard_dir.lid[0x70].str = "Discovery"; - standard_dir.lid[0x80].str = "Reservation Notification"; - standard_dir.lid[0x81].str = "Sanitize Status"; for (int lid = 0; lid < NVME_LOG_SUPPORTED_LOG_PAGES_MAX; lid++) { if (!supported->lid_support[lid] || lid >= MIN_VENDOR_LID) continue; standard_dir.lid[lid].supported = true; + standard_dir.lid[lid].str = nvme_log_to_string(lid); } return &standard_dir; @@ -158,6 +133,14 @@ static struct lid_dir *get_solidigm_lids(struct nvme_supported_log_pages *suppor solidigm_dir.lid[0xC4].str = "Endurance Manager Statistics"; solidigm_dir.lid[0xC5].str = "Temperature Statistics"; solidigm_dir.lid[0xCA].str = "SMART Attributes"; + solidigm_dir.lid[0xCB].str = "VU NVMe IO Queue Metrics Log Page"; + 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[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"; update_vendor_lid_supported(supported, &solidigm_dir); @@ -281,15 +264,18 @@ int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *c } if (!err) { - const enum nvme_print_flags print_flag = validate_output_format(format); + enum nvme_print_flags print_flag; + + err = validate_output_format(format, &print_flag); + if (err < 0) { + fprintf(stderr, "Error: Invalid output format specified: %s.\n", format); + return err; + } if (print_flag == NORMAL) { supported_log_pages_normal(lid_dirs); } else if (print_flag == JSON) { supported_log_pages_json(lid_dirs); - } else { - fprintf(stderr, "Error: Invalid output format specified: %s.\n", format); - err = -EINVAL; } } diff --git a/plugins/solidigm/solidigm-nvme.c b/plugins/solidigm/solidigm-nvme.c index b0db1ea..3fb86f5 100644 --- a/plugins/solidigm/solidigm-nvme.c +++ b/plugins/solidigm/solidigm-nvme.c @@ -18,8 +18,11 @@ #include "solidigm-telemetry.h" #include "solidigm-log-page-dir.h" #include "solidigm-market-log.h" +#include "solidigm-temp-stats.h" +#include "solidigm-get-drive-info.h" +#include "solidigm-ocp-version.h" -#include "plugins/ocp/ocp-clear-fw-update-history.h" +#include "plugins/ocp/ocp-clear-features.h" #include "plugins/ocp/ocp-smart-extended-log.h" #include "plugins/ocp/ocp-fw-activation-history.h" @@ -59,6 +62,12 @@ static int clear_fw_update_history(int argc, char **argv, struct command *cmd, return ocp_clear_fw_update_history(argc, argv, cmd, plugin); } +static int clear_pcie_correctable_error_counters(int argc, char **argv, struct command *cmd, + struct plugin *plugin) +{ + return ocp_clear_pcie_correctable_errors(argc, argv, cmd, plugin); +} + static int smart_cloud(int argc, char **argv, struct command *cmd, struct plugin *plugin) { @@ -82,3 +91,19 @@ static int get_market_log(int argc, char **argv, struct command *cmd, { return sldgm_get_market_log(argc, argv, cmd, plugin); } + +static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + return sldgm_get_temp_stats_log(argc, argv, cmd, plugin); +} + +static int get_drive_info(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + return sldgm_get_drive_info(argc, argv, cmd, plugin); +} + +static int get_cloud_SSDplugin_version(int argc, char **argv, struct command *cmd, + struct plugin *plugin) +{ + return sldgm_ocp_version(argc, argv, cmd, plugin); +} diff --git a/plugins/solidigm/solidigm-nvme.h b/plugins/solidigm/solidigm-nvme.h index 69b63e5..a984a38 100644 --- a/plugins/solidigm/solidigm-nvme.h +++ b/plugins/solidigm/solidigm-nvme.h @@ -13,7 +13,7 @@ #include "cmd.h" -#define SOLIDIGM_PLUGIN_VERSION "0.14" +#define SOLIDIGM_PLUGIN_VERSION "1.0" PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_VERSION), COMMAND_LIST( @@ -25,9 +25,13 @@ PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_V ENTRY("market-log", "Retrieve Market Log", get_market_log) ENTRY("latency-tracking-log", "Enable/Retrieve Latency tracking Log", get_latency_tracking_log) ENTRY("parse-telemetry-log", "Parse Telemetry Log binary", get_telemetry_log) + ENTRY("clear-pcie-correctable-errors ", "Clear PCIe Correctable Error Counters (redirects to ocp plug-in)", clear_pcie_correctable_error_counters) ENTRY("clear-fw-activate-history", "Clear firmware update history log (redirects to ocp plug-in)", clear_fw_update_history) ENTRY("vs-fw-activate-history", "Get firmware activation history log (redirects to ocp plug-in)", fw_activation_history) ENTRY("log-page-directory", "Retrieve log page directory", get_log_page_directory_log) + ENTRY("temp-stats", "Retrieve Temperature Statistics log", get_temp_stats_log) + ENTRY("vs-drive-info", "Retrieve drive information", get_drive_info) + ENTRY("cloud-SSDplugin-version", "Prints plug-in OCP version", get_cloud_SSDplugin_version) ) ); diff --git a/plugins/solidigm/solidigm-ocp-version.c b/plugins/solidigm/solidigm-ocp-version.c new file mode 100644 index 0000000..4048cc1 --- /dev/null +++ b/plugins/solidigm/solidigm-ocp-version.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023 Solidigm. + * + * Author: leonardo.da.cunha@solidigm.com + */ + +#include +#include "nvme.h" + +int sldgm_ocp_version(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Prints OCP extensions version of Solidigm plugin"; + + OPT_ARGS(opts) = { + OPT_END() + }; + + int err = argconfig_parse(argc, argv, desc, opts); + + if (!err) + printf("1.0\n"); + + return err; +} diff --git a/plugins/solidigm/solidigm-ocp-version.h b/plugins/solidigm/solidigm-ocp-version.h new file mode 100644 index 0000000..d79452c --- /dev/null +++ b/plugins/solidigm/solidigm-ocp-version.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023 Solidigm. + * + * Author: leonardo.da.cunha@solidigm.com + */ + +int sldgm_ocp_version(int argc, char **argv, struct command *cmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-smart.c b/plugins/solidigm/solidigm-smart.c index e3d468a..62245fa 100644 --- a/plugins/solidigm/solidigm-smart.c +++ b/plugins/solidigm/solidigm-smart.c @@ -69,15 +69,17 @@ static char *id_to_name(__u8 id) case 0xE2: return "media_wear_percentage"; case 0xE3: - return "host_reads"; + return "timed_work_load_host_reads"; case 0xE4: - return "timed_work_load"; + return "timed_work_load_timer"; case 0xE5: return "read_commands_in_flight_counter"; case 0xE6: return "write_commands_in_flight_counter"; case 0xEA: return "thermal_throttle_status"; + case 0xEE: + return "re_sku_count"; case 0xF0: return "retry_buffer_overflow_counter"; case 0xF3: @@ -220,11 +222,11 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd if (err) return err; - flags = validate_output_format(cfg.output_format); - if (flags == -EINVAL) { + err = validate_output_format(cfg.output_format, &flags); + if (err < 0) { fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format); dev_close(dev); - return flags; + return err; } uuid_index = solidigm_get_vu_uuid_index(dev); diff --git a/plugins/solidigm/solidigm-telemetry.c b/plugins/solidigm/solidigm-telemetry.c index 472284a..2bebccc 100644 --- a/plugins/solidigm/solidigm-telemetry.c +++ b/plugins/solidigm/solidigm-telemetry.c @@ -22,6 +22,7 @@ #include "solidigm-telemetry/header.h" #include "solidigm-telemetry/config.h" #include "solidigm-telemetry/data-area.h" +#include "solidigm-util.h" static int read_file2buffer(char *file_name, char **buffer, size_t *length) { @@ -71,7 +72,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc struct config cfg = { .host_gen = 1, .ctrl_init = false, - .data_area = 3, + .data_area = -1, .cfg_file = NULL, .is_input_file = false, }; @@ -90,6 +91,10 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc if (err) goto ret; + /* When not selected on the command line, get minimum data area required */ + if (cfg.data_area == -1) + cfg.data_area = cfg.cfg_file ? 3 : 1; + if (cfg.is_input_file) { if (optind >= argc) { err = errno = EINVAL; @@ -138,19 +143,23 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc } if (!cfg.is_input_file) { - if (cfg.ctrl_init) - err = nvme_get_ctrl_telemetry(dev_fd(dev), true, - &tl.log, cfg.data_area, - &tl.log_size); - else if (cfg.host_gen) - err = nvme_get_new_host_telemetry(dev_fd(dev), &tl.log, - cfg.data_area, - &tl.log_size); - else - err = nvme_get_host_telemetry(dev_fd(dev), &tl.log, - cfg.data_area, - &tl.log_size); + size_t max_data_tx; + + err = nvme_get_telemetry_max(dev_fd(dev), NULL, &max_data_tx); + if (err < 0) { + SOLIDIGM_LOG_WARNING("identify_ctrl: %s", + nvme_strerror(errno)); + goto close_fd; + } else if (err > 0) { + nvme_show_status(err); + SOLIDIGM_LOG_WARNING("Failed to acquire identify ctrl %d!", err); + goto close_fd; + } + if (max_data_tx > DRIVER_MAX_TX_256K) + max_data_tx = DRIVER_MAX_TX_256K; + err = nvme_get_telemetry_log(dev_fd(dev), cfg.host_gen, cfg.ctrl_init, true, + max_data_tx, cfg.data_area, &tl.log, &tl.log_size); if (err < 0) { SOLIDIGM_LOG_WARNING("get-telemetry-log: %s", nvme_strerror(errno)); diff --git a/plugins/solidigm/solidigm-telemetry/config.c b/plugins/solidigm/solidigm-telemetry/config.c index cc2a8bb..eceeede 100644 --- a/plugins/solidigm/solidigm-telemetry/config.c +++ b/plugins/solidigm/solidigm-telemetry/config.c @@ -9,7 +9,7 @@ #include #include "config.h" -// max 16 bit unsigned integer nummber 65535 +// max 16 bit unsigned integer number 65535 #define MAX_16BIT_NUM_AS_STRING_SIZE 6 #define OBJ_NAME_PREFIX "UID_" diff --git a/plugins/solidigm/solidigm-telemetry/data-area.c b/plugins/solidigm/solidigm-telemetry/data-area.c index 0cfa56c..14d612b 100644 --- a/plugins/solidigm/solidigm-telemetry/data-area.c +++ b/plugins/solidigm/solidigm-telemetry/data-area.c @@ -57,7 +57,7 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl, char err_msg[MAX_WARNING_SIZE]; snprintf(err_msg, MAX_WARNING_SIZE, - "Value crossing 64 bit, byte aligned bounday, not supported. size_bit=%u, offset_bit_from_byte=%u.", + "Value crossing 64 bit, byte aligned boundary, not supported. size_bit=%u, offset_bit_from_byte=%u.", size_bit, offset_bit_from_byte); *val_obj = json_object_new_string(err_msg); diff --git a/plugins/solidigm/solidigm-telemetry/nlog.c b/plugins/solidigm/solidigm-telemetry/nlog.c index 43b8918..926772b 100644 --- a/plugins/solidigm/solidigm-telemetry/nlog.c +++ b/plugins/solidigm/solidigm-telemetry/nlog.c @@ -8,15 +8,16 @@ #include "nlog.h" #include "config.h" #include -#include #include +#include "ccan/ilog/ilog.h" + #define LOG_ENTRY_HEADER_SIZE 1 #define LOG_ENTRY_TIMESTAMP_SIZE 2 #define LOG_ENTRY_NUM_ARGS_MAX 8 #define LOG_ENTRY_MAX_SIZE (LOG_ENTRY_HEADER_SIZE + LOG_ENTRY_TIMESTAMP_SIZE + \ LOG_ENTRY_NUM_ARGS_MAX) -#define NUM_ARGS_MASK ((1 << ((int)log2(LOG_ENTRY_NUM_ARGS_MAX)+1)) - 1) +#define NUM_ARGS_MASK ((1 << ((int)STATIC_ILOG_32(LOG_ENTRY_NUM_ARGS_MAX))) - 1) #define MAX_HEADER_MISMATCH_TRACK 10 static int formats_find(struct json_object *formats, uint32_t val, struct json_object **format) diff --git a/plugins/solidigm/solidigm-temp-stats.c b/plugins/solidigm/solidigm-temp-stats.c new file mode 100644 index 0000000..85a3c37 --- /dev/null +++ b/plugins/solidigm/solidigm-temp-stats.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023 Solidigm. + * + * Author: leonardo.da.cunha@solidigm.com + */ + +#include + +#include "common.h" +#include "nvme-print.h" +#include "solidigm-util.h" + +#define SLDGM_TEMP_STATS_LID 0xC5 + +struct temp_stats { + __le64 curr; + __le64 last_overtemp; + __le64 life_overtemp; + __le64 highest_temp; + __le64 lowest_temp; + __u8 rsvd[40]; + __le64 max_operating_temp; + __le64 min_operating_temp; + __le64 est_offset; +}; + +static void show_temp_stats(struct temp_stats *stats) +{ + printf("Current temperature : %"PRIu64"\n", le64_to_cpu(stats->curr)); + printf("Last critical overtemp flag : %"PRIu64"\n", le64_to_cpu(stats->last_overtemp)); + printf("Life critical overtemp flag : %"PRIu64"\n", le64_to_cpu(stats->life_overtemp)); + printf("Highest temperature : %"PRIu64"\n", le64_to_cpu(stats->highest_temp)); + printf("Lowest temperature : %"PRIu64"\n", le64_to_cpu(stats->lowest_temp)); + printf("Max operating temperature : %"PRIu64"\n", le64_to_cpu(stats->max_operating_temp)); + printf("Min operating temperature : %"PRIu64"\n", le64_to_cpu(stats->min_operating_temp)); + printf("Estimated offset : %"PRIu64"\n", le64_to_cpu(stats->est_offset)); +} + +int sldgm_get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + unsigned char buffer[4096] = {0}; + struct nvme_dev *dev; + __u8 uuid_idx; + int err; + + const char *desc = "Get/show Temperature Statistics log."; + const char *raw = "dump output in binary format"; + struct config { + bool raw_binary; + }; + + struct config cfg = { + .raw_binary = false, + }; + + OPT_ARGS(opts) = { + OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw), + OPT_END() + }; + + err = parse_and_open(&dev, argc, argv, desc, opts); + if (err) + return err; + + uuid_idx = solidigm_get_vu_uuid_index(dev); + + struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = buffer, + .args_size = sizeof(args), + .fd = dev_fd(dev), + .uuidx = uuid_idx, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .lid = SLDGM_TEMP_STATS_LID, + .len = sizeof(buffer), + .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) { + uint64_t *guid = (uint64_t *)&buffer[4080]; + + if (guid[1] == 0xC7BB98B7D0324863 && guid[0] == 0xBB2C23990E9C722F) { + fprintf(stderr, "Error: Log page has 'OCP unsupported Requirements' GUID\n"); + err = -EBADMSG; + goto closefd; + } + if (!cfg.raw_binary) + show_temp_stats((struct temp_stats *) buffer); + else + d_raw(buffer, sizeof(struct temp_stats)); + } else if (err > 0) { + nvme_show_status(err); + } + +closefd: + /* Redundant close() to make static code analysis happy */ + close(dev->direct.fd); + dev_close(dev); + return err; +} diff --git a/plugins/solidigm/solidigm-temp-stats.h b/plugins/solidigm/solidigm-temp-stats.h new file mode 100644 index 0000000..58d5a86 --- /dev/null +++ b/plugins/solidigm/solidigm-temp-stats.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023 Solidigm. + * + * Author: leonardo.da.cunha@solidigm.com + */ + +int sldgm_get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-util.h b/plugins/solidigm/solidigm-util.h index 3a18501..fa5032f 100644 --- a/plugins/solidigm/solidigm-util.h +++ b/plugins/solidigm/solidigm-util.h @@ -7,4 +7,6 @@ #include "nvme.h" +#define DRIVER_MAX_TX_256K (256 * 1024) + __u8 solidigm_get_vu_uuid_index(struct nvme_dev *dev); -- cgit v1.2.3