]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
Add support for decoding IO Determinism features
authorKeith Busch <keith.busch@gmail.com>
Sun, 4 Feb 2018 00:12:06 +0000 (17:12 -0700)
committerKeith Busch <keith.busch@gmail.com>
Sun, 18 Feb 2018 17:40:56 +0000 (10:40 -0700)
This patch adds support for setting and getting the IO determinisitic
windows and configuration, as defined by TP4003.

Signed-off-by: Keith Busch <keith.busch@gmail.com>
linux/nvme.h
memblaze-nvme.c
nvme-ioctl.c
nvme-ioctl.h
nvme-print.c
nvme.c

index 228391e93dddf6c1e5b96b32ca478f9fcfcc86bc..127d63678bb7df334598753c43df853ae1067d08 100644 (file)
@@ -491,6 +491,15 @@ enum {
        NVME_LBART_ATTRIB_HIDE  = 1 << 1,
 };
 
+struct nvme_plm_config {
+       __u16   enable_event;
+       __u8    rsvd2[30];
+       __u64   dtwin_reads_thresh;
+       __u64   dtwin_writes_thresh;
+       __u64   dtwin_time_thresh;
+       __u8    rsvd56[456];
+};
+
 struct nvme_reservation_status {
        __le32  gen;
        __u8    rtype;
@@ -792,6 +801,8 @@ enum {
        NVME_FEAT_HOST_MEM_BUF  = 0x0d,
        NVME_FEAT_TIMESTAMP     = 0x0e,
        NVME_FEAT_KATO          = 0x0f,
+       NVME_FEAT_PLM_CONFIG    = 0x13,
+       NVME_FEAT_PLM_WINDOW    = 0x14,
        NVME_FEAT_SW_PROGRESS   = 0x80,
        NVME_FEAT_HOST_ID       = 0x81,
        NVME_FEAT_RESV_MASK     = 0x82,
index 259022e2797a0e93f01aa2558f45f36ee9eadafe..a5a74d38484c64a22ebd3f3d6b9f0c06fcbd173d 100644 (file)
@@ -426,8 +426,8 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
                }
        }
 
-       err = nvme_set_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.value, cfg.save,
-                               cfg.data_len, buf, &result);
+       err = nvme_set_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.value,
+                               0, cfg.save, cfg.data_len, buf, &result);
        if (err < 0) {
                perror("set-feature");
                goto free;
index a6e1e01a505ac90ffc9804b4c6ef2eca54cabe5c..770ff8c15229bb8964060eec1e25fb814f7c4208 100644 (file)
@@ -459,13 +459,14 @@ int nvme_sanitize_log(int fd, struct nvme_sanitize_log_page *sanitize_log)
 }
 
 int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10, __u32 cdw11,
-                __u32 data_len, void *data, __u32 *result)
+                __u32 cdw12, __u32 data_len, void *data, __u32 *result)
 {
        struct nvme_admin_cmd cmd = {
                .opcode         = opcode,
                .nsid           = nsid,
                .cdw10          = cdw10,
                .cdw11          = cdw11,
+               .cdw11          = cdw12,
                .addr           = (__u64)(uintptr_t) data,
                .data_len       = data_len,
        };
@@ -477,13 +478,13 @@ int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10, __u32 cdw11,
        return err;
 }
 
-int nvme_set_feature(int fd, __u32 nsid, __u8 fid, __u32 value, bool save,
-                    __u32 data_len, void *data, __u32 *result)
+int nvme_set_feature(int fd, __u32 nsid, __u8 fid, __u32 value, __u32 cdw12,
+                    bool save, __u32 data_len, void *data, __u32 *result)
 {
        __u32 cdw10 = fid | (save ? 1 << 31 : 0);
 
        return nvme_feature(fd, nvme_admin_set_features, nsid, cdw10, value,
-                           data_len, data, result);
+                           cdw12, data_len, data, result);
 }
 
 int nvme_property(int fd, __u8 fctype, __le32 off, __le64 *value, __u8 attrib)
@@ -591,7 +592,7 @@ int nvme_get_feature(int fd, __u32 nsid, __u8 fid, __u8 sel, __u32 cdw11,
        __u32 cdw10 = fid | sel << 8;
 
        return nvme_feature(fd, nvme_admin_get_features, nsid, cdw10, cdw11,
-                           data_len, data, result);
+                           0, data_len, data, result);
 }
 
 int nvme_format(int fd, __u32 nsid, __u8 lbaf, __u8 ses, __u8 pi,
index f5b287b0e815c0dac323390c590cdfd4dbcc57df..69a303b2744baa68832f792c981961ee547b3446 100644 (file)
@@ -93,8 +93,9 @@ int nvme_discovery_log(int fd, struct nvmf_disc_rsp_page_hdr *log, __u32 size);
 int nvme_sanitize_log(int fd, struct nvme_sanitize_log_page *sanitize_log);
 
 int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10,
-                __u32 cdw11, __u32 data_len, void *data, __u32 *result);
-int nvme_set_feature(int fd, __u32 nsid, __u8 fid, __u32 value,
+                __u32 cdw11, __u32 cdw12, __u32 data_len, void *data,
+                __u32 *result);
+int nvme_set_feature(int fd, __u32 nsid, __u8 fid, __u32 value, __u32 cdw12,
                     bool save, __u32 data_len, void *data, __u32 *result);
 int nvme_get_feature(int fd, __u32 nsid, __u8 fid, __u8 sel,
                     __u32 cdw11, __u32 data_len, void *data, __u32 *result);
index 7527f36de196b21477d0e6f767b4e8de5edcaaf9..e729a3c967d2c7421bc8c567232352bb4cb3a4a0 100644 (file)
@@ -1291,6 +1291,8 @@ char *nvme_feature_to_string(int feature)
        case NVME_FEAT_AUTO_PST:        return "Autonomous Power State Transition";
        case NVME_FEAT_HOST_MEM_BUF:    return "Host Memory Buffer";
        case NVME_FEAT_KATO:            return "Keep Alive Timer";
+       case NVME_FEAT_PLM_CONFIG:      return "Predicatable Latency Mode Config";
+       case NVME_FEAT_PLM_WINDOW:      return "Predicatable Latency Mode Window";
        case NVME_FEAT_SW_PROGRESS:     return "Software Progress";
        case NVME_FEAT_HOST_ID:         return "Host Identifier";
        case NVME_FEAT_RESV_MASK:       return "Reservation Notification Mask";
@@ -1538,6 +1540,26 @@ void nvme_directive_show_fields(__u8 dtype, __u8 doper, unsigned int result, uns
         return;
 }
 
+static char *nvme_plm_window(__u32 plm)
+{
+       switch (plm & 0x7) {
+       case 1:
+               return "Deterministic Window (DTWIN)";
+       case 2:
+               return "Non-deterministic Window (NDWIN)";
+       default:
+               return "Reserved";
+       }
+}
+
+static void show_plm_config(struct nvme_plm_config *plmcfg)
+{
+       printf("\tEnable Event          :%04x\n", le16_to_cpu(plmcfg->enable_event));
+       printf("\tDTWIN Reads Threshold :%"PRIu64"\n", (uint64_t)le64_to_cpu(plmcfg->dtwin_reads_thresh));
+       printf("\tDTWIN Writes Threshold:%"PRIu64"\n", (uint64_t)le64_to_cpu(plmcfg->dtwin_writes_thresh));
+       printf("\tDTWIN Time Threshold  :%"PRIu64"\n", (uint64_t)le64_to_cpu(plmcfg->dtwin_time_thresh));
+}
+
 void nvme_feature_show_fields(__u32 fid, unsigned int result, unsigned char *buf)
 {
        __u8 field;
@@ -1610,6 +1632,13 @@ void nvme_feature_show_fields(__u32 fid, unsigned int result, unsigned char *buf
        case NVME_FEAT_SW_PROGRESS:
                printf("\tPre-boot Software Load Count (PBSLC): %u\n", result & 0x000000ff);
                break;
+       case NVME_FEAT_PLM_CONFIG:
+               printf("\tPredictable Latency Window Enabled: %s\n", result & 0x1 ? "True":"False");
+               show_plm_config((struct nvme_plm_config *)buf);
+               break;
+       case NVME_FEAT_PLM_WINDOW:
+               printf("\tWindow Select: %s", nvme_plm_window(result));
+               break;
        case NVME_FEAT_HOST_ID:
                ull =  buf[7]; ull <<= 8; ull |= buf[6]; ull <<= 8; ull |= buf[5]; ull <<= 8;
                ull |= buf[4]; ull <<= 8; ull |= buf[3]; ull <<= 8; ull |= buf[2]; ull <<= 8;
diff --git a/nvme.c b/nvme.c
index 7939b1624b093f2a79d0126b6c115b0314f4a5b6..fad7fcc056f540e1a73c46297de58b143db5680b 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -1811,6 +1811,9 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin
                if (cfg.cdw11 & 0x1)
                        cfg.data_len = 16;
                break;
+       case NVME_FEAT_PLM_CONFIG:
+               cfg.data_len = 512;
+               break;
        }
 
        if (cfg.sel == 3)
@@ -2457,10 +2460,11 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
                "Use get-feature to determine which Features are supported by "\
                "the controller and are saveable/changeable.";
        const char *namespace_id = "desired namespace";
-       const char *feature_id = "hex feature name (required)";
+       const char *feature_id = "feature identifier (required)";
        const char *data_len = "buffer length if data required";
        const char *data = "optional file for feature data (default stdin)";
        const char *value = "new value of feature (required)";
+       const char *cdw12 = "feature cdw12, if used";
        const char *save = "specifies that the controller shall save the attribute";
        int err;
        __u32 result;
@@ -2472,6 +2476,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
                __u32 namespace_id;
                __u32 feature_id;
                __u32 value;
+               __u32 cdw12;
                __u32 data_len;
                int   save;
        };
@@ -2489,6 +2494,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
                {"namespace-id", 'n', "NUM",  CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace_id},
                {"feature-id",   'f', "NUM",  CFG_POSITIVE, &cfg.feature_id,   required_argument, feature_id},
                {"value",        'v', "NUM",  CFG_POSITIVE, &cfg.value,        required_argument, value},
+               {"cdw12",        'c', "NUM",  CFG_POSITIVE, &cfg.cdw12,        required_argument, cdw12},
                {"data-len",     'l', "NUM",  CFG_POSITIVE, &cfg.data_len,     required_argument, data_len},
                {"data",         'd', "FILE", CFG_STRING,   &cfg.file,         required_argument, data},
                {"save",         's', "",     CFG_NONE,     &cfg.save,         no_argument, save},
@@ -2531,8 +2537,8 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
                }
        }
 
-       err = nvme_set_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.value, cfg.save,
-                               cfg.data_len, buf, &result);
+       err = nvme_set_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.value,
+                              cfg.cdw12, cfg.save, cfg.data_len, buf, &result);
        if (err < 0) {
                perror("set-feature");
        } else if (!err) {