Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Documentation/nvme-solidigm-workload-tracker.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ nvme-solidigm-workload-tracker - Real-time capture of Workload Tracker samples
SYNOPSIS
--------
[verse]
'nvme solidigm workload-tracker' <device> [--enable | -e] [--disable | -d]
'nvme solidigm workload-tracker' <device> [--uuid-index=<id> | -U <id>]
[--enable | -e] [--disable | -d]
[--sample-time=<time> | -s <time>]
[--type=<type> | -t <type>]
[--run-time=<seconds> | -r <seconds>]
Expand All @@ -31,6 +32,9 @@ device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).

OPTIONS
-------
-U <id>, --uuid-index=<id>::
Specify the UUID index (0-127) for the command.

-e, --enable::
Enable the workload tracker before capturing samples.

Expand Down
2 changes: 2 additions & 0 deletions completions/_nvme
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,8 @@ _nvme () {
(workload-tracker)
local _workload_tracker
_workload_tracker=(
'--uuid-index=:specify uuid index'
'-U:alias for --uuid-index'
--enable':Enable Workload Tracker'
-e':alias for --enable'
--disable':Disable Workload Tracker'
Expand Down
2 changes: 1 addition & 1 deletion completions/bash-nvme-completion.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,7 @@ plugin_solidigm_opts () {
opts+=" --raw-binary -b"
;;
"workload-tracker")
opts+=" --enable -e --disable -d --sample-time= -s \
opts+=" --uuid-index= -U --enable -e --disable -d --sample-time= -s \
--type= -t --run-time= -r --flush-freq= -f \
--wall-clock -w --trigger-field= -T \
--trigger-threshold= -V --trigger-on-delta -D \
Expand Down
19 changes: 13 additions & 6 deletions plugins/solidigm/solidigm-log-page-dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);

Expand Down Expand Up @@ -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()
};

Expand Down Expand Up @@ -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;
}

Expand Down
58 changes: 37 additions & 21 deletions plugins/solidigm/solidigm-market-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,45 +18,61 @@
#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,
struct plugin *plugin)
{
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()
};

err = parse_and_open(&dev, argc, argv, desc, opts);
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;
}
2 changes: 1 addition & 1 deletion plugins/solidigm/solidigm-nvme.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
60 changes: 42 additions & 18 deletions plugins/solidigm/solidigm-workload-tracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand All @@ -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);
Expand All @@ -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);
}

Expand All @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -331,15 +342,15 @@ 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);
}
we.trackerEnable = true;
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);
Expand All @@ -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);
}
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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),
Expand All @@ -542,14 +554,19 @@ 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()
};

err = parse_and_open(&dev, argc, argv, desc, opts);
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)) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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;
Expand Down