Skip to content

Commit 93ca890

Browse files
committed
nvme-print-stdout: add performance characteristics feature output
The feature identifier 1Ch added by NVMe 2.1. Signed-off-by: Tokunori Ikegami <[email protected]>
1 parent 71fa5d9 commit 93ca890

4 files changed

Lines changed: 164 additions & 10 deletions

File tree

nvme-print-stdout.c

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ static void nvme_resources_free(struct nvme_resources *res)
162162
htable_subsys_clear(&res->ht_s);
163163
}
164164

165-
static void stdout_feature_show_fields(enum nvme_features_id fid,
166-
unsigned int result,
165+
static void stdout_feature_show_fields(enum nvme_features_id fid, __u32 cdw11, unsigned int result,
167166
unsigned char *buf);
168167
static void stdout_smart_log(struct nvme_smart_log *smart, unsigned int nsid, const char *devname);
169168

@@ -463,7 +462,7 @@ static void pel_set_feature_event(void *pevent_log_info, __u32 offset)
463462
cdw12 = le32_to_cpu(set_feat_event->cdw_mem[2]);
464463
stdout_persistent_event_log_fdp_events(cdw11, cdw12, mem_buf);
465464
} else {
466-
stdout_feature_show_fields(fid, cdw11, mem_buf);
465+
stdout_feature_show_fields(fid, cdw11, cdw11, mem_buf);
467466
}
468467
}
469468

@@ -4864,6 +4863,64 @@ static void stdout_plm_config(struct nvme_plm_config *plmcfg)
48644863
printf("\tDTWIN Time Threshold :%"PRIu64"\n", le64_to_cpu(plmcfg->dtwintt));
48654864
}
48664865

4866+
static void stdout_perfc_std_attr(struct nvme_std_perf_attr *std_perf)
4867+
{
4868+
printf("\tRandom 4 KiB average read latency (R4KARL): %s\n",
4869+
nvme_perf_lat_to_string(std_perf->r4karl));
4870+
}
4871+
4872+
static void stdout_perfc_attr_id_list(struct nvme_perf_attr_id_list *id_list)
4873+
{
4874+
int i;
4875+
4876+
printf("\tAttribute Type (ATTRTYP): %s\n",
4877+
nvme_perf_attr_type_to_string(NVME_GET(id_list->attrtyp, FEAT_PERFC_ATTRTYP)));
4878+
printf("\tMaximum Saveable Vendor Specific Performance Attributes (MSVSPA): %u\n",
4879+
id_list->msvspa);
4880+
printf("\tUnused Saveable Vendor Specific Performance Attributes (USVSPA): %u\n",
4881+
id_list->usvspa);
4882+
for (i = 0; i < ARRAY_SIZE(id_list->id_list); i++)
4883+
printf("\tPerformance Attribute %Xh Identifier (PA%XHI): %s\n", i, i,
4884+
util_uuid_to_string(id_list->id_list[i].id));
4885+
}
4886+
4887+
static void stdout_perfc_vs_attr(struct nvme_vs_perf_attr *vs_perf)
4888+
{
4889+
printf("\tPerformance Attribute Identifier (PAID): %s\n",
4890+
memcmp(vs_perf->paid.id, zero_uuid, sizeof(zero_uuid)) ?
4891+
util_uuid_to_string(vs_perf->paid.id) : "Unused");
4892+
printf("\tAttribute Length (ATTRL): %u\n", le16_to_cpu(vs_perf->attrl));
4893+
printf("\tVendor Specific (VS)\n");
4894+
d((unsigned char *)vs_perf->vs, le16_to_cpu(vs_perf->attrl), 16, 1);
4895+
}
4896+
4897+
static void stdout_perf_characteristics(__u32 cdw11, unsigned char *buf)
4898+
{
4899+
struct nvme_perf_characteristics *attr = (struct nvme_perf_characteristics *)buf;
4900+
__u8 attri;
4901+
bool rvspa;
4902+
4903+
nvme_feature_decode_perf_characteristics(cdw11, &attri, &rvspa);
4904+
4905+
printf("\tAttribute Index (ATTRI): %s\n", nvme_attr_index_to_string(attri));
4906+
printf("\tRevert Vendor Specific Performance Attribute (RVSPA): %s\n",
4907+
rvspa ? "Deleted" : "Not deleted");
4908+
4909+
switch (attri) {
4910+
case 0:
4911+
stdout_perfc_std_attr(attr->std_perf);
4912+
break;
4913+
case 0xc0:
4914+
stdout_perfc_attr_id_list(attr->id_list);
4915+
break;
4916+
case 0xc1 ... 0xff:
4917+
stdout_perfc_vs_attr(attr->vs_perf);
4918+
break;
4919+
default:
4920+
break;
4921+
}
4922+
}
4923+
48674924
static void stdout_host_metadata(enum nvme_features_id fid,
48684925
struct nvme_host_metadata *data)
48694926
{
@@ -4894,8 +4951,7 @@ static void stdout_feature_show(enum nvme_features_id fid, int sel, unsigned int
48944951
nvme_feature_to_string(fid), nvme_select_to_string(sel), result ? 10 : 8, result);
48954952
}
48964953

