Skip to content

Commit a4b58f1

Browse files
committed
Merge tag 'nvme-5.13-2021-05-27' of git://git.infradead.org/nvme into block-5.13
Pull NVMe fixes from Christoph: "nvme fixes for Linux 5.13 - fix a memory leak in nvme_cdev_add (Guoqing Jiang) - fix inline data size comparison in nvmet_tcp_queue_response (Hou Pu) - fix false keep-alive timeout when a controller is torn down (Sagi Grimberg) - fix a nvme-tcp Kconfig dependency (Sagi Grimberg) - short-circuit reconnect retries for FC (Hannes Reinecke) - decode host pathing error for connect (Hannes Reinecke)" * tag 'nvme-5.13-2021-05-27' of git://git.infradead.org/nvme: nvmet: fix false keep-alive timeout when a controller is torn down nvmet-tcp: fix inline data size comparison in nvmet_tcp_queue_response nvme-tcp: remove incorrect Kconfig dep in BLK_DEV_NVME nvme-fabrics: decode host pathing error for connect nvme-fc: short-circuit reconnect retries nvme: fix potential memory leaks in nvme_cdev_add
2 parents 094c271 + aaeadd7 commit a4b58f1

File tree

7 files changed

+40
-16
lines changed

7 files changed

+40
-16
lines changed

drivers/nvme/host/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ config NVME_FC
7171
config NVME_TCP
7272
tristate "NVM Express over Fabrics TCP host driver"
7373
depends on INET
74-
depends on BLK_DEV_NVME
74+
depends on BLOCK
75+
select NVME_CORE
7576
select NVME_FABRICS
7677
select CRYPTO
7778
select CRYPTO_CRC32C

drivers/nvme/host/core.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3485,8 +3485,10 @@ int nvme_cdev_add(struct cdev *cdev, struct device *cdev_device,
34853485
cdev_init(cdev, fops);
34863486
cdev->owner = owner;
34873487
ret = cdev_device_add(cdev, cdev_device);
3488-
if (ret)
3488+
if (ret) {
3489+
put_device(cdev_device);
34893490
ida_simple_remove(&nvme_ns_chr_minor_ida, minor);
3491+
}
34903492
return ret;
34913493
}
34923494

drivers/nvme/host/fabrics.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@ static void nvmf_log_connect_error(struct nvme_ctrl *ctrl,
336336
cmd->connect.recfmt);
337337
break;
338338

339+
case NVME_SC_HOST_PATH_ERROR:
340+
dev_err(ctrl->device,
341+
"Connect command failed: host path error\n");
342+
break;
343+
339344
default:
340345
dev_err(ctrl->device,
341346
"Connect command failed, error wo/DNR bit: %d\n",

drivers/nvme/host/fc.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3107,13 +3107,15 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
31073107
if (ctrl->ctrl.icdoff) {
31083108
dev_err(ctrl->ctrl.device, "icdoff %d is not supported!\n",
31093109
ctrl->ctrl.icdoff);
3110+
ret = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
31103111
goto out_disconnect_admin_queue;
31113112
}
31123113

31133114
/* FC-NVME supports normal SGL Data Block Descriptors */
31143115
if (!(ctrl->ctrl.sgls & ((1 << 0) | (1 << 1)))) {
31153116
dev_err(ctrl->ctrl.device,
31163117
"Mandatory sgls are not supported!\n");
3118+
ret = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
31173119
goto out_disconnect_admin_queue;
31183120
}
31193121

@@ -3280,11 +3282,13 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status)
32803282
if (ctrl->ctrl.state != NVME_CTRL_CONNECTING)
32813283
return;
32823284

3283-
if (portptr->port_state == FC_OBJSTATE_ONLINE)
3285+
if (portptr->port_state == FC_OBJSTATE_ONLINE) {
32843286
dev_info(ctrl->ctrl.device,
32853287
"NVME-FC{%d}: reset: Reconnect attempt failed (%d)\n",
32863288
ctrl->cnum, status);
3287-
else if (time_after_eq(jiffies, rport->dev_loss_end))
3289+
if (status > 0 && (status & NVME_SC_DNR))
3290+
recon = false;
3291+
} else if (time_after_eq(jiffies, rport->dev_loss_end))
32883292
recon = false;
32893293

