Skip to content

Commit 935878c

Browse files
ikegami-tigaw
authored andcommitted
feat: add power-thresh command
This is for Power Threshold feature to get and set. Signed-off-by: Tokunori Ikegami <[email protected]>
1 parent b771608 commit 935878c

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
@@ -9063,6 +9079,14 @@ enum nvme_features_id {
90639079
* @NVME_FEAT_POWER_LIMIT_PLV_MASK:
90649080
* @NVME_FEAT_POWER_LIMIT_PLS_SHIFT:
90659081
* @NVME_FEAT_POWER_LIMIT_PLS_MASK:
9082+
* @NVME_FEAT_POWER_THRESH_PTV_SHIFT:
9083+
* @NVME_FEAT_POWER_THRESH_PTV_MASK:
9084+
* @NVME_FEAT_POWER_THRESH_PTS_SHIFT:
9085+
* @NVME_FEAT_POWER_THRESH_PTS_MASK:
9086+
* @NVME_FEAT_POWER_THRESH_PMTS_SHIFT:
9087+
* @NVME_FEAT_POWER_THRESH_PMTS_MASK:
9088+
* @NVME_FEAT_POWER_THRESH_EPT_SHIFT:
9089+
* @NVME_FEAT_POWER_THRESH_EPT_MASK:
90669090
**/
90679091
enum nvme_feat {
90689092
NVME_FEAT_ARBITRATION_BURST_SHIFT = 0,
@@ -9221,6 +9245,14 @@ enum nvme_feat {
92219245
NVME_FEAT_POWER_LIMIT_PLV_MASK = 0xffff,
92229246
NVME_FEAT_POWER_LIMIT_PLS_SHIFT = 16,
92239247
NVME_FEAT_POWER_LIMIT_PLS_MASK = 0x3,
9248+
NVME_FEAT_POWER_THRESH_PTV_SHIFT = 0,
9249+
NVME_FEAT_POWER_THRESH_PTV_MASK = 0xffff,
9250+
NVME_FEAT_POWER_THRESH_PTS_SHIFT = 16,
9251+
NVME_FEAT_POWER_THRESH_PTS_MASK = 0x3,
9252+
NVME_FEAT_POWER_THRESH_PMTS_SHIFT = 20,
9253+
NVME_FEAT_POWER_THRESH_PMTS_MASK = 0xf,
9254+
NVME_FEAT_POWER_THRESH_EPT_SHIFT = 31,
9255+
NVME_FEAT_POWER_THRESH_EPT_MASK = 0x1,
92249256
};
92259257

92269258
/**

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
@@ -4123,6 +4123,31 @@ static void json_feature_show_fields_power_limit(struct json_object *r,
41234123
obj_add_str(r, "Power Limit", k);
41244124
}
41254125

4126+
static void json_feature_show_fields_power_thresh(struct json_object *r,
4127+
unsigned int result)
4128+
{
4129+
__u8 field = NVME_FEAT_POWER_THRESH_EPT(result);
4130+
4131+
_cleanup_free_ char *k = NULL;
4132+
4133+
obj_add_str(r, "Enable Power Threshold (EPT)",
4134+
field ? "Enabled" : "Disabled");
4135+
4136+
field = NVME_FEAT_POWER_THRESH_PMTS(result);
4137+
obj_add_str(r, "Power Measurement Type Select (PMTS)",
4138+
nvme_power_measurement_type_to_string(field));
4139+
4140+
field = NVME_FEAT_POWER_THRESH_PTS(result);
4141+
obj_add_str(r, "Power Threshold Scale (PTS)",
4142+
nvme_feature_power_limit_scale_to_string(field));
4143+
4144+
field = NVME_FEAT_POWER_THRESH_PTV(result);
4145+
obj_add_uint(r, "Power Threshold Value (PTV)", field);
4146+
4147+
k = get_power_and_scale(field, NVME_FEAT_POWER_THRESH_PTS(result));
4148+
obj_add_str(r, "Power Threshold", k);
4149+
}
4150+
41264151
static void json_feature_show(enum nvme_features_id fid, int sel, unsigned int result)
41274152
{
41284153
struct json_object *r;
@@ -4265,6 +4290,9 @@ static void json_feature_show_fields(enum nvme_features_id fid, unsigned int res
42654290
case NVME_FEAT_FID_POWER_LIMIT:
42664291
json_feature_show_fields_power_limit(r, result);
42674292
break;
4293+
case NVME_FEAT_FID_POWER_THRESH:
4294+
json_feature_show_fields_power_thresh(r, result);
4295+
break;
42684296
default:
42694297
break;
42704298
}

nvme-print-stdout.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5397,6 +5397,23 @@ static void stdout_feature_show_fields(enum nvme_features_id fid,
53975397
print_power_and_scale(NVME_FEAT_POWER_LIMIT_PLV(result), field);
53985398
printf("\n");
53995399
break;
5400+
case NVME_FEAT_FID_POWER_THRESH:
5401+
field = NVME_FEAT_POWER_THRESH_EPT(result);
5402+
printf("\tEnable Power Threshold (EPT): %u - %s\n",
5403+
field, field ? "Enabled" : "Disabled");
5404+
field = NVME_FEAT_POWER_THRESH_PMTS(result);
5405+
printf("\tPower Measurement Type Select (PMTS): %u - %s\n",
5406+
field, nvme_power_measurement_type_to_string(field));
5407+
field = NVME_FEAT_POWER_THRESH_PTS(result);
5408+
printf("\tPower Threshold Scale (PTS): %u - %s\n", field,
5409+
nvme_feature_power_limit_scale_to_string(field));
5410+
printf("\tPower Threshold Value (PTV): %u\n",
5411+
NVME_FEAT_POWER_THRESH_PTV(result));
5412+
printf("\tPower Threshold: ");
5413+
print_power_and_scale(NVME_FEAT_POWER_THRESH_PTV(result),
5414+
field);
5415+
printf("\n");
5416+
break;
54005417
default:
54015418
break;
54025419
}

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)