4897-
static void stdout_feature_show_fields(enum nvme_features_id fid,
4898-
unsigned int result,
4954+
static void stdout_feature_show_fields(enum nvme_features_id fid, __u32 cdw11, unsigned int result,
48994955
unsigned char *buf)
49004956
{
49014957
const char *async = "Send async event";
@@ -5093,6 +5149,9 @@ static void stdout_feature_show_fields(enum nvme_features_id fid,
50935149
printf("\tPower Loss Signaling Mode (PLSM): %s\n",
50945150
nvme_pls_mode_to_string(NVME_GET(result, FEAT_PLS_MODE)));
50955151
break;
5152+
case NVME_FEAT_FID_PERF_CHARACTERISTICS:
5153+
if (buf)
5154+
stdout_perf_characteristics(cdw11, buf);
50965155
case NVME_FEAT_FID_ENH_CTRL_METADATA:
50975156
case NVME_FEAT_FID_CTRL_METADATA:
50985157
case NVME_FEAT_FID_NS_METADATA:

nvme-print.c

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,14 +1364,105 @@ const char *nvme_pls_mode_to_string(__u8 mode)
13641364
return "Reserved";
13651365
}
13661366

1367+
const char *nvme_attr_index_to_string(__u8 index)
1368+
{
1369+
switch (index) {
1370+
case 0:
1371+
return "Standard Performance Attribute 00h";
1372+
case 0xc0:
1373+
return "Performance Attribute Identifier List";
1374+
case 0xc1 ... 0xff:
1375+
return "Vendor Specific Performance Attribute";
1376+
default:
1377+
break;
1378+
}
1379+
1380+
return "Reserved";
1381+
}
1382+
1383+
const char *nvme_perf_lat_to_string(__u8 lat)
1384+
{
1385+
switch (lat) {
1386+
case 0:
1387+
return "Not Reported";
1388+
case 1:
1389+
return "Greater than or equal to 100 seconds";
1390+
case 2:
1391+
return "Greater than or equal to 50 seconds and less than 100 seconds";
1392+
case 3:
1393+
return "Greater than or equal to 10 seconds and less than 50 seconds";
1394+
case 4:
1395+
return "Greater than or equal to 5 seconds and less than 10 seconds";
1396+
case 5:
1397+
return "Greater than or equal to 1 second and less than 5 seconds";
1398+
case 6:
1399+
return "Greater than or equal to 500 milliseconds and less than 1 second";
1400+
case 7:
1401+
return "Greater than or equal to 100 milliseconds and less than 500 milliseconds";
1402+
case 8:
1403+
return "Greater than or equal to 50 milliseconds and less than 100 milliseconds";
1404+
case 9:
1405+
return "Greater than or equal to 10 milliseconds and less than 50 milliseconds";
1406+
case 0xa:
1407+
return "Greater than or equal to 5 milliseconds and less than 10 milliseconds";
1408+
case 0xb:
1409+
return "Greater than or equal to 1 millisecond and less than 5 milliseconds";
1410+
case 0xc:
1411+
return "Greater than or equal to 500 microseconds and less than 1 millisecond";
1412+
case 0xd:
1413+
return "Greater than or equal to 100 microseconds and less than 500 microseconds";
1414+
case 0xe:
1415+
return "Greater than or equal to 50 microseconds and less than 100 microseconds";
1416+
case 0xf:
1417+
return "Greater than or equal to 10 microseconds and less than 50 microseconds";
1418+
case 0x10:
1419+
return "Greater than or equal to 5 microseconds and less than 10 microseconds";
1420+
case 0x11:
1421+
return "Greater than or equal to 1 microsecond and less than 5 microseconds";
1422+
case 0x12:
1423+
return "Greater than or equal to 500 nanoseconds and less than 1 microsecond";
1424+
case 0x13:
1425+
return "Greater than or equal to 100 nanoseconds and less than 500 nanoseconds";
1426+
case 0x14:
1427+
return "Greater than or equal to 50 nanoseconds and less than 100 nanoseconds";
1428+
case 0x15:
1429+
return "Greater than or equal to 10 nanoseconds and less than 50 nanoseconds";
1430+
case 0x16:
1431+
return "Greater than or equal to 5 nanoseconds and less than 10 nanoseconds";
1432+
case 0x17:
1433+
return "Greater than or equal to 1 nanosecond and less than 5 nanoseconds";
1434+
default:
1435+
break;
1436+
}
1437+
1438+
return "Reserved";
1439+
}
1440+
1441+
const char *nvme_perf_attr_type_to_string(__u8 type)
1442+
{
1443+
switch (type) {
1444+
case 0:
1445+
return "Current attribute";
1446+
case 1:
1447+
return "Default attribute";
1448+
case 2:
1449+
return "Saved attribute";
1450+
default:
1451+
break;
1452+
}
1453+
1454+
return "Reserved";
1455+
}
1456+
13671457
void nvme_feature_show(enum nvme_features_id fid, int sel, unsigned int result)
13681458
{
13691459
nvme_print(show_feature, NORMAL, fid, sel, result);
13701460
}
13711461

1372-
void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, unsigned char *buf)
1462+
void nvme_feature_show_fields(enum nvme_features_id fid, __u32 cdw11, unsigned int result,
1463+
unsigned char *buf)
13731464
{
1374-
nvme_print(show_feature_fields, NORMAL, fid, result, buf);
1465+
nvme_print(show_feature_fields, NORMAL, fid, cdw11, result, buf);
13751466
}
13761467

13771468
void nvme_show_lba_status(struct nvme_lba_status *list, unsigned long len,

nvme-print.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ struct print_ops {
8181
void (*zns_id_ns)(struct nvme_zns_id_ns *ns, struct nvme_id_ns *id_ns);
8282
void (*zns_report_zones)(void *report, __u32 descs, __u8 ext_size, __u32 report_size, struct json_object *zone_list);
8383
void (*show_feature)(enum nvme_features_id fid, int sel, unsigned int result);
84-
void (*show_feature_fields)(enum nvme_features_id fid, unsigned int result, unsigned char *buf);
84+
void (*show_feature_fields)(enum nvme_features_id fid, __u32 cdw11, unsigned int result, unsigned char *buf);
8585
void (*id_ctrl_rpmbs)(__le32 ctrl_rpmbs);
8686
void (*lba_range)(struct nvme_lba_range_type *lbrt, int nr_ranges);
8787
void (*lba_status_info)(__u32 result);
@@ -249,7 +249,8 @@ void nvme_show_topology(nvme_root_t t,
249249
nvme_print_flags_t flags);
250250

251251
void nvme_feature_show(enum nvme_features_id fid, int sel, unsigned int result);
252-
void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, unsigned char *buf);
252+
void nvme_feature_show_fields(enum nvme_features_id fid, __u32 cdw11, unsigned int result,
253+
unsigned char *buf);
253254
void nvme_directive_show(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u32 result,
254255
void *buf, __u32 len, nvme_print_flags_t flags);
255256
void nvme_show_select_result(enum nvme_features_id fid, __u32 result);
@@ -322,6 +323,9 @@ const char *nvme_pel_ehai_pit_to_string(enum nvme_pel_ehai_pit pit);
322323
const char *nvme_ssi_state_to_string(__u8 state);
323324
const char *nvme_time_scale_to_string(__u8 ts);
324325
const char *nvme_pls_mode_to_string(__u8 mode);
326+
const char *nvme_attr_index_to_string(__u8 index);
327+
const char *nvme_perf_lat_to_string(__u8 lat);
328+
const char *nvme_perf_attr_type_to_string(__u8 type);
325329

326330
void nvme_dev_full_path(nvme_ns_t n, char *path, size_t len);
327331
void nvme_generic_full_path(nvme_ns_t n, char *path, size_t len);

nvme.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4749,7 +4749,7 @@ static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result,
47494749
if (NVME_CHECK(cfg.sel, GET_FEATURES_SEL, SUPPORTED))
47504750
nvme_show_select_result(cfg.feature_id, result);
47514751
else if (verbose || !strcmp(nvme_cfg.output_format, "json"))
4752-
nvme_feature_show_fields(cfg.feature_id, result, buf);
4752+
nvme_feature_show_fields(cfg.feature_id, cfg.cdw11, result, buf);
47534753
else if (buf)
47544754
d(buf, cfg.data_len, 16, 1);
47554755
} else if (buf) {

0 commit comments

Comments
 (0)