Skip to content

Commit fab4bbc

Browse files
committed
feat: add power-thresh command
This is for Power Threshold feature to get and set. Signed-off-by: Tokunori Ikegami <[email protected]>
1 parent cb54012 commit fab4bbc

8 files changed

Lines changed: 181 additions & 0 deletions

File tree

libnvme/src/nvme/types.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,22 @@ enum nvme_psd_ps {
10981098
NVME_PSD_PS_10_MILLI_WATT = 2,
10991099
};
11001100

1101+
/**
1102+
* enum nvme_power_measurement_type - Power measurement types.
1103+
* @NVME_PMT_NSS_TOTAL_POWER: NVM subsystem total power
1104+
* @NVME_PMT_RSVD_MIN: Reserved minimum value
1105+
* @NVME_PMT_RSVD_MAX: Reserved maximum value
1106+
* @NVME_PMT_VS_MIN: Vendor Specific minimum value
1107+
* @NVME_PMT_VS_MAX: Vendor Specific maximum value
1108+
*/
1109+
enum nvme_power_measurement_type {
1110+
NVME_PMT_NSS_TOTAL_POWER = 0x0,
1111+
NVME_PMT_RSVD_MIN = 0x1,
1112+
NVME_PMT_RSVD_MAX = 0xb,
1113+
NVME_PMT_VS_MIN = 0xc,
1114+
NVME_PMT_VS_MAX = 0xf,
1115+
};
1116+
11011117
/**
11021118
* nvme_psd_power_scale() - power scale occupies the upper 3 bits
11031119
* @ps: power scale value
@@ -9032,6 +9048,14 @@ enum nvme_features_id {
90329048
* @NVME_FEAT_POWER_LIMIT_PLV_MASK:
90339049
* @NVME_FEAT_POWER_LIMIT_PLS_SHIFT:
90349050
* @NVME_FEAT_POWER_LIMIT_PLS_MASK:
9051+
* @NVME_FEAT_POWER_THRESH_PTV_SHIFT:
9052+
* @NVME_FEAT_POWER_THRESH_PTV_MASK:
9053+
* @NVME_FEAT_POWER_THRESH_PTS_SHIFT:
9054+
* @NVME_FEAT_POWER_THRESH_PTS_MASK:
9055+
* @NVME_FEAT_POWER_THRESH_PMTS_SHIFT:
9056+
* @NVME_FEAT_POWER_THRESH_PMTS_MASK:
9057+
* @NVME_FEAT_POWER_THRESH_EPT_SHIFT:
9058+
* @NVME_FEAT_POWER_THRESH_EPT_MASK:
90359059
**/
90369060
enum nvme_feat {
90379061
NVME_FEAT_ARBITRATION_BURST_SHIFT = 0,
@@ -9190,6 +9214,14 @@ enum nvme_feat {
91909214
NVME_FEAT_POWER_LIMIT_PLV_MASK = 0xffff,
91919215
NVME_FEAT_POWER_LIMIT_PLS_SHIFT = 16,
91929216
NVME_FEAT_POWER_LIMIT_PLS_MASK = 0x3,
9217+
NVME_FEAT_POWER_THRESH_PTV_SHIFT = 0,
9218+
NVME_FEAT_POWER_THRESH_PTV_MASK = 0xffff,
9219+
NVME_FEAT_POWER_THRESH_PTS_SHIFT = 16,
9220+
NVME_FEAT_POWER_THRESH_PTS_MASK = 0x3,
9221+
NVME_FEAT_POWER_THRESH_PMTS_SHIFT = 20,
9222+
NVME_FEAT_POWER_THRESH_PMTS_MASK = 0xf,
9223+
NVME_FEAT_POWER_THRESH_EPT_SHIFT = 31,
9224+
NVME_FEAT_POWER_THRESH_EPT_MASK = 0x1,
91939225
};
91949226

91959227
/**

libnvme/src/nvme/util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,11 @@ static inline void nvme_feature_decode_arbitration(__u32 value, __u8 *ab,
291291
#define NVME_FEAT_POWER_LIMIT_PLV(v) NVME_GET(v, FEAT_POWER_LIMIT_PLV)
292292
#define NVME_FEAT_POWER_LIMIT_PLS(v) NVME_GET(v, FEAT_POWER_LIMIT_PLS)
293293

294+
#define NVME_FEAT_POWER_THRESH_PTV(v) NVME_GET(v, FEAT_POWER_THRESH_PTV)
295+
#define NVME_FEAT_POWER_THRESH_PTS(v) NVME_GET(v, FEAT_POWER_THRESH_PTS)
296+
#define NVME_FEAT_POWER_THRESH_PMTS(v) NVME_GET(v, FEAT_POWER_THRESH_PMTS)
297+
#define NVME_FEAT_POWER_THRESH_EPT(v) NVME_GET(v, FEAT_POWER_THRESH_EPT)
298+
294299
static inline void nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps,
295300
__u8 *wh)
296301
{

nvme-print-json.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4042,6 +4042,31 @@ static void json_feature_show_fields_power_limit(struct json_object *r,
40424042
obj_add_str(r, "Power Limit", k);
40434043
}
40444044

4045+
static void json_feature_show_fields_power_thresh(struct json_object *r,
4046+
unsigned int result)
4047+
{
4048+
__u8 field = NVME_FEAT_POWER_THRESH_EPT(result);
4049+
4050+
_cleanup_free_ char *k = NULL;
4051+
4052+
obj_add_str(r, "Enable Power Threshold (EPT)",
4053+
field ? "Enabled" : "Disabled");
4054+
4055+
field = NVME_FEAT_POWER_THRESH_PMTS(result);
4056+
obj_add_str(r, "Power Measurement Type Select (PMTS)",
4057+
nvme_power_measurement_type_to_string(field));
4058+
4059+
field = NVME_FEAT_POWER_THRESH_PTS(result);
4060+
obj_add_str(r, "Power Threshold Scale (PTS)",
4061+
nvme_feature_power_limit_scale_to_string(field));
4062+
4063+
field = NVME_FEAT_POWER_THRESH_PTV(result);
4064+
obj_add_uint(r, "Power Threshold Value (PTV)", field);
4065+
4066+
k = get_power_and_scale(field, NVME_FEAT_POWER_THRESH_PTS(result));
4067+
obj_add_str(r, "Power Threshold", k);
4068+
}
4069+
40454070
static void json_feature_show(enum nvme_features_id fid, int sel, unsigned int result)
40464071
{
40474072
struct json_object *r;
@@ -4184,6 +4209,9 @@ static void json_feature_show_fields(enum nvme_features_id fid, unsigned int res
41844209
case NVME_FEAT_FID_POWER_LIMIT:
41854210
json_feature_show_fields_power_limit(r, result);
41864211
break;
4212+
case NVME_FEAT_FID_POWER_THRESH:
4213+
json_feature_show_fields_power_thresh(r, result);
4214+
break;
41874215
default:
41884216
break;
41894217
}

nvme-print-stdout.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5335,6 +5335,23 @@ static void stdout_feature_show_fields(enum nvme_features_id fid,
53355335
print_power_and_scale(NVME_FEAT_POWER_LIMIT_PLV(result), field);
53365336
printf("\n");
53375337
break;
5338+
case NVME_FEAT_FID_POWER_THRESH:
5339+
field = NVME_FEAT_POWER_THRESH_EPT(result);
5340+
printf("\tEnable Power Threshold (EPT): %u - %s\n",
5341+
field, field ? "Enabled" : "Disabled");
5342+
field = NVME_FEAT_POWER_THRESH_PMTS(result);
5343+
printf("\tPower Measurement Type Select (PMTS): %u - %s\n",
5344+
field, nvme_power_measurement_type_to_string(field));
5345+
field = NVME_FEAT_POWER_THRESH_PTS(result);
5346+
printf("\tPower Threshold Scale (PTS): %u - %s\n", field,
5347+
nvme_feature_power_limit_scale_to_string(field));
5348+
printf("\tPower Threshold Value (PTV): %u\n",
5349+
NVME_FEAT_POWER_THRESH_PTV(result));
5350+
printf("\tPower Threshold: ");
5351+
print_power_and_scale(NVME_FEAT_POWER_THRESH_PTV(result),
5352+
field);
5353+
printf("\n");
5354+
break;
53385355
default:
53395356
break;
53405357
}

nvme-print.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,20 @@ const char *nvme_feature_power_limit_scale_to_string(__u8 pls)
15111511
return "Reserved";
15121512
}
15131513

1514+
const char *nvme_power_measurement_type_to_string(__u8 pmt)
1515+
{
1516+
switch (pmt) {
1517+
case NVME_PMT_NSS_TOTAL_POWER:
1518+
return "NVM subsystem total power";
1519+
case NVME_PMT_VS_MIN ... NVME_PMT_VS_MAX:
1520+
return "Vendor Specific";
1521+
default:
1522+
break;
1523+
}
1524+
1525+
return "Reserved";
1526+
}
1527+
15141528
void nvme_feature_show(enum nvme_features_id fid, int sel, unsigned int result)
15151529
{
15161530
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
@@ -342,6 +342,7 @@ const char *nvme_time_scale_to_string(__u8 ts);
342342
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);
345+
const char *nvme_power_measurement_type_to_string(__u8 pmt);
345346

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

plugins/feat/feat-nvme.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ static const char *temp_thresh_feat = "temperature threshold feature";
4949
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";
52+
static const char *power_thresh_feat = "power threshold feature";
5253

5354
static int feat_get(struct nvme_transport_handle *hdl, const __u8 fid,
5455
__u32 cdw11, __u8 sel, __u8 uidx, const char *feat)
@@ -669,3 +670,84 @@ static int feat_power_limit(int argc, char **argv, struct command *acmd,
669670

670671
return err;
671672
}
673+
674+
static int power_thresh_set(struct nvme_transport_handle *hdl, const __u8 fid,
675+
__u8 ptv, __u8 pts, __u8 pmts, __u8 ept, __u8 uidx,
676+
bool sv)
677+
{
678+
__u32 cdw11 = NVME_SET(ptv, FEAT_POWER_THRESH_PTV) |
679+
NVME_SET(pmts, FEAT_POWER_THRESH_PMTS) |
680+
NVME_SET(pts, FEAT_POWER_THRESH_PTS) |
681+
NVME_SET(ept, FEAT_POWER_THRESH_EPT);
682+
__u64 result;
683+
int err;
684+
685+
err = nvme_set_features(hdl, 0, fid, sv, cdw11, 0, 0, uidx, 0, NULL, 0,
686+
&result);
687+
688+
nvme_show_init();
689+
690+
if (err > 0) {
691+
nvme_show_status(err);
692+
} else if (err < 0) {
693+
nvme_show_perror("Set %s", power_thresh_feat);
694+
} else {
695+
nvme_show_result("Set %s: 0x%04x (%s)", power_thresh_feat,
696+
cdw11, sv ? "Save" : "Not save");
697+
nvme_feature_show_fields(fid, cdw11, NULL);
698+
}
699+
700+
nvme_show_finish();
701+
702+
return err;
703+
}
704+
705+
static int feat_power_thresh(int argc, char **argv, struct command *acmd,
706+
struct plugin *plugin)
707+
{
708+
const char *ptv = "power threshold value";
709+
const char *pts = "power threshold scale";
710+
const char *pmts = "power measurement type select";
711+
const char *ept = "enable power threshold";
712+
const __u8 fid = NVME_FEAT_FID_POWER_THRESH;
713+
714+
_cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL;
715+
716+
_cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl =
717+
NULL;
718+
int err;
719+
720+
struct config {
721+
__u8 ptv;
722+
__u8 pts;
723+
__u8 pmts;
724+
__u8 ept;
725+
__u8 uidx;
726+
__u8 sel;
727+
};
728+
729+
struct config cfg = { 0 };
730+
731+
FEAT_ARGS(opts,
732+
OPT_BYTE("ptv", 'p', &cfg.ptv, ptv),
733+
OPT_BYTE("pts", 't', &cfg.pts, pts),
734+
OPT_BYTE("pmts", 'm', &cfg.pmts, pmts),
735+
OPT_BYTE("ept", 'e', &cfg.ept, ept),
736+
OPT_BYTE("uuid-index", 'u', &cfg.uidx, uuid_index));
737+
738+
err = parse_and_open(&ctx, &hdl, argc, argv, POWER_LIMIT_DESC, opts);
739+
if (err)
740+
return err;
741+
742+
if (argconfig_parse_seen(opts, "ptv") ||
743+
argconfig_parse_seen(opts, "pmts") ||
744+
argconfig_parse_seen(opts, "ept"))
745+
err = power_thresh_set(hdl, fid, cfg.ptv, cfg.pts, cfg.pmts,
746+
cfg.ept, cfg.uidx,
747+
argconfig_parse_seen(opts, "save"));
748+
else
749+
err = feat_get(hdl, fid, 0, cfg.sel, cfg.uidx,
750+
power_thresh_feat);
751+
752+
return err;
753+
}

plugins/feat/feat-nvme.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define ARBITRATION_DESC "Get and set arbitration feature"
1919
#define VOLATILE_WC_DESC "Get and set volatile write cache feature"
2020
#define POWER_LIMIT_DESC "Get and set power limit feature"
21+
#define POWER_THRESH_DESC "Get and set power threshold feature"
2122

2223
#define FEAT_ARGS(n, ...) \
2324
NVME_ARGS(n, ##__VA_ARGS__, OPT_FLAG("save", 's', NULL, save), \
@@ -33,6 +34,7 @@ PLUGIN(NAME("feat", "NVMe feature extensions", FEAT_PLUGIN_VERSION),
3334
ENTRY("arbitration", ARBITRATION_DESC, feat_arbitration)
3435
ENTRY("volatile-wc", VOLATILE_WC_DESC, feat_volatile_wc)
3536
ENTRY("power-limit", POWER_LIMIT_DESC, feat_power_limit)
37+
ENTRY("power-thresh", POWER_THRESH_DESC, feat_power_thresh)
3638
)
3739
);
3840
#endif /* !FEAT_NVME || CMD_HEADER_MULTI_READ */

0 commit comments

Comments
 (0)