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
69 changes: 69 additions & 0 deletions nvme-print-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -3712,6 +3712,72 @@ static void json_feature_show_fields_power_loss_signal(struct json_object *r, un
nvme_pls_mode_to_string(NVME_GET(result, FEAT_PLS_MODE)));
}

static void json_feat_perfc_std(struct json_object *r, struct nvme_std_perf_attr *data)
{
obj_add_str(r, "random 4 kib average read latency",
nvme_feature_perfc_r4karl_to_string(data->r4karl));
obj_add_uint_02x(r, "R4KARL", data->r4karl);
}

static void json_feat_perfc_id_list(struct json_object *r, struct nvme_perf_attr_id_list *data)
{
int i;
int attri_vs;
char json_str[STR_LEN];
struct json_object *paida = json_create_array();
struct json_object *paide;

obj_add_str(r, "attribute type", nvme_feature_perfc_attrtyp_to_string(data->attrtyp));
obj_add_uint_02x(r, "ATTRTYP", data->attrtyp);
obj_add_int(r, "maximum saveable vendor specific performance attributes (MSVSPA)",
data->msvspa);
obj_add_int(r, "unused saveable vendor specific performance attributes (USVSPA)",
data->usvspa);

obj_add_array(r, "performance attribute identifier list", paida);
for (i = 0; i < ARRAY_SIZE(data->id_list); i++) {
paide = json_create_object();
array_add_obj(paida, paide);
attri_vs = i + NVME_FEAT_PERFC_ATTRI_VS_MIN;
sprintf(json_str, "performance attribute %02xh identifier (PA%02XHI)", attri_vs,
attri_vs);
obj_add_str(paide, json_str, util_uuid_to_string(data->id_list[i].id));
}
}

static void json_feat_perfc_vs(struct json_object *r, struct nvme_vs_perf_attr *data)
{
obj_add_str(r, "performance attribute identifier (PAID)", util_uuid_to_string(data->paid));
obj_add_uint(r, "attribute length (ATTRL)", data->attrl);
obj_d(r, "vendor specific (VS)", (unsigned char *)data->vs, data->attrl, 16, 1);
}

static void json_feat_perfc(struct json_object *r, enum nvme_features_id fid, unsigned int result,
struct nvme_perf_characteristics *data)
{
__u8 attri;
bool rvspa;

nvme_feature_decode_perf_characteristics(result, &attri, &rvspa);

obj_add_str(r, "attribute index", nvme_feature_perfc_attri_to_string(attri));
obj_add_uint_02x(r, "ATTRI", attri);

switch (attri) {
case NVME_FEAT_PERFC_ATTRI_STD:
json_feat_perfc_std(r, data->std_perf);
break;
case NVME_FEAT_PERFC_ATTRI_ID_LIST:
json_feat_perfc_id_list(r, data->id_list);
break;
case NVME_FEAT_PERFC_ATTRI_VS_MIN ... NVME_FEAT_PERFC_ATTRI_VS_MAX:
json_feat_perfc_vs(r, data->vs_perf);
break;
default:
break;
}
}

static void json_host_metadata(struct json_object *r, enum nvme_features_id fid,
struct nvme_host_metadata *data)
{
Expand Down Expand Up @@ -3925,6 +3991,9 @@ static void json_feature_show_fields(enum nvme_features_id fid, unsigned int res
case NVME_FEAT_FID_POWER_LOSS_SIGNAL:
json_feature_show_fields_power_loss_signal(r, result);
break;
case NVME_FEAT_FID_PERF_CHARACTERISTICS:
json_feat_perfc(r, fid, result, (struct nvme_perf_characteristics *)buf);
break;
case NVME_FEAT_FID_ENH_CTRL_METADATA:
case NVME_FEAT_FID_CTRL_METADATA:
case NVME_FEAT_FID_NS_METADATA:
Expand Down
63 changes: 63 additions & 0 deletions nvme-print-stdout.c
Original file line number Diff line number Diff line change
Expand Up @@ -4882,6 +4882,66 @@ static void stdout_plm_config(struct nvme_plm_config *plmcfg)
printf("\tDTWIN Time Threshold :%"PRIu64"\n", le64_to_cpu(plmcfg->dtwintt));
}

static void stdout_feat_perfc_std(struct nvme_std_perf_attr *data)
{
printf("random 4 kib average read latency (R4KARL): %s (0x%02x)\n",
nvme_feature_perfc_r4karl_to_string(data->r4karl), data->r4karl);
}

static void stdout_feat_perfc_id_list(struct nvme_perf_attr_id_list *data)
{
int i;
int attri_vs;

printf("attribute type (ATTRTYP): %s (0x%02x)\n",
nvme_feature_perfc_attrtyp_to_string(data->attrtyp), data->attrtyp);
printf("maximum saveable vendor specific performance attributes (MSVSPA): %d\n",
data->msvspa);
printf("unused saveable vendor specific performance attributes (USVSPA): %d\n",
data->usvspa);

printf("performance attribute identifier list\n");
for (i = 0; i < ARRAY_SIZE(data->id_list); i++) {
attri_vs = i + NVME_FEAT_PERFC_ATTRI_VS_MIN;
printf("performance attribute %02xh identifier (PA%02XHI): %s\n", attri_vs,
attri_vs, util_uuid_to_string(data->id_list[i].id));
}
}

static void stdout_feat_perfc_vs(struct nvme_vs_perf_attr *data)
{
printf("performance attribute identifier (PAID): %s\n", util_uuid_to_string(data->paid));
printf("attribute length (ATTRL): %u\n", data->attrl);
printf("vendor specific (VS):\n");
d((unsigned char *)data->vs, data->attrl, 16, 1);
}

static void stdout_feat_perfc(enum nvme_features_id fid, unsigned int result,
struct nvme_perf_characteristics *data)
{
__u8 attri;
bool rvspa;

nvme_feature_decode_perf_characteristics(result, &attri, &rvspa);

printf("attribute index (ATTRI): %s (0x%02x)\n", nvme_feature_perfc_attri_to_string(attri),
attri);

switch (attri) {
case NVME_FEAT_PERFC_ATTRI_STD:
stdout_feat_perfc_std(data->std_perf);
break;
case NVME_FEAT_PERFC_ATTRI_ID_LIST:
stdout_feat_perfc_id_list(data->id_list);
break;
case NVME_FEAT_PERFC_ATTRI_VS_MIN ... NVME_FEAT_PERFC_ATTRI_VS_MAX:
stdout_feat_perfc_vs(data->vs_perf);
break;
default:
break;
}
}

static void stdout_host_metadata(enum nvme_features_id fid,
struct nvme_host_metadata *data)
{
Expand Down Expand Up @@ -5111,6 +5171,9 @@ static void stdout_feature_show_fields(enum nvme_features_id fid,
printf("\tPower Loss Signaling Mode (PLSM): %s\n",
nvme_pls_mode_to_string(NVME_GET(result, FEAT_PLS_MODE)));
break;
case NVME_FEAT_FID_PERF_CHARACTERISTICS:
stdout_feat_perfc(fid, result, (struct nvme_perf_characteristics *)buf);
break;
case NVME_FEAT_FID_ENH_CTRL_METADATA:
case NVME_FEAT_FID_CTRL_METADATA:
case NVME_FEAT_FID_NS_METADATA:
Expand Down
90 changes: 90 additions & 0 deletions nvme-print.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,96 @@ const char *nvme_feature_temp_sel_to_string(__u8 sel)
}
}

const char *nvme_feature_perfc_attri_to_string(__u8 attri)
{
switch (attri) {
case NVME_FEAT_PERFC_ATTRI_STD:
return "standard performance attribute";
case NVME_FEAT_PERFC_ATTRI_ID_LIST:
return "performance attribute identifier list";
case NVME_FEAT_PERFC_ATTRI_VS_MIN ... NVME_FEAT_PERFC_ATTRI_VS_MAX:
return "vendor specific performance attribute";
default:
break;
}

return "reserved";
}

const char *nvme_feature_perfc_r4karl_to_string(__u8 r4karl)
{
switch (r4karl) {
case NVME_FEAT_PERFC_R4KARL_NO_REPORT:
return "not reported";
case NVME_FEAT_PERFC_R4KARL_GE_100_SEC:
return "greater than or equal to 100 seconds";
case NVME_FEAT_PERFC_R4KARL_GE_50_SEC:
return "greater than or equal to 50 seconds and less than 100 seconds";
case NVME_FEAT_PERFC_R4KARL_GE_10_SEC:
return "greater than or equal to 10 seconds and less than 50 seconds";
case NVME_FEAT_PERFC_R4KARL_GE_5_SEC:
return "greater than or equal to 5 seconds and less than 10 seconds";
case NVME_FEAT_PERFC_R4KARL_GE_1_SEC:
return "greater than or equal to 1 second and less than 5 seconds";
case NVME_FEAT_PERFC_R4KARL_GE_500_MS:
return "greater than or equal to 500 milliseconds and less than 1 second";
case NVME_FEAT_PERFC_R4KARL_GE_100_MS:
return "greater than or equal to 100 milliseconds and less than 500 milliseconds";
case NVME_FEAT_PERFC_R4KARL_GE_50_MS:
return "greater than or equal to 50 milliseconds and less than 100 milliseconds";
case NVME_FEAT_PERFC_R4KARL_GE_10_MS:
return "greater than or equal to 10 milliseconds and less than 50 milliseconds";
case NVME_FEAT_PERFC_R4KARL_GE_5_MS:
return "greater than or equal to 5 milliseconds and less than 10 milliseconds";
case NVME_FEAT_PERFC_R4KARL_GE_1_MS:
return "greater than or equal to 1 millisecond and less than 5 milliseconds";
case NVME_FEAT_PERFC_R4KARL_GE_500_US:
return "greater than or equal to 500 microseconds and less than 1 millisecond";
case NVME_FEAT_PERFC_R4KARL_GE_100_US:
return "greater than or equal to 100 microseconds and less than 500 microseconds";
case NVME_FEAT_PERFC_R4KARL_GE_50_US:
return "greater than or equal to 50 microseconds and less than 100 microseconds";
case NVME_FEAT_PERFC_R4KARL_GE_10_US:
return "greater than or equal to 10 microseconds and less than 50 microseconds";
case NVME_FEAT_PERFC_R4KARL_GE_5_US:
return "greater than or equal to 5 microseconds and less than 10 microseconds";
case NVME_FEAT_PERFC_R4KARL_GE_1_US:
return "greater than or equal to 1 microsecond and less than 5 microseconds";
case NVME_FEAT_PERFC_R4KARL_GE_500_NS:
return "greater than or equal to 500 nanoseconds and less than 1 microsecond";
case NVME_FEAT_PERFC_R4KARL_GE_100_NS:
return "greater than or equal to 100 nanoseconds and less than 500 nanoseconds";
case NVME_FEAT_PERFC_R4KARL_GE_50_NS:
return "greater than or equal to 50 nanoseconds and less than 100 nanoseconds";
case NVME_FEAT_PERFC_R4KARL_GE_10_NS:
return "greater than or equal to 10 nanoseconds and less than 50 nanoseconds";
case NVME_FEAT_PERFC_R4KARL_GE_5_NS:
return "greater than or equal to 5 nanoseconds and less than 10 nanoseconds";
case NVME_FEAT_PERFC_R4KARL_GE_1_NS:
return "greater than or equal to 1 nanosecond and less than 5 nanoseconds";
default:
break;
}

return "reserved";
}

const char *nvme_feature_perfc_attrtyp_to_string(__u8 attrtyp)
{
switch (attrtyp) {
case NVME_GET_FEATURES_SEL_CURRENT:
return "current attribute";
case NVME_GET_FEATURES_SEL_DEFAULT:
return "default attribute";
case NVME_GET_FEATURES_SEL_SAVED:
return "saved attribute";
default:
break;
}

return "reserved";
}

const char *nvme_ns_wp_cfg_to_string(enum nvme_ns_write_protect_cfg state)
{
switch (state) {
Expand Down
3 changes: 3 additions & 0 deletions nvme-print.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,9 @@ const char *nvme_feature_temp_sel_to_string(__u8 sel);
const char *nvme_feature_temp_type_to_string(__u8 type);
const char *nvme_feature_to_string(enum nvme_features_id feature);
const char *nvme_feature_wl_hints_to_string(__u8 wh);
const char *nvme_feature_perfc_attri_to_string(__u8 attri);
const char *nvme_feature_perfc_r4karl_to_string(__u8 r4karl);
const char *nvme_feature_perfc_attrtyp_to_string(__u8 attrtyp);
const char *nvme_host_metadata_type_to_string(enum nvme_features_id fid, __u8 type);
const char *nvme_log_to_string(__u8 lid);
const char *nvme_nss_hw_error_to_string(__u16 error_code);
Expand Down
15 changes: 15 additions & 0 deletions nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -4772,6 +4772,18 @@ static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result,
}
}

static bool is_get_feature_result_set(enum nvme_features_id feature_id)
{
switch (feature_id) {
case NVME_FEAT_FID_PERF_CHARACTERISTICS:
return false;
default:
break;
}

return true;
}

static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg,
nvme_print_flags_t flags)
{
Expand All @@ -4792,6 +4804,9 @@ static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg,
err_def = get_feature_id(dev, &cfg, &buf_def, &result_def);
}

if (!err && !is_get_feature_result_set(cfg.feature_id))
result = cfg.cdw11;

if (err || !cfg.changed || err_def || result != result_def ||
(buf && buf_def && !strcmp(buf, buf_def)))
get_feature_id_print(cfg, err, result, buf, flags);
Expand Down
Loading