]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: Use chunked read in get_log()
authorDaniel Wagner <dwagner@suse.de>
Wed, 15 Feb 2023 11:35:10 +0000 (12:35 +0100)
committerDaniel Wagner <wagi@monom.org>
Thu, 16 Feb 2023 07:48:22 +0000 (08:48 +0100)
Large transfer might not work because we exhaust resource limits, so
chunk the read into 4k (default).

Signed-off-by: Daniel Wagner <dwagner@suse.de>
Documentation/nvme-get-log.txt
nvme-wrap.c
nvme-wrap.h
nvme.c

index a92ab6a334e44b0dd1eb8c34e1213126097d0045..a51c435df04b96594c88889d6a2c880d2e4c4289 100644 (file)
@@ -19,6 +19,7 @@ SYNOPSIS
              [--rae | -r]
              [--csi=<command_set_identifier> | -y <command_set_identifier>]
              [--ot=<offset_type> | -O <offset_type>]
+                   [--xfer-len=<length> | -x <length>]
 
 DESCRIPTION
 -----------
@@ -95,6 +96,11 @@ OPTIONS
        The default is byte offset. If the option is specified
        the index mode is used.
 
+-x <length>::
+--xfer-len <length>:
+       Specify the read chunk size. The length argument is expected to be
+       a multiple of 4096. The default size is 4096.
+
 EXAMPLES
 --------
 * Get 512 bytes from log page 2
index ae7cd9253999469ff82e5f4cbf580476b40a355a..cee9b235d3d5412d1759d130cf4e6a36cc53dff8 100644 (file)
@@ -158,6 +158,12 @@ int nvme_cli_get_log(struct nvme_dev *dev, struct nvme_get_log_args *args)
        return do_admin_args_op(get_log, dev, args);
 }
 
+int nvme_cli_get_log_page(struct nvme_dev *dev, __u32 xfer_len,
+                         struct nvme_get_log_args *args)
+{
+       return do_admin_op(get_log_page, dev, xfer_len, args);
+}
+
 int nvme_cli_get_nsid_log(struct nvme_dev *dev, bool rae,
                          enum nvme_cmd_get_log_lid lid,
                          __u32 nsid, __u32 len, void *log)
index 4dcc6651b3d1958cbb5d324e8497768825a0498a..e44a4f28395f177a0f30b7b8c2ff3742eedaeee8 100644 (file)
@@ -51,6 +51,9 @@ int nvme_cli_get_features(struct nvme_dev *dev,
 
 
 int nvme_cli_get_log(struct nvme_dev *dev, struct nvme_get_log_args *args);
+int nvme_cli_get_log_page(struct nvme_dev *dev,
+                          __u32 xfer_len,
+                          struct nvme_get_log_args *args);
 
 int nvme_cli_get_nsid_log(struct nvme_dev *dev, bool rae,
                          enum nvme_cmd_get_log_lid lid,
diff --git a/nvme.c b/nvme.c
index b76df8521edc0bfc898260c139b10736ff600898..2ab5923631e44e1634f63b720956984f258ddc12 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -2119,6 +2119,7 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
        const char *raw = "output in raw format";
        const char *csi = "command set identifier";
        const char *offset_type = "offset type";
+       const char *xfer_len = "read chunk size (default 4k)";
        struct nvme_dev *dev;
        unsigned char *log;
        int err;
@@ -2136,6 +2137,7 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
                bool    raw_binary;
                __u8    csi;
                bool    ot;
+               __u32   xfer_len;
        };
 
        struct config cfg = {
@@ -2151,6 +2153,7 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
                .raw_binary     = false,
                .csi            = NVME_CSI_NVM,
                .ot             = false,
+               .xfer_len       = 4096,
        };
 
        OPT_ARGS(opts) = {
@@ -2166,6 +2169,7 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
                OPT_FLAG("raw-binary",   'b', &cfg.raw_binary,   raw),
                OPT_BYTE("csi",          'y', &cfg.csi,          csi),
                OPT_FLAG("ot",           'O', &cfg.ot,           offset_type),
+               OPT_UINT("xfer-len",     'x', &cfg.xfer_len,     xfer_len),
                OPT_END()
        };
 
@@ -2196,6 +2200,12 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
                goto close_dev;
        }
 
+       if (cfg.xfer_len == 0 || cfg.xfer_len % 4096) {
+               fprintf(stderr, "xfer-len argument invalid. It needs to be mulitple of 4k");
+               err = -EINVAL;
+               goto close_dev;
+       }
+
        log = malloc(cfg.log_len);
        if (!log) {
                perror("could not alloc buffer for log\n");
@@ -2218,7 +2228,7 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
                .log            = log,
                .result         = NULL,
        };
-       err = nvme_cli_get_log(dev, &args);
+       err = nvme_cli_get_log_page(dev, cfg.xfer_len, &args);
        if (!err) {
                if (!cfg.raw_binary) {
                        printf("Device:%s log-id:%d namespace-id:%#x\n",