From: Tokunori Ikegami Date: Fri, 21 Jan 2022 15:58:38 +0000 (+0900) Subject: nvme: Refactor telemetry-log command for build warning #1323 X-Git-Tag: v2.0-rc2~3^2~1 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=5bc6f7b538694fe1d636023917f0eecb288522c9;p=users%2Fsagi%2Fnvme-cli.git nvme: Refactor telemetry-log command for build warning #1323 Signed-off-by: Tokunori Ikegami --- diff --git a/common.h b/common.h index 8d382070..9b118ab2 100644 --- a/common.h +++ b/common.h @@ -33,4 +33,10 @@ static inline uint64_t mmio_read64(void *addr) return ((uint64_t) high << 32) | low; } +#if __has_attribute(__fallthrough__) +# define fallthrough __attribute__((__fallthrough__)) +#else +# define fallthrough do {} while (0) /* fallthrough */ +#endif + #endif diff --git a/nvme.c b/nvme.c index dd7fcd42..73ede42e 100644 --- a/nvme.c +++ b/nvme.c @@ -407,20 +407,110 @@ ret: return nvme_status_to_errno(err, false); } -static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_telemetry_log_total_size_dalb4(int fd, + struct nvme_telemetry_log *log, + unsigned int *total_size) +{ + const size_t bs = 512; + int err; + int block_size = NVME_LOG_TELEM_BLOCK_SIZE; + __u32 result, len; + void *buf = NULL; + struct nvme_id_ctrl ctrl; + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_HOST_BEHAVIOR, + .nsid = NVME_NSID_ALL, + .sel = 0, + .cdw11 = 0, + .uuidx = 0, + .data = buf, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = &result, + }; + + err = nvme_identify_ctrl(fd, &ctrl); + if (err) { + perror("identify-ctrl"); + return err; + } + + len = nvme_get_feature_length(NVME_FEAT_FID_HOST_BEHAVIOR, 0, + &len); + if (posix_memalign(&buf, getpagesize(), len)) { + fprintf(stderr, "can not allocate feature payload\n"); + errno = ENOMEM; + return -1; + } + memset(buf, 0, len); + + args.data_len = len, + + err = nvme_get_features(&args); + if (err > 0) { + nvme_show_status(err); + } else if (err < 0) { + perror("get-feature"); + } else { + if (ctrl.lpa & 0x40) { + if (((unsigned char *)buf)[1] == 1) { + *total_size = le32_to_cpu(log->dalb4) * bs + block_size; + } else { + fprintf(stderr, + "Data area 4 unsupported, Host Behavior Support ETDAS not set to 1\n"); + err = -1; + } + } else { + fprintf(stderr, + "Data area 4 unsupported, bit 6 of Log Page Attributes not set\n"); + err = -1; + } + if (err) + errno = EINVAL; + } + free(buf); + return err; +} + +static int get_telemetry_log_total_size(int fd, int data_area, + struct nvme_telemetry_log *log, + unsigned int *total_size) +{ + int err = 0; + int block_size = NVME_LOG_TELEM_BLOCK_SIZE; + + switch (data_area) { + case 1: + *total_size = (le16_to_cpu(log->dalb1) + 1) * block_size; + break; + case 2: + *total_size = (le16_to_cpu(log->dalb2) + 1) * block_size; + break; + case 3: + fallthrough; + default: + *total_size = (le16_to_cpu(log->dalb3) + 1) * block_size; + break; + case 4: + err = get_telemetry_log_total_size_dalb4(fd, log, total_size); + break; + } + + return err; +} + +static int get_telemetry_log(int argc, char **argv, struct command *cmd, + struct plugin *plugin) { const char *desc = "Retrieve telemetry log and write to binary file"; const char *fname = "File name to save raw binary, includes header"; const char *hgen = "Have the host tell the controller to generate the report"; const char *cgen = "Gather report generated by the controller."; const char *dgen = "Pick which telemetry data area to report. Default is 3 to fetch areas 1-3. Valid options are 1, 2, 3, 4."; - const size_t bs = 512; struct nvme_telemetry_log *log; - struct nvme_id_ctrl ctrl; int err = 0, fd, output; - unsigned total_size; - __u32 result, len; - void *buf = NULL; + unsigned int total_size = 0; struct config { char *file_name; @@ -469,84 +559,19 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct else err = nvme_get_host_telemetry(fd, &log); - if (err < 0) + if (err < 0) { perror("get-telemetry-log"); - else if (err > 0) { + } else if (err > 0) { nvme_show_status(err); fprintf(stderr, "Failed to acquire telemetry log %d!\n", err); goto close_output; } - switch (cfg.data_area) { - case 1: - total_size = (le16_to_cpu(log->dalb1) + 1) * NVME_LOG_TELEM_BLOCK_SIZE; - break; - case 2: - total_size = (le16_to_cpu(log->dalb2) + 1) * NVME_LOG_TELEM_BLOCK_SIZE; - break; - case 3: - default: - total_size = (le16_to_cpu(log->dalb3) + 1) * NVME_LOG_TELEM_BLOCK_SIZE; - break; - case 4: - err = nvme_identify_ctrl(fd, &ctrl); - if (err) { - perror("identify-ctrl"); - goto close_output; - } - - len = nvme_get_feature_length(NVME_FEAT_FID_HOST_BEHAVIOR, 0, &len); - if (posix_memalign(&buf, getpagesize(), len)) { - fprintf(stderr, "can not allocate feature payload\n"); - errno = ENOMEM; - err = -1; - goto close_output; - } - memset(buf, 0, len); - - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = fd, - .fid = NVME_FEAT_FID_HOST_BEHAVIOR, - .nsid = NVME_NSID_ALL, - .sel = 0, - .cdw11 = 0, - .uuidx = 0, - .data_len = len, - .data = buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_get_features(&args); - if (err > 0) { - nvme_show_status(err); - } else if (err < 0) { - perror("get-feature"); - } else { - if ((ctrl.lpa & 0x40)) { - if (((unsigned char *)buf)[1] == 1) - total_size = (le32_to_cpu(log->dalb4) * bs) + NVME_LOG_TELEM_BLOCK_SIZE; - else { - fprintf(stderr, "Data area 4 unsupported, Host Behavior Support ETDAS not set to 1\n"); - errno = EINVAL; - err = -1; - } - } else { - fprintf(stderr, "Data area 4 unsupported, bit 6 of Log Page Attributes not set\n"); - errno = EINVAL; - err = -1; - } - } - free(buf); - if (err) - goto close_output; - break; - } - - err = write(output, (void *)log, total_size); - if (err != total_size) { - fprintf(stderr, "Failed to flush all data to file!\n"); - goto close_output; + err = get_telemetry_log_total_size(fd, cfg.data_area, log, &total_size); + if (total_size) { + err = write(output, (void *)log, total_size); + if (err < 0 || err != total_size) + fprintf(stderr, "Failed to flush all data to file!\n"); } close_output: