]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
Split host and controller telemetry log API
authorKeith Busch <kbusch@kernel.org>
Mon, 10 Feb 2020 19:04:51 +0000 (11:04 -0800)
committerKeith Busch <kbusch@kernel.org>
Mon, 10 Feb 2020 19:04:51 +0000 (11:04 -0800)
While similar, these are logs are not obtained the same way.

Signed-off-by: Keith Busch <kbusch@kernel.org>
examples/telemetry-listen.c
src/nvme/cmd.h
src/nvme/ioctl.c
src/nvme/util.c
src/nvme/util.h

index 1561a0c740d40440a90600dbde307ad5ef269bbc..00c43f7bef7fa32d420c5b5705fe627aa85775f4 100644 (file)
@@ -33,16 +33,11 @@ static void save_telemetry(nvme_ctrl_t c)
        void *log;
        time_t s;
 
-       ret = nvme_get_telemetry_log(nvme_ctrl_get_fd(c), false, true, 3, &log,
-               &log_size);
+       /* Clear the log (rae == false) at the end to see new telemetry events later */
+       ret = nvme_get_ctrl_telemetry(nvme_ctrl_get_fd(c), false, &log, &log_size);
        if (ret)
                return;
 
-       /* Clear the log (rae == false) to see new telemetry events later */
-       nvme_get_log_telemetry_ctrl(nvme_ctrl_get_fd(c), false, 0, sizeof(buf),
-               buf);
-       memset(buf, 0, sizeof(buf));
-
        s = time(NULL);
        ret = snprintf(buf, sizeof(buf), "/var/log/%s-telemetry-%ld",
                nvme_ctrl_get_subsysnqn(c), s);
index bdbff39140be1b9fd377ab3e54b4a08e1634daae..80b7b96eb259b11b2650bed68e4c93bd6a8543e2 100644 (file)
@@ -314,44 +314,39 @@ enum nvme_directive_dtype {
 };
 
 /**
- * enum -
+ * enum nvme_directive_receive_doper -
+ * @NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM:
+ * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM:
+ * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS:
+ * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE:
  */
-enum nvme_cmd_directive_receive_identify_doper {
+enum nvme_directive_receive_doper {
        NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM             = 0x01,
-};
-
-/**
- * enum -
- */
-enum nvme_cmd_directive_receive_streams_doper {
        NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM              = 0x01,
        NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS             = 0x02,
        NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE           = 0x03,
 };
 
 /**
- * enum -
+ * enum nvme_directive_send_doper -
+ * @NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR:
+ * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER:
+ * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE:
  */
-enum nvme_cmd_directive_send_identify_doper {
+enum nvme_directive_send_doper {
        NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR                = 0x01,
+       NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER    = 0x01,
+       NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE      = 0x02,
 };
 
 /**
  * enum -
  */
-enum nvme_cmd_directive_send_identify_endir {
+enum nvme_directive_send_identify_endir {
        NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE              = 0,
        NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE               = 1,
 };
 
-/**
- * enum -
- */
-enum nvme_cmd_directive_send_streams_doper {
-       NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER    = 0x01,
-       NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE      = 0x02,
-};
-
 /**
  * enum nvme_sanitize_sanact -
  * @NVME_SANITIZE_SANACT_EXIT_FAILURE:
@@ -1893,7 +1888,7 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl,
  * @fd:                File descriptor of nvme device
  * @nsid:      Namespace ID, if applicable
  * @dspec:     Directive specific field
- * @doper:     Directive operation
+ * @doper:     Directive send operation, see &enum nvme_directive_send_doper
  * @dtype:     Directive type, see &enum nvme_directive_dtype
  * @dw12:      Directive specific command dword12
  * @data_len:  Length of data payload in bytes
@@ -1909,7 +1904,8 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl,
  * Return: The nvme command status if a response was received or -1 with errno
  *        set otherwise.
  */
-int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, __u8 doper,
+int nvme_directive_send(int fd, __u32 nsid, __u16 dspec,
+                       enum nvme_directive_send_doper doper,
                        enum nvme_directive_dtype dtype, __u32 cdw12,
                        __u32 data_len, void *data, __u32 *result);
 
@@ -1951,7 +1947,7 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid);
  * @fd:                File descriptor of nvme device
  * @nsid:      Namespace ID, if applicable
  * @dspec:     Directive specific field
- * @doper:     Directive operation
+ * @doper:     Directive receive operation, see &enum nvme_directive_receive_doper
  * @dtype:     Directive type, see &enum nvme_directive_dtype
  * @dw12:      Directive specific command dword12
  * @data_len:  Length of data payload
@@ -1961,7 +1957,8 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid);
  * Return: The nvme command status if a response was received or -1 with errno
  *        set otherwise.
  */
-int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, __u8 doper,
+int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec,
+                       enum nvme_directive_receive_doper doper,
                        enum nvme_directive_dtype dtype, __u32 cdw12,
                        __u32 data_len, void *data, __u32 *result);
 
index c2d219cc7ac39f75428b73823a8b27dec6d5d6db..0298c8b9eda66c8da36236397e823bb0307b9518 100644 (file)
@@ -1281,7 +1281,8 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl,
        return nvme_submit_admin_passthru(fd, &cmd, NULL);
 }
 
-int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, __u8 doper,
+int nvme_directive_send(int fd, __u32 nsid, __u16 dspec,
+                       enum nvme_directive_send_doper doper,
                        enum nvme_directive_dtype dtype, __u32 cdw12,
                        __u32 data_len, void *data, __u32 *result)
 {
@@ -1331,7 +1332,8 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid)
                NULL);
 }
 
-int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, __u8 doper,
+int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec,
+                       enum nvme_directive_receive_doper doper,
                        enum nvme_directive_dtype dtype, __u32 cdw12,
                        __u32 data_len, void *data, __u32 *result)
 {
index 73099afe6dde2deed0ed2335dfedd73fdc1b38df..7ce5b63c0e50c3a454ce743d88abca768fed5604 100644 (file)
@@ -235,6 +235,7 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
                __u32 xfer_len, __u32 data_len, void *data)
 {
        __u64 offset = 0, xfer;
+       bool retain = true;
        void *ptr = data;
        int ret;
 
@@ -247,8 +248,16 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
                if (xfer > xfer_len)
                        xfer  = xfer_len;
 
+               /*
+                * Always retain regardless of the RAE parameter until the very
+                * last portion of this log page so the data remains latched
+                * during the fetch sequence.
+                */
+               if (offset + xfer == data_len)
+                       retain = rae;
+
                ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE,
-                                  NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE,
+                                  NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE,
                                   xfer, ptr);
                if (ret)
                        return ret;
@@ -266,14 +275,14 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae,
        return __nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data);
 }
 
-int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area,
-                      void **buf, __u32 *log_size)
+static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, void **buf,
+               __u32 *log_size)
 {
        static const __u32 xfer = 512;
 
-       __u8 lid = NVME_LOG_LID_TELEMETRY_HOST;
        struct nvme_telemetry_log *telem;
        __u32 size;
+       __u8 lid;
        void *log;
        int err;
 
@@ -286,36 +295,24 @@ int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area,
        if (ctrl) {
                err = nvme_get_log_telemetry_ctrl(fd, true, 0, xfer, log);
                lid = NVME_LOG_LID_TELEMETRY_CTRL;
-       } else if (create)
-               err = nvme_get_log_create_telemetry_host(fd, log);
-       else
-               err = nvme_get_log_telemetry_host(fd, 0, xfer, log);
+       } else {
+               lid = NVME_LOG_LID_TELEMETRY_HOST;
+               if (create)
+                       err = nvme_get_log_create_telemetry_host(fd, log);
+               else
+                       err = nvme_get_log_telemetry_host(fd, 0, xfer, log);
+       }
 
        if (err)
                goto free;
 
        telem = log;
-       if (!telem->ctrlavail) {
+       if (ctrl && !telem->ctrlavail) {
                size = xfer;
                goto done;
        }
 
-       switch (data_area) {
-       case 1:
-               size = (le16_to_cpu(telem->dalb1) * xfer) + xfer;
-               break;
-       case 2:
-               size = (le16_to_cpu(telem->dalb2) * xfer) + xfer;
-               break;
-       case 3:
-               size = (le16_to_cpu(telem->dalb3) * xfer) + xfer;
-               break;
-       default:
-               errno = EINVAL;
-               err = -1;
-               goto free;
-       }
-
+       size = (le16_to_cpu(telem->dalb3) * xfer) + xfer;
        log = realloc(log, size);
        if (!log) {
                errno = ENOMEM;
@@ -323,7 +320,7 @@ int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area,
                goto free;
        }
 
-       err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, true, size, (void *)log);
+       err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, rae, size, (void *)log);
        if (err)
                goto free;
 done:
@@ -335,6 +332,21 @@ free:
        return err;
 }
 
+int nvme_get_ctrl_telemetry(int fd, bool rae, void **buf, __u32 *log_size)
+{
+       return nvme_get_telemetry_log(fd, false, true, rae, buf, log_size);
+}
+
+int nvme_get_host_telemetry(int fd,  void **buf, __u32 *log_size)
+{
+       return nvme_get_telemetry_log(fd, false, false, false, buf, log_size);
+}
+
+int nvme_get_new_host_telemetry(int fd,  void **buf, __u32 *log_size)
+{
+       return nvme_get_telemetry_log(fd, true, false, false, buf, log_size);
+}
+
 void nvme_setup_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs,
                          __u32 *llbas, __u64 *slbas, __u16 nr_ranges)
 {
@@ -464,37 +476,36 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len)
        return 0;
 }
 
-int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len)
+int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype,
+               enum nvme_directive_receive_doper doper, __u32 *len)
 {
        switch (dtype) {
        case NVME_DIRECTIVE_DTYPE_IDENTIFY:
                switch (doper) {
                case NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM:
                        *len = sizeof(struct nvme_id_directives);
-                       break;
+                       return 0;
                default:
                        errno = EINVAL;
                        return -1;
                }
-               break;
        case NVME_DIRECTIVE_DTYPE_STREAMS:
                switch (doper) {
                case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM:
                        *len = sizeof(struct nvme_streams_directive_params);
-                       break;
+                       return 0;
                case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS:
                        *len = (128 * 1024) * sizeof(__le16);
-                       break;
+                       return 0;
                case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE:
                        *len = 0;
-                       break;
+                       return 0;
                default:
                        return -EINVAL;
                }
        default:
                return -EINVAL;
        }
-       return 0;
 }
 
 static int __nvme_set_attr(const char *path, const char *value)
index 96824d5f4a0b9e8cead522717d21e7ff579e1604..82588dd1446a6822706a65462d59816a9f77d526 100644 (file)
@@ -4,7 +4,7 @@
 #include <stdbool.h>
 #include <linux/types.h>
 
-#include "types.h"
+#include "cmd.h"
 
 /**
  * nvme_status_to_errno() - Converts nvme return status to errno
@@ -31,18 +31,35 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset,
                         void *buf);
 
 /**
- * nvme_get_telemetry_log() -
+ * nvme_get_ctrl_telemetry() -
  * @fd:
- * @create:
- * @ctrl:
- * @data_area:
+ * @rae:
  * @buf:
  * @log_size:
  *
- * Return: 
+ * Returns:
+ */
+int nvme_get_ctrl_telemetry(int fd, bool rae, void **buf, __u32 *log_size);
+
+/**
+ * nvme_get_host_telemetry() -
+ * @fd:
+ * @buf:
+ * @log_size:
+ *
+ * Returns:
  */
-int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area,
-                          void **buf, __u32 *log_size);
+int nvme_get_host_telemetry(int fd, void **buf, __u32 *log_size);
+
+/**
+ * nvme_get_new_host_telemetry() -
+ * @fd:
+ * @buf:
+ * @log_size:
+ *
+ * Returns:
+ */
+int nvme_get_new_host_telemetry(int fd, void **buf, __u32 *log_size);
 
 /**
  * nvme_setup_id_ns() -
@@ -156,13 +173,15 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len);
 
 /**
  * nvme_get_directive_receive_length() -
- * @dtype:
- * @doper:
- * @len:
+ * @dtype:     Directive type, see &enum nvme_directive_dtype
+ * @doper:     Directive receive operation, see &enum nvme_directive_receive_doper
+ * @len:       Address to save the payload length of the directive in bytes on
+ *             a successful decode
  *
- * Return: 
+ * Return: 0 on success, -1 with errno set to EINVAL.
  */
-int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len);
+int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype,
+               enum nvme_directive_receive_doper doper, __u32 *len);
 
 /**
  * nvme_open() - Open an nvme controller or namespace device