Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retry discovery log page on DNR #810

Merged
merged 11 commits into from
Apr 9, 2024
5 changes: 5 additions & 0 deletions src/libnvme.map
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ LIBNVME_1.9 {
nvme_submit_passthru64;
nvme_update_key;
nvme_ctrl_get_cntlid;
nvme_set_features_timestamp2;
nvme_set_features_host_behavior2;
nvme_set_features_host_id2;
nvme_set_features_iocs_profile2;
nvme_get_features_timestamp2;
};

LIBNVME_1_8 {
Expand Down
15 changes: 15 additions & 0 deletions src/nvme/fabrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,7 @@ static struct nvmf_discovery_log *nvme_discovery_log(
int retries = 0;
const char *name = nvme_ctrl_get_name(args->c);
uint64_t genctr, numrec;
__u32 result;
int fd = nvme_ctrl_get_fd(args->c);
struct nvme_get_log_args log_args = {
.result = args->result,
Expand All @@ -1076,13 +1077,21 @@ static struct nvmf_discovery_log *nvme_discovery_log(
name, retries, args->max_retries);
log_args.log = log;
log_args.len = DISCOVERY_HEADER_LEN;
if (!args->result)
log_args.result = &result;
retry_header:
if (nvme_get_log_page(fd, NVME_LOG_PAGE_PDU_SIZE, &log_args)) {
nvme_msg(r, LOG_INFO,
"%s: discover try %d/%d failed, error %d\n",
name, retries, args->max_retries, errno);
if (*log_args.result &&
!(*log_args.result & NVME_SC_DNR) &&
(++retries < args->max_retries))
goto retry_header;
goto out_free_log;
}

retries = 0;
do {
size_t entries_size;

Expand Down Expand Up @@ -1113,6 +1122,9 @@ static struct nvmf_discovery_log *nvme_discovery_log(
nvme_msg(r, LOG_INFO,
"%s: discover try %d/%d failed, error %d\n",
name, retries, args->max_retries, errno);
if (*log_args.result &&
!(*log_args.result & NVME_SC_DNR))
continue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continue in a do-while loop jumps to the while condition: while (genctr != le64_to_cpu(log->genctr) && ++retries < args->max_retries);. Is accessing the header valid valid if the command returned an error status? Presumably no data would have been transferred in that case.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There were some nasty surprises with this series. I've reverted the whole series for now.

goto out_free_log;
}

Expand All @@ -1129,6 +1141,9 @@ static struct nvmf_discovery_log *nvme_discovery_log(
nvme_msg(r, LOG_INFO,
"%s: discover try %d/%d failed, error %d\n",
name, retries, args->max_retries, errno);
if (*log_args.result &&
!(*log_args.result & NVME_SC_DNR))
continue;
goto out_free_log;
}
} while (genctr != le64_to_cpu(log->genctr) &&
Expand Down
119 changes: 105 additions & 14 deletions src/nvme/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,14 @@ int nvme_submit_passthru64(int fd, unsigned long ioctl_cmd,
{
int err = ioctl(fd, ioctl_cmd, cmd);

if (err >= 0 && result)
*result = cmd->result;
if (err >= 0) {
if (result)
*result = cmd->result;
if (cmd->result) {
errno = EPROTO;
err = -1;
}
}
return err;
}

Expand All @@ -96,8 +102,14 @@ int nvme_submit_passthru(int fd, unsigned long ioctl_cmd,
{
int err = ioctl(fd, ioctl_cmd, cmd);

if (err >= 0 && result)
*result = cmd->result;
if (err >= 0) {
if (result)
*result = cmd->result;
if (cmd->result) {
errno = EPROTO;
err = -1;
}
}
return err;
}

Expand Down Expand Up @@ -518,6 +530,18 @@ int nvme_set_features_auto_pst(int fd, bool apste, bool save,
}

int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp)
{
__u32 result = 0;
int err;

err = nvme_set_features_timestamp2(fd, save, timestamp, &result);
if (err && result)
err = result;
return err;
}

int nvme_set_features_timestamp2(int fd, bool save, __u64 timestamp,
__u32 *result)
{
__le64 t = cpu_to_le64(timestamp);
struct nvme_timestamp ts = {};
Expand All @@ -534,7 +558,7 @@ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp)
.data_len = sizeof(ts),
.data = &ts,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
.result = result,
};

memcpy(ts.timestamp, &t, sizeof(ts.timestamp));
Expand Down Expand Up @@ -637,7 +661,19 @@ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi,
}

int nvme_set_features_host_behavior(int fd, bool save,
struct nvme_feat_host_behavior *data)
struct nvme_feat_host_behavior *data)
{
__u32 result = 0;
int err;

err = nvme_set_features_host_behavior2(fd, save, data, &result);
if (err && result)
err = result;
return err;
}

int nvme_set_features_host_behavior2(int fd, bool save,
struct nvme_feat_host_behavior *data, __u32 *result)
{
struct nvme_set_features_args args = {
.args_size = sizeof(args),
Expand All @@ -652,7 +688,7 @@ int nvme_set_features_host_behavior(int fd, bool save,
.data_len = sizeof(*data),
.data = data,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
.result = result,
};

return nvme_set_features(&args);
Expand Down Expand Up @@ -681,6 +717,18 @@ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save,
}

int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid)
{
__u32 result = 0;
int err;

err = nvme_set_features_host_id2(fd, exhid, save, hostid, &result);
if (err && result)
err = result;
return err;
}

int nvme_set_features_host_id2(int fd, bool exhid, bool save, __u8 *hostid,
__u32 *result)
{
__u32 len = exhid ? 16 : 8;
__u32 value = !!exhid;
Expand All @@ -697,7 +745,7 @@ int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid)
.data_len = len,
.data = hostid,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
.result = result,
};

return nvme_set_features(&args);
Expand Down Expand Up @@ -745,11 +793,25 @@ int nvme_set_features_write_protect2(int fd, __u32 nsid,
}

int nvme_set_features_iocs_profile(int fd, __u16 iocsi, bool save)
{
__u32 value = NVME_SET(iocsi, FEAT_IOCSP_IOCSCI);
__u32 result = 0;
int err;

err = __nvme_set_features(fd, NVME_FEAT_FID_IOCS_PROFILE, value,
save, &result);
if (err && result)
err = result;
return err;
}

int nvme_set_features_iocs_profile2(int fd, __u16 iocsi, bool save,
__u32 *result)
{
__u32 value = NVME_SET(iocsi, FEAT_IOCSP_IOCSCI);

return __nvme_set_features(fd, NVME_FEAT_FID_IOCS_PROFILE, value,
save, NULL);
save, result);
}

int nvme_get_features(struct nvme_get_features_args *args)
Expand Down Expand Up @@ -980,6 +1042,18 @@ int nvme_get_features_host_mem_buf2(int fd, enum nvme_get_features_sel sel,

int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel,
struct nvme_timestamp *ts)
{
__u32 result = 0;
int err;

err = nvme_get_features_timestamp2(fd, sel, ts, &result);
if (err && result)
err = result;
return err;
}

int nvme_get_features_timestamp2(int fd, enum nvme_get_features_sel sel,
struct nvme_timestamp *ts, __u32 *result)
{
struct nvme_get_features_args args = {
.args_size = sizeof(args),
Expand All @@ -992,7 +1066,7 @@ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel,
.data_len = sizeof(*ts),
.data = ts,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
.result = result,
};

return nvme_get_features(&args);
Expand Down Expand Up @@ -1120,7 +1194,19 @@ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel,
}

int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel,
bool exhid, __u32 len, __u8 *hostid)
bool exhid, __u32 len, __u8 *hostid)
{
__u32 result = 0;
int err;

err = nvme_get_features_host_id2(fd, sel, exhid, len, hostid, &result);
if (err && result)
err = result;
return err;
}

int nvme_get_features_host_id2(int fd, enum nvme_get_features_sel sel,
bool exhid, __u32 len, __u8 *hostid, __u32 *result)
{
struct nvme_get_features_args args = {
.args_size = sizeof(args),
Expand All @@ -1133,7 +1219,7 @@ int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel,
.data_len = len,
.data = hostid,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
.result = result,
};

return nvme_get_features(&args);
Expand Down Expand Up @@ -1447,6 +1533,8 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir,
{
__u32 cdw12 = NVME_SET(dtype, DIRECTIVE_SEND_IDENTIFY_CDW12_DTYPE) |
NVME_SET(endir, DIRECTIVE_SEND_IDENTIFY_CDW12_ENDIR);
__u32 result = 0;
int err;
struct nvme_directive_send_args args = {
.args_size = sizeof(args),
.fd = fd,
Expand All @@ -1458,10 +1546,13 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir,
.data_len = sizeof(*id),
.data = id,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
.result = &result,
};

return nvme_directive_send(&args);
err = nvme_directive_send(&args);
if (err && result)
err = result;
return err;
}

int nvme_directive_recv(struct nvme_directive_recv_args *args)
Expand Down
Loading