From 0fe9d30da21dfb03fbbca9fa3099e8433c7b58c4 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sat, 3 May 2025 02:38:05 +0900 Subject: [PATCH 1/2] feat: add temp-thresh command For temperature threshold feature to get and set temperature values. Signed-off-by: Tokunori Ikegami --- plugins/feat/feat-nvme.c | 87 ++++++++++++++++++++++++++++++++++++++++ plugins/feat/feat-nvme.h | 2 + 2 files changed, 89 insertions(+) diff --git a/plugins/feat/feat-nvme.c b/plugins/feat/feat-nvme.c index 5c36897c5f..496dd29082 100644 --- a/plugins/feat/feat-nvme.c +++ b/plugins/feat/feat-nvme.c @@ -23,6 +23,15 @@ struct perfc_config { __u8 sel; }; +struct temp_thresh_config { + __u16 tmpth; + __u8 tmpsel; + __u8 thsel; + __u8 tmpthh; + bool save; + __u8 sel; +}; + static const char *power_mgmt_feat = "power management feature"; static const char *sel = "[0-3]: current/default/saved/supported"; static const char *save = "Specifies that the controller shall save the attribute"; @@ -381,3 +390,81 @@ static int feat_timestamp(int argc, char **argv, struct command *cmd, struct plu return err; } + +static int temp_thresh_set(int fd, const __u8 fid, struct argconfig_commandline_options *opts, + struct temp_thresh_config *cfg) +{ + __u32 result; + int err; + enum nvme_get_features_sel sel = NVME_GET_FEATURES_SEL_CURRENT; + __u16 tmpth; + __u8 tmpsel; + __u8 thsel; + __u8 tmpthh; + bool save = argconfig_parse_seen(opts, "save"); + + if (save) + sel = NVME_GET_FEATURES_SEL_SAVED; + + err = nvme_get_features_temp_thresh2(fd, sel, cfg->tmpsel, cfg->thsel, &result); + if (!err) { + nvme_feature_decode_temp_threshold(result, &tmpth, &tmpsel, &thsel, &tmpthh); + if (!argconfig_parse_seen(opts, "tmpth")) + cfg->tmpth = tmpth; + if (!argconfig_parse_seen(opts, "tmpthh")) + cfg->tmpthh = tmpthh; + } + + err = nvme_set_features_temp_thresh2(fd, cfg->tmpth, cfg->tmpsel, cfg->thsel, cfg->tmpthh, + save, &result); + + nvme_show_init(); + + if (err > 0) { + nvme_show_status(err); + } else if (err < 0) { + nvme_show_perror("Set %s", timestamp_feat); + } else { + nvme_show_result("Set %s: (%s)", timestamp_feat, save ? "Save" : "Not save"); + nvme_feature_show_fields(fid, NVME_SET(cfg->tmpth, FEAT_TT_TMPTH) | + NVME_SET(cfg->tmpsel, FEAT_TT_TMPSEL) | + NVME_SET(cfg->thsel, FEAT_TT_THSEL) | + NVME_SET(cfg->tmpthh, FEAT_TT_TMPTHH), NULL); + } + + nvme_show_finish(); + + return err; +} + +static int feat_temp_thresh(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const __u8 fid = NVME_FEAT_FID_TEMP_THRESH; + const char *tmpth = "temperature threshold"; + const char *tmpsel = "threshold temperature select"; + const char *thsel = "threshold type select"; + const char *tmpthh = "temperature threshold hysteresis"; + + _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + int err; + + struct temp_thresh_config cfg = { 0 }; + + FEAT_ARGS(opts, + OPT_SHRT("tmpth", 'T', &cfg.tmpth, tmpth), + OPT_BYTE("tmpsel", 'm', &cfg.tmpsel, tmpsel), + OPT_BYTE("thsel", 'H', &cfg.thsel, thsel), + OPT_BYTE("tmpthh", 'M', &cfg.tmpthh, tmpthh)); + + err = parse_and_open(&dev, argc, argv, TEMP_THRESH_DESC, opts); + if (err) + return err; + + if (argconfig_parse_seen(opts, "tmpth") || argconfig_parse_seen(opts, "tmpthh")) + err = temp_thresh_set(dev_fd(dev), fid, opts, &cfg); + else + err = feat_get(dev, fid, NVME_SET(cfg.tmpsel, FEAT_TT_TMPSEL) | + NVME_SET(cfg.thsel, FEAT_TT_THSEL), cfg.sel, timestamp_feat); + + return err; +} diff --git a/plugins/feat/feat-nvme.h b/plugins/feat/feat-nvme.h index ca1709e40e..1e727d31dd 100644 --- a/plugins/feat/feat-nvme.h +++ b/plugins/feat/feat-nvme.h @@ -14,6 +14,7 @@ #define PERFC_DESC "Get and set perf characteristics feature" #define HCTM_DESC "Get and set host controlled thermal management feature" #define TIMESTAMP_DESC "Get and set timestamp feature" +#define TEMP_THRESH_DESC "Get and set temperature threshold feature" #define FEAT_ARGS(n, ...) \ NVME_ARGS(n, ##__VA_ARGS__, OPT_FLAG("save", 's', NULL, save), \ @@ -25,6 +26,7 @@ PLUGIN(NAME("feat", "NVMe feature extensions", FEAT_PLUGIN_VERSION), ENTRY("perf-characteristics", PERFC_DESC, feat_perfc) ENTRY("hctm", HCTM_DESC, feat_hctm) ENTRY("timestamp", TIMESTAMP_DESC, feat_timestamp) + ENTRY("temp-thresh", TEMP_THRESH_DESC, feat_temp_thresh) ) ); #endif /* !FEAT_NVME || CMD_HEADER_MULTI_READ */ From ac0adbe6bd6429e5bb9eeeeeff087b753708917a Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sun, 4 May 2025 17:10:54 +0900 Subject: [PATCH 2/2] feat: fix to set perfc feature save argument correctly Previously incorrect save string poiner set to the argument. Signed-off-by: Tokunori Ikegami --- plugins/feat/feat-nvme.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/feat/feat-nvme.c b/plugins/feat/feat-nvme.c index 496dd29082..37d88458b6 100644 --- a/plugins/feat/feat-nvme.c +++ b/plugins/feat/feat-nvme.c @@ -28,7 +28,6 @@ struct temp_thresh_config { __u8 tmpsel; __u8 thsel; __u8 tmpthh; - bool save; __u8 sel; }; @@ -150,7 +149,8 @@ static int feat_power_mgmt(int argc, char **argv, struct command *cmd, struct pl return err; } -static int perfc_set(struct nvme_dev *dev, __u8 fid, __u32 cdw11, struct perfc_config *cfg) +static int perfc_set(struct nvme_dev *dev, __u8 fid, __u32 cdw11, struct perfc_config *cfg, + bool save) { __u32 result; int err; @@ -252,7 +252,7 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin if (argconfig_parse_seen(opts, "rvspa") || argconfig_parse_seen(opts, "r4karl") || argconfig_parse_seen(opts, "paid")) - err = perfc_set(dev, fid, cdw11, &cfg); + err = perfc_set(dev, fid, cdw11, &cfg, argconfig_parse_seen(opts, "save")); else err = feat_get(dev, fid, cdw11, cfg.sel, perfc_feat);