Skip to content

Commit a333a9e

Browse files
jimmunnigaw
authored andcommitted
feat: Add power measurement feature support.
Added "power-meas" feature. Fixed bug in power threshold printing code. Signed-off-by: Jim Munn <[email protected]>
1 parent 32f4203 commit a333a9e

8 files changed

Lines changed: 164 additions & 8 deletions

File tree

libnvme/src/nvme/cmds.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,7 @@ int nvme_get_feature_length(int fid, __u32 cdw11, enum nvme_data_tfr dir,
563563
case NVME_FEAT_FID_RESV_PERSIST:
564564
case NVME_FEAT_FID_WRITE_PROTECT:
565565
case NVME_FEAT_FID_POWER_LIMIT:
566+
case NVME_FEAT_FID_POWER_MEASUREMENT:
566567
*len = 0;
567568
break;
568569
case NVME_FEAT_FID_ENH_CTRL_METADATA:

libnvme/src/nvme/types.h

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,16 @@ enum nvme_power_measurement_type {
10921092
NVME_PMT_VS_MAX = 0xf,
10931093
};
10941094

1095+
/**
1096+
* enum nvme_power_measurement_action - Power measurement actions.
1097+
* @NVME_PMA_STOP: Stop power measurement
1098+
* @NVME_PMA_START: Start power measurement
1099+
*/
1100+
enum nvme_power_measurement_action {
1101+
NVME_PMA_STOP = 0x0,
1102+
NVME_PMA_START = 0x1,
1103+
};
1104+
10951105
/**
10961106
* nvme_psd_power_scale() - power scale occupies the upper 3 bits
10971107
* @ps: power scale value
@@ -8835,7 +8845,7 @@ enum nvme_cmd_get_log_lid {
88358845
* @NVME_FEAT_FID_CONF_DEV_PERSONALITY: Configurable Device Personality
88368846
* @NVME_FEAT_FID_POWER_LIMIT: Power Limit
88378847
* @NVME_FEAT_FID_POWER_THRESH: Power Threshold
8838-
* @NVME_FEAT_FID_POEWR_MEASUREMENT: Power Measurement
8848+
* @NVME_FEAT_FID_POWER_MEASUREMENT: Power Measurement
88398849
* @NVME_FEAT_FID_EMB_MGMT_CTRL_ADDR: Embedded Management Controller Address
88408850
* @NVME_FEAT_FID_HOST_MGMT_AGENT_ADDR: Host Management Agent Address
88418851
* @NVME_FEAT_FID_ENH_CTRL_METADATA: Enhanced Controller Metadata
@@ -8885,7 +8895,7 @@ enum nvme_features_id {
88858895
NVME_FEAT_FID_CONF_DEV_PERSONALITY = 0x22,
88868896
NVME_FEAT_FID_POWER_LIMIT = 0x23,
88878897
NVME_FEAT_FID_POWER_THRESH = 0x24,
8888-
NVME_FEAT_FID_POEWR_MEASUREMENT = 0x25,
8898+
NVME_FEAT_FID_POWER_MEASUREMENT = 0x25,
88898899
NVME_FEAT_FID_EMB_MGMT_CTRL_ADDR = 0x78,
88908900
NVME_FEAT_FID_HOST_MGMT_AGENT_ADDR = 0x79,
88918901
NVME_FEAT_FID_ENH_CTRL_METADATA = 0x7d,
@@ -9065,6 +9075,12 @@ enum nvme_features_id {
90659075
* @NVME_FEAT_POWER_THRESH_PMTS_MASK:
90669076
* @NVME_FEAT_POWER_THRESH_EPT_SHIFT:
90679077
* @NVME_FEAT_POWER_THRESH_EPT_MASK:
9078+
* @NVME_FEAT_POWER_MEAS_ACT_SHIFT:
9079+
* @NVME_FEAT_POWER_MEAS_ACT_MASK:
9080+
* @NVME_FEAT_POWER_MEAS_PMTS_SHIFT:
9081+
* @NVME_FEAT_POWER_MEAS_PMTS_MASK:
9082+
* @NVME_FEAT_POWER_MEAS_SMT_SHIFT:
9083+
* @NVME_FEAT_POWER_MEAS_SMT_MASK:
90689084
**/
90699085
enum nvme_feat {
90709086
NVME_FEAT_ARBITRATION_BURST_SHIFT = 0,
@@ -9231,6 +9247,12 @@ enum nvme_feat {
92319247
NVME_FEAT_POWER_THRESH_PMTS_MASK = 0xf,
92329248
NVME_FEAT_POWER_THRESH_EPT_SHIFT = 31,
92339249
NVME_FEAT_POWER_THRESH_EPT_MASK = 0x1,
9250+
NVME_FEAT_POWER_MEAS_ACT_SHIFT = 0,
9251+
NVME_FEAT_POWER_MEAS_ACT_MASK = 0xf,
9252+
NVME_FEAT_POWER_MEAS_PMTS_SHIFT = 4,
9253+
NVME_FEAT_POWER_MEAS_PMTS_MASK = 0xf,
9254+
NVME_FEAT_POWER_MEAS_SMT_SHIFT = 16,
9255+
NVME_FEAT_POWER_MEAS_SMT_MASK = 0xffff,
92349256
};
92359257

92369258
/**
@@ -10514,6 +10536,10 @@ static inline void nvme_feature_decode_arbitration(__u32 value, __u8 *ab,
1051410536
#define NVME_FEAT_POWER_THRESH_PMTS(v) NVME_GET(v, FEAT_POWER_THRESH_PMTS)
1051510537
#define NVME_FEAT_POWER_THRESH_EPT(v) NVME_GET(v, FEAT_POWER_THRESH_EPT)
1051610538

10539+
#define NVME_FEAT_POWER_MEAS_ACT(v) NVME_GET(v, FEAT_POWER_MEAS_ACT)
10540+
#define NVME_FEAT_POWER_MEAS_PMTS(v) NVME_GET(v, FEAT_POWER_MEAS_PMTS)
10541+
#define NVME_FEAT_POWER_MEAS_SMT(v) NVME_GET(v, FEAT_POWER_MEAS_SMT)
10542+
1051710543
static inline void
1051810544
nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps, __u8 *wh)
1051910545
{

nvme-print-json.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4133,10 +4133,12 @@ static void json_feature_show_fields_power_limit(struct json_object *r,
41334133
static void json_feature_show_fields_power_thresh(struct json_object *r,
41344134
unsigned int result)
41354135
{
4136-
__u8 field = NVME_FEAT_POWER_THRESH_EPT(result);
4137-
4136+
__u8 field;
4137+
__u16 ptv;
41384138
_cleanup_free_ char *k = NULL;
41394139

4140+
field = NVME_FEAT_POWER_THRESH_EPT(result);
4141+
41404142
obj_add_str(r, "Enable Power Threshold (EPT)",
41414143
field ? "Enabled" : "Disabled");
41424144

@@ -4148,13 +4150,33 @@ static void json_feature_show_fields_power_thresh(struct json_object *r,
41484150
obj_add_str(r, "Power Threshold Scale (PTS)",
41494151
nvme_feature_power_limit_scale_to_string(field));
41504152

4151-
field = NVME_FEAT_POWER_THRESH_PTV(result);
4152-
obj_add_uint(r, "Power Threshold Value (PTV)", field);
4153+
ptv = NVME_FEAT_POWER_THRESH_PTV(result);
4154+
4155+
obj_add_uint(r, "Power Threshold Value (PTV)", ptv);
41534156

4154-
k = get_power_and_scale(field, NVME_FEAT_POWER_THRESH_PTS(result));
4157+
k = get_power_and_scale(ptv, NVME_FEAT_POWER_THRESH_PTS(result));
41554158
obj_add_str(r, "Power Threshold", k);
41564159
}
41574160

4161+
static void json_feature_show_fields_power_meas(struct json_object *r,
4162+
unsigned int result)
4163+
{
4164+
__u8 field;
4165+
__u16 smt;
4166+
4167+
field = NVME_FEAT_POWER_MEAS_ACT(result);
4168+
obj_add_str(r, "Action (ACT)",
4169+
nvme_power_measurement_action_to_string(field));
4170+
4171+
field = NVME_FEAT_POWER_MEAS_PMTS(result);
4172+
obj_add_str(r, "Power Measurement Type Select (PMTS)",
4173+
nvme_power_measurement_type_to_string(field));
4174+
4175+
smt = NVME_FEAT_POWER_MEAS_SMT(result);
4176+
4177+
obj_add_uint(r, "Stop Measurement Time (SMT)", smt);
4178+
}
4179+
41584180
static void json_feature_show(enum nvme_features_id fid, int sel, unsigned int result)
41594181
{
41604182
struct json_object *r;
@@ -4300,6 +4322,9 @@ static void json_feature_show_fields(enum nvme_features_id fid, unsigned int res
43004322
case NVME_FEAT_FID_POWER_THRESH:
43014323
json_feature_show_fields_power_thresh(r, result);
43024324
break;
4325+
case NVME_FEAT_FID_POWER_MEASUREMENT:
4326+
json_feature_show_fields_power_meas(r, result);
4327+
break;
43034328
default:
43044329
break;
43054330
}

nvme-print-stdout.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5427,6 +5427,16 @@ static void stdout_feature_show_fields(enum nvme_features_id fid,
54275427
field);
54285428
printf("\n");
54295429
break;
5430+
case NVME_FEAT_FID_POWER_MEASUREMENT:
5431+
field = NVME_FEAT_POWER_MEAS_ACT(result);
5432+
printf("\tAction (ACT): %u - %s\n", field,
5433+
nvme_power_measurement_action_to_string(field));
5434+
field = NVME_FEAT_POWER_MEAS_PMTS(result);
5435+
printf("\tPower Measurement Type Select (PMTS): %u - %s\n",
5436+
field, nvme_power_measurement_type_to_string(field));
5437+
printf("\tStop Measurement Time (SMT): %u\n",
5438+
NVME_FEAT_POWER_MEAS_SMT(result));
5439+
break;
54305440
default:
54315441
break;
54325442
}

nvme-print.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ const char *nvme_feature_to_string(enum nvme_features_id feature)
952952
case NVME_FEAT_FID_CONF_DEV_PERSONALITY:return "Configurable Device Personality";
953953
case NVME_FEAT_FID_POWER_LIMIT: return "Power Limit";
954954
case NVME_FEAT_FID_POWER_THRESH: return "Power Threshold";
955-
case NVME_FEAT_FID_POEWR_MEASUREMENT: return "Power Measurement";
955+
case NVME_FEAT_FID_POWER_MEASUREMENT: return "Power Measurement";
956956
case NVME_FEAT_FID_EMB_MGMT_CTRL_ADDR: return "Embedded Management Controller Address";
957957
case NVME_FEAT_FID_HOST_MGMT_AGENT_ADDR:return "Host Management Agent Address";
958958
case NVME_FEAT_FID_ENH_CTRL_METADATA: return "Enhanced Controller Metadata";
@@ -1526,6 +1526,21 @@ const char *nvme_power_measurement_type_to_string(__u8 pmt)
15261526
return "Reserved";
15271527
}
15281528

1529+
1530+
const char *nvme_power_measurement_action_to_string(__u8 act)
1531+
{
1532+
switch (act) {
1533+
case 0:
1534+
return "Stop";
1535+
case 1:
1536+
return "Start";
1537+
default:
1538+
break;
1539+
}
1540+
1541+
return "Reserved";
1542+
}
1543+
15291544
void nvme_feature_show(enum nvme_features_id fid, int sel, unsigned int result)
15301545
{
15311546
nvme_print(show_feature, NORMAL, fid, sel, result);

nvme-print.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ const char *nvme_pls_mode_to_string(__u8 mode);
343343
const char *nvme_bpwps_to_string(__u8 bpwps);
344344
const char *nvme_feature_power_limit_scale_to_string(__u8 pls);
345345
const char *nvme_power_measurement_type_to_string(__u8 pmt);
346+
const char *nvme_power_measurement_action_to_string(__u8 act);
346347

347348
void nvme_dev_full_path(nvme_ns_t n, char *path, size_t len);
348349
void nvme_generic_full_path(nvme_ns_t n, char *path, size_t len);

plugins/feat/feat-nvme.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static const char *arbitration_feat = "arbitration feature";
5050
static const char *volatile_wc_feat = "volatile write cache feature";
5151
static const char *power_limit_feat = "power limit feature";
5252
static const char *power_thresh_feat = "power threshold feature";
53+
static const char *power_meas_feat = "power measurement feature";
5354

5455
static int feat_get(struct nvme_transport_handle *hdl, const __u8 fid,
5556
__u32 cdw11, __u8 sel, __u8 uidx, const char *feat)
@@ -753,3 +754,78 @@ static int feat_power_thresh(int argc, char **argv, struct command *acmd,
753754

754755
return err;
755756
}
757+
758+
static int power_meas_set(struct nvme_transport_handle *hdl, const __u8 fid,
759+
__u8 action, __u8 pmts, __u16 smt, __u8 uidx, bool sv)
760+
{
761+
__u32 cdw11 = NVME_SET(action, FEAT_POWER_MEAS_ACT) |
762+
NVME_SET(pmts, FEAT_POWER_MEAS_PMTS) |
763+
NVME_SET(smt, FEAT_POWER_MEAS_SMT);
764+
__u64 result;
765+
int err;
766+
767+
err = nvme_set_features(hdl, 0, fid, sv, cdw11, 0, 0, uidx, 0, NULL, 0,
768+
&result);
769+
770+
nvme_show_init();
771+
772+
if (err > 0) {
773+
nvme_show_status(err);
774+
} else if (err < 0) {
775+
nvme_show_perror("Set %s", power_meas_feat);
776+
} else {
777+
nvme_show_result("Set %s: 0x%04x (%s)", power_meas_feat, cdw11,
778+
sv ? "Save" : "Not save");
779+
nvme_feature_show_fields(fid, cdw11, NULL);
780+
}
781+
782+
nvme_show_finish();
783+
784+
return err;
785+
}
786+
787+
static int feat_power_meas(int argc, char **argv, struct command *cmd,
788+
struct plugin *plugin)
789+
{
790+
const char *action = "action [0-1]: stop|start";
791+
const char *pmts = "power measurement type select";
792+
const char *smt = "stop measurement time";
793+
const __u8 fid = NVME_FEAT_FID_POWER_MEASUREMENT;
794+
795+
_cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL;
796+
797+
_cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl =
798+
NULL;
799+
int err;
800+
801+
struct config {
802+
__u8 act;
803+
__u8 pmts;
804+
__u16 smt;
805+
__u8 uidx;
806+
__u8 sel;
807+
};
808+
809+
struct config cfg = { 0 };
810+
811+
FEAT_ARGS(opts,
812+
OPT_BYTE("act", 0, &cfg.act, action),
813+
OPT_BYTE("pmts", 0, &cfg.pmts, pmts),
814+
OPT_SHRT("smt", 0, &cfg.smt, smt),
815+
OPT_BYTE("uuid-index", 'u', &cfg.uidx, uuid_index));
816+
817+
err = parse_and_open(&ctx, &hdl, argc, argv, POWER_MEAS_DESC, opts);
818+
if (err)
819+
return err;
820+
821+
if (argconfig_parse_seen(opts, "act") ||
822+
argconfig_parse_seen(opts, "pmts") ||
823+
argconfig_parse_seen(opts, "smt"))
824+
err = power_meas_set(hdl, fid, cfg.act, cfg.pmts, cfg.smt,
825+
cfg.uidx,
826+
argconfig_parse_seen(opts, "save"));
827+
else
828+
err = feat_get(hdl, fid, 0, cfg.sel, 0, power_meas_feat);
829+
830+
return err;
831+
}

plugins/feat/feat-nvme.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define VOLATILE_WC_DESC "Get and set volatile write cache feature"
2020
#define POWER_LIMIT_DESC "Get and set power limit feature"
2121
#define POWER_THRESH_DESC "Get and set power threshold feature"
22+
#define POWER_MEAS_DESC "Get and set power measurement feature"
2223

2324
#define FEAT_ARGS(n, ...) \
2425
NVME_ARGS(n, ##__VA_ARGS__, OPT_FLAG("save", 's', NULL, save), \
@@ -35,6 +36,7 @@ PLUGIN(NAME("feat", "NVMe feature extensions", FEAT_PLUGIN_VERSION),
3536
ENTRY("volatile-wc", VOLATILE_WC_DESC, feat_volatile_wc)
3637
ENTRY("power-limit", POWER_LIMIT_DESC, feat_power_limit)
3738
ENTRY("power-thresh", POWER_THRESH_DESC, feat_power_thresh)
39+
ENTRY("power-meas", POWER_MEAS_DESC, feat_power_meas)
3840
)
3941
);
4042
#endif /* !FEAT_NVME || CMD_HEADER_MULTI_READ */

0 commit comments

Comments
 (0)