32903294
if (recon && nvmf_should_reconnect(&ctrl->ctrl)) {
@@ -3298,12 +3302,17 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status)
32983302

32993303
queue_delayed_work(nvme_wq, &ctrl->connect_work, recon_delay);
33003304
} else {
3301-
if (portptr->port_state == FC_OBJSTATE_ONLINE)
3302-
dev_warn(ctrl->ctrl.device,
3303-
"NVME-FC{%d}: Max reconnect attempts (%d) "
3304-
"reached.\n",
3305-
ctrl->cnum, ctrl->ctrl.nr_reconnects);
3306-
else
3305+
if (portptr->port_state == FC_OBJSTATE_ONLINE) {
3306+
if (status > 0 && (status & NVME_SC_DNR))
3307+
dev_warn(ctrl->ctrl.device,
3308+
"NVME-FC{%d}: reconnect failure\n",
3309+
ctrl->cnum);
3310+
else
3311+
dev_warn(ctrl->ctrl.device,
3312+
"NVME-FC{%d}: Max reconnect attempts "
3313+
"(%d) reached.\n",
3314+
ctrl->cnum, ctrl->ctrl.nr_reconnects);
3315+
} else
33073316
dev_warn(ctrl->ctrl.device,
33083317
"NVME-FC{%d}: dev_loss_tmo (%d) expired "
33093318
"while waiting for remoteport connectivity.\n",

drivers/nvme/target/core.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,10 @@ static void nvmet_keep_alive_timer(struct work_struct *work)
388388
{
389389
struct nvmet_ctrl *ctrl = container_of(to_delayed_work(work),
390390
struct nvmet_ctrl, ka_work);
391-
bool cmd_seen = ctrl->cmd_seen;
391+
bool reset_tbkas = ctrl->reset_tbkas;
392392

393-
ctrl->cmd_seen = false;
394-
if (cmd_seen) {
393+
ctrl->reset_tbkas = false;
394+
if (reset_tbkas) {
395395
pr_debug("ctrl %d reschedule traffic based keep-alive timer\n",
396396
ctrl->cntlid);
397397
schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ);
@@ -804,6 +804,13 @@ void nvmet_sq_destroy(struct nvmet_sq *sq)
804804
percpu_ref_exit(&sq->ref);
805805

806806
if (ctrl) {
807+
/*
808+
* The teardown flow may take some time, and the host may not
809+
* send us keep-alive during this period, hence reset the
810+
* traffic based keep-alive timer so we don't trigger a
811+
* controller teardown as a result of a keep-alive expiration.
812+
*/
813+
ctrl->reset_tbkas = true;
807814
nvmet_ctrl_put(ctrl);
808815
sq->ctrl = NULL; /* allows reusing the queue later */
809816
}
@@ -952,7 +959,7 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
952959
}
953960

954961
if (sq->ctrl)
955-
sq->ctrl->cmd_seen = true;
962+
sq->ctrl->reset_tbkas = true;
956963

957964
return true;
958965

drivers/nvme/target/nvmet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ struct nvmet_ctrl {
167167
struct nvmet_subsys *subsys;
168168
struct nvmet_sq **sqs;
169169

170-
bool cmd_seen;
170+
bool reset_tbkas;
171171

172172
struct mutex lock;
173173
u64 cap;

drivers/nvme/target/tcp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ static void nvmet_tcp_queue_response(struct nvmet_req *req)
550550
* nvmet_req_init is completed.
551551
*/
552552
if (queue->rcv_state == NVMET_TCP_RECV_PDU &&
553-
len && len < cmd->req.port->inline_data_size &&
553+
len && len <= cmd->req.port->inline_data_size &&
554554
nvme_is_write(cmd->req.cmd))
555555
return;
556556
}

0 commit comments

Comments
 (0)