summaryrefslogtreecommitdiffstats
path: root/plugins/intel/intel-nvme.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/intel/intel-nvme.c')
-rw-r--r--plugins/intel/intel-nvme.c238
1 files changed, 147 insertions, 91 deletions
diff --git a/plugins/intel/intel-nvme.c b/plugins/intel/intel-nvme.c
index aaa40ad..80d218c 100644
--- a/plugins/intel/intel-nvme.c
+++ b/plugins/intel/intel-nvme.c
@@ -5,16 +5,12 @@
#include <unistd.h>
#include <inttypes.h>
-#include "linux/nvme_ioctl.h"
-
#include "common.h"
#include "nvme.h"
-#include "nvme-print.h"
-#include "nvme-ioctl.h"
+#include "libnvme.h"
#include "plugin.h"
-
-#include "argconfig.h"
-#include "suffix.h"
+#include "linux/types.h"
+#include "nvme-print.h"
#define CREATE_CMD
#include "intel-nvme.h"
@@ -351,8 +347,8 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
struct config {
__u32 namespace_id;
- int raw_binary;
- int json;
+ bool raw_binary;
+ bool json;
};
struct config cfg = {
@@ -370,8 +366,7 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
if (fd < 0)
return fd;
- err = nvme_get_log(fd, cfg.namespace_id, 0xca, false,
- NVME_NO_LOG_LSP, sizeof(smart_log), &smart_log);
+ err = nvme_get_log_simple(fd, 0xca, sizeof(smart_log), &smart_log);
if (!err) {
if (cfg.json)
show_intel_smart_log_jsn(&smart_log, cfg.namespace_id, devicename);
@@ -381,8 +376,7 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
}
else if (err > 0)
- fprintf(stderr, "NVMe Status:%s(%x)\n",
- nvme_status_to_string(err), err);
+ nvme_show_status(err);
return err;
}
@@ -395,7 +389,7 @@ static int get_market_log(int argc, char **argv, struct command *cmd, struct plu
int err, fd;
struct config {
- int raw_binary;
+ bool raw_binary;
};
struct config cfg = {
@@ -410,16 +404,14 @@ static int get_market_log(int argc, char **argv, struct command *cmd, struct plu
if (fd < 0)
return fd;
- err = nvme_get_log(fd, NVME_NSID_ALL, 0xdd, false,
- NVME_NO_LOG_LSP, sizeof(log), log);
+ err = nvme_get_log_simple(fd, 0xdd, sizeof(log), log);
if (!err) {
if (!cfg.raw_binary)
printf("Intel Marketing Name Log:\n%s\n", log);
else
d_raw((unsigned char *)&log, sizeof(log));
} else if (err > 0)
- fprintf(stderr, "NVMe Status:%s(%x)\n",
- nvme_status_to_string(err), err);
+ nvme_show_status(err);
return err;
}
@@ -457,7 +449,7 @@ static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct
const char *desc = "Get Temperature Statistics log and show it.";
const char *raw = "dump output in binary format";
struct config {
- int raw_binary;
+ bool raw_binary;
};
struct config cfg = {
@@ -472,16 +464,14 @@ static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct
if (fd < 0)
return fd;
- err = nvme_get_log(fd, NVME_NSID_ALL, 0xc5, false,
- NVME_NO_LOG_LSP, sizeof(stats), &stats);
+ err = nvme_get_log_simple(fd, 0xc5, sizeof(stats), &stats);
if (!err) {
if (!cfg.raw_binary)
show_temp_stats(&stats);
else
d_raw((unsigned char *)&stats, sizeof(stats));
} else if (err > 0)
- fprintf(stderr, "NVMe Status:%s(%x)\n",
- nvme_status_to_string(err), err);
+ nvme_show_status(err);
return err;
}
@@ -497,10 +487,13 @@ struct __attribute__((__packed__)) optane_lat_stats {
__u64 data[9];
};
-#define MEDIA_MAJOR_IDX 0
-#define MEDIA_MINOR_IDX 1
-#define MEDIA_MAX_LEN 2
-#define OPTANE_V1000_BUCKET_LEN 8
+#define MEDIA_MAJOR_IDX 0
+#define MEDIA_MINOR_IDX 1
+#define MEDIA_MAX_LEN 2
+#define OPTANE_V1000_BUCKET_LEN 8
+#define OPTANE_V1000_BUCKET_LEN 8
+#define NAND_LAT_STATS_LEN 4868
+
static struct intel_lat_stats stats;
static struct optane_lat_stats v1000_stats;
@@ -529,7 +522,7 @@ enum FormatUnit {
#define US_IN_S 1000000
#define US_IN_MS 1000
-static const enum FormatUnit get_seconds_magnitude(__u32 microseconds)
+static enum FormatUnit get_seconds_magnitude(__u32 microseconds)
{
if (microseconds > US_IN_S)
return S;
@@ -539,7 +532,7 @@ static const enum FormatUnit get_seconds_magnitude(__u32 microseconds)
return US;
}
-static const float convert_seconds(__u32 microseconds)
+static float convert_seconds(__u32 microseconds)
{
float divisor = 1.0;
@@ -567,13 +560,15 @@ enum inf_bound_type {
* either of "-INF" or "+INF", respectively.
*/
static void set_unit_string(char *buffer, __u32 microseconds,
- enum FormatUnit unit, enum inf_bound_type bound_type)
+ enum FormatUnit unit,
+ enum inf_bound_type bound_type)
{
+ char *string;
+
if (bound_type != NOINF) {
- snprintf(buffer, 5, "%s", bound_type ? "+INF" : "-INF");
+ snprintf(buffer, BUFSIZE, "%s", bound_type ? "+INF" : "-INF");
return;
}
- char *string;
switch (unit) {
case US:
@@ -589,8 +584,9 @@ static void set_unit_string(char *buffer, __u32 microseconds,
string = "_s";
break;
}
- snprintf(buffer, 11, "%4.2f%s",
- convert_seconds(microseconds), string);
+
+ snprintf(buffer, BUFSIZE, "%4.2f%s", convert_seconds(microseconds),
+ string);
}
static void init_buffer(char *buffer, size_t size)
@@ -660,12 +656,11 @@ static void show_lat_stats_linear(struct intel_lat_stats *stats,
/*
* For 4.0-4.5 revision.
*/
+#define LATENCY_STATS_V4_BASE_BITS 6
+#define LATENCY_STATS_V4_BASE_VAL (1 << LATENCY_STATS_V4_BASE_BITS)
+
static int lat_stats_log_scale(int i)
{
- static const int LATENCY_STATS_V4_BASE_BITS = 6;
- static const int LATENCY_STATS_V4_BASE_VAL = (
- 1 << LATENCY_STATS_V4_BASE_BITS);
-
// if (i < 128)
if (i < (LATENCY_STATS_V4_BASE_VAL << 1))
return i;
@@ -715,8 +710,7 @@ static void json_add_bucket(struct intel_lat_stats *stats,
init_buffer(buffer, BUFSIZE);
- json_object_add_value_object(bucket_list,
- "bucket", bucket);
+ json_object_array_add(bucket_list, bucket);
json_object_add_value_int(bucket, "id", id);
set_unit_string(buffer, lower_us,
@@ -739,8 +733,7 @@ static void json_add_bucket_optane(struct json_object *bucket_list, __u32 id,
init_buffer(buffer, BUFSIZE);
- json_object_add_value_object(bucket_list,
- "bucket", bucket);
+ json_object_array_add(bucket_list, bucket);
json_object_add_value_int(bucket, "id", id);
set_unit_string(buffer, lower_us,
@@ -775,7 +768,7 @@ static void json_lat_stats_3_0(struct intel_lat_stats *stats,
int write)
{
struct json_object *root = json_create_object();
- struct json_object *bucket_list = json_create_object();
+ struct json_object *bucket_list = json_object_new_array();
lat_stats_make_json_root(root, bucket_list, write);
@@ -794,7 +787,7 @@ static void json_lat_stats_4_0(struct intel_lat_stats *stats,
int write)
{
struct json_object *root = json_create_object();
- struct json_object *bucket_list = json_create_object();
+ struct json_object *bucket_list = json_object_new_array();
lat_stats_make_json_root(root, bucket_list, write);
@@ -847,11 +840,11 @@ static void show_lat_stats_4_0(struct intel_lat_stats *stats)
}
}
-static void jason_lat_stats_v1000_0(struct optane_lat_stats *stats, int write)
+static void json_lat_stats_v1000_0(struct optane_lat_stats *stats, int write)
{
int i;
struct json_object *root = json_create_object();
- struct json_object *bucket_list = json_create_object();
+ struct json_object *bucket_list = json_object_new_array();
lat_stats_make_json_root(root, bucket_list, write);
@@ -951,7 +944,7 @@ static void json_lat_stats(int write)
case 1000:
switch (media_version[MEDIA_MINOR_IDX]) {
case 0:
- jason_lat_stats_v1000_0(&v1000_stats, write);
+ json_lat_stats_v1000_0(&v1000_stats, write);
break;
default:
printf("Unsupported minor revision (%u.%u)\n",
@@ -998,6 +991,7 @@ static void show_lat_stats(int write)
case 3:
case 4:
case 5:
+ case 6:
show_lat_stats_4_0(&stats);
break;
default:
@@ -1028,6 +1022,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
{
int err, fd;
+ __u8 data[NAND_LAT_STATS_LEN];
const char *desc = "Get Intel Latency Statistics log and show it.";
const char *raw = "Dump output in binary format";
@@ -1035,9 +1030,9 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
const char *write = "Get write statistics (read default)";
struct config {
- int raw_binary;
- int json;
- int write;
+ bool raw_binary;
+ bool json;
+ bool write;
};
struct config cfg = {
@@ -1054,10 +1049,15 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
if (fd < 0)
return fd;
- /* Query maj and minor version first */
- err = nvme_get_log(fd, NVME_NSID_ALL, cfg.write ? 0xc2 : 0xc1,
- false, NVME_NO_LOG_LSP, sizeof(media_version),
- media_version);
+ /* For optate, latency stats are deleted every time their LID is pulled.
+ * Therefore, we query the longest lat_stats log page first.
+ */
+ err = nvme_get_log_simple(fd, cfg.write ? 0xc2 : 0xc1,
+ sizeof(data), &data);
+
+ media_version[0] = (data[1] << 8) | data[0];
+ media_version[1] = (data[3] << 8) | data[2];
+
if (err)
goto close_fd;
@@ -1065,11 +1065,23 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
__u32 thresholds[OPTANE_V1000_BUCKET_LEN] = {0};
__u32 result;
- err = nvme_get_feature(fd, 0, 0xf7, 0, cfg.write ? 0x1 : 0x0, 0,
- sizeof(thresholds), thresholds, &result);
+ struct nvme_get_features_args args = {
+ .args_size = sizeof(args),
+ .fd = fd,
+ .fid = 0xf7,
+ .nsid = 0,
+ .sel = 0,
+ .cdw11 = cfg.write ? 0x1 : 0x0,
+ .uuidx = 0,
+ .data_len = sizeof(thresholds),
+ .data = thresholds,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+ err = nvme_get_features(&args);
if (err) {
- fprintf(stderr, "Quering thresholds failed. NVMe Status:%s(%x)\n",
- nvme_status_to_string(err), err);
+ fprintf(stderr, "Quering thresholds failed. ");
+ nvme_show_status(err);
goto close_fd;
}
@@ -1083,13 +1095,14 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
}
- err = nvme_get_log(fd, NVME_NSID_ALL, cfg.write ? 0xc2 : 0xc1,
- false, NVME_NO_LOG_LSP, sizeof(v1000_stats),
- &v1000_stats);
+ /* Move counter values to optate stats struct which has a
+ * smaller size
+ */
+ memcpy(&v1000_stats, (struct optane_lat_stats *)data,
+ sizeof(struct optane_lat_stats));
} else {
- err = nvme_get_log(fd, NVME_NSID_ALL, cfg.write ? 0xc2 : 0xc1,
- false, NVME_NO_LOG_LSP, sizeof(stats),
- &stats);
+ memcpy(&stats, (struct intel_lat_stats *)data,
+ sizeof(struct intel_lat_stats));
}
if (!err) {
@@ -1097,11 +1110,16 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
json_lat_stats(cfg.write);
else if (!cfg.raw_binary)
show_lat_stats(cfg.write);
- else
- d_raw((unsigned char *)&stats, sizeof(stats));
+ else {
+ if (media_version[0] == 1000)
+ d_raw((unsigned char *)&v1000_stats,
+ sizeof(v1000_stats));
+ else
+ d_raw((unsigned char *)&stats,
+ sizeof(stats));
+ }
} else if (err > 0)
- fprintf(stderr, "NVMe Status:%s(%x)\n",
- nvme_status_to_string(err), err);
+ nvme_show_status(err);
close_fd:
close(fd);
return err;
@@ -1213,7 +1231,7 @@ static int read_entire_cmd(struct nvme_passthru_cmd *cmd, int total_size,
dword_tfer = min(max_tfer, total_size);
while (total_size > 0) {
- err = nvme_submit_admin_passthru(ioctl_fd, cmd);
+ err = nvme_submit_admin_passthru(ioctl_fd, cmd, NULL);
if (err) {
fprintf(stderr,
"failed on cmd.data_len %u cmd.cdw13 %u cmd.cdw12 %x cmd.cdw10 %u err %x remaining size %d\n",
@@ -1478,8 +1496,7 @@ static int get_internal_log(int argc, char **argv, struct command *command,
err = 0;
out:
if (err > 0) {
- fprintf(stderr, "NVMe Status:%s(%x)\n",
- nvme_status_to_string(err), err);
+ nvme_show_status(err);
} else if (err < 0) {
perror("intel log");
err = EIO;
@@ -1518,8 +1535,8 @@ static int enable_lat_stats_tracking(int argc, char **argv,
};
const struct argconfig_commandline_options command_line_options[] = {
- {"enable", 'e', "", CFG_NONE, &cfg.enable, no_argument, enable_desc},
- {"disable", 'd', "", CFG_NONE, &cfg.disable, no_argument, disable_desc},
+ {"enable", 'e', "", CFG_FLAG, &cfg.enable, no_argument, enable_desc},
+ {"disable", 'd', "", CFG_FLAG, &cfg.disable, no_argument, disable_desc},
{NULL}
};
@@ -1540,10 +1557,40 @@ static int enable_lat_stats_tracking(int argc, char **argv,
if (fd < 0)
return fd;
+
+ struct nvme_get_features_args args_get = {
+ .args_size = sizeof(args_get),
+ .fd = fd,
+ .fid = fid,
+ .nsid = nsid,
+ .sel = sel,
+ .cdw11 = cdw11,
+ .uuidx = 0,
+ .data_len = data_len,
+ .data = buf,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+
+ struct nvme_set_features_args args_set = {
+ .args_size = sizeof(args_set),
+ .fd = fd,
+ .fid = fid,
+ .nsid = nsid,
+ .cdw11 = option,
+ .cdw12 = cdw12,
+ .save = save,
+ .uuidx = 0,
+ .cdw15 = 0,
+ .data_len = data_len,
+ .data = buf,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+
switch (option) {
case None:
- err = nvme_get_feature(fd, nsid, fid, sel, cdw11, 0, data_len, buf,
- &result);
+ err = nvme_get_features(&args_get);
if (!err) {
printf(
"Latency Statistics Tracking (FID 0x%X) is currently (%i).\n",
@@ -1555,11 +1602,9 @@ static int enable_lat_stats_tracking(int argc, char **argv,
break;
case True:
case False:
- err = nvme_set_feature(fd, nsid, fid, option, cdw12, save, 0,
- data_len, buf, &result);
+ err = nvme_set_features(&args_set);
if (err > 0) {
- fprintf(stderr, "NVMe Status:%s(%x)\n",
- nvme_status_to_string(err), err);
+ nvme_show_status(err);
} else if (err < 0) {
perror("Enable latency tracking");
fprintf(stderr, "Command failed while parsing.\n");
@@ -1590,12 +1635,12 @@ static int set_lat_stats_thresholds(int argc, char **argv,
__u32 result;
struct config {
- int write;
+ bool write;
char *bucket_thresholds;
};
struct config cfg = {
- .write = 0,
+ .write = false,
.bucket_thresholds = "",
};
@@ -1615,12 +1660,11 @@ static int set_lat_stats_thresholds(int argc, char **argv,
* valid buckets a user is allowed to modify. Read or write doesn't
* matter
*/
- err = nvme_get_log(fd, NVME_NSID_ALL, 0xc2,
- false, NVME_NO_LOG_LSP, sizeof(media_version),
- media_version);
+ err = nvme_get_log_simple(fd, 0xc2,
+ sizeof(media_version), media_version);
if (err) {
- fprintf(stderr, "Querying media version failed. NVMe Status:%s(%x)\n",
- nvme_status_to_string(err), err);
+ fprintf(stderr, "Querying media version failed. ");
+ nvme_show_status(err);
goto close_fd;
}
@@ -1635,13 +1679,25 @@ static int set_lat_stats_thresholds(int argc, char **argv,
}
- err = nvme_set_feature(fd, nsid, fid, cfg.write ? 0x1 : 0x0,
- cdw12, save, 0, OPTANE_V1000_BUCKET_LEN,
- thresholds, &result);
+ struct nvme_set_features_args args = {
+ .args_size = sizeof(args),
+ .fd = fd,
+ .fid = fid,
+ .nsid = nsid,
+ .cdw11 = cfg.write ? 0x1 : 0x0,
+ .cdw12 = cdw12,
+ .save = save,
+ .uuidx = 0,
+ .cdw15 = 0,
+ .data_len = sizeof(thresholds),
+ .data = thresholds,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+ err = nvme_set_features(&args);
if (err > 0) {
- fprintf(stderr, "NVMe Status:%s(%x)\n",
- nvme_status_to_string(err), err);
+ nvme_show_status(err);
} else if (err < 0) {
perror("Enable latency tracking");
fprintf(stderr, "Command failed while parsing.\n");