Skip to content

Commit f3163d8

Browse files
committed
Merge tag 'nvme-5.19-2022-06-30' of git://git.infradead.org/nvme into block-5.19
Pull NVMe fixes from Christoph: "nvme fixes for Linux 5.19 - more quirks (Lamarque Vieira Souza, Pablo Greco) - fix a fabrics disconnect regression (Ruozhu Li) - fix a nvmet-tcp data_digest calculation regression (Sagi Grimberg) - fix nvme-tcp send failure handling (Sagi Grimberg) - fix a regression with nvmet-loop and passthrough controllers (Alan Adamson)" * tag 'nvme-5.19-2022-06-30' of git://git.infradead.org/nvme: nvme-pci: add NVME_QUIRK_BOGUS_NID for ADATA IM2P33F8ABR1 nvmet: add a clear_ids attribute for passthru targets nvme: fix regression when disconnect a recovering ctrl nvme-pci: add NVME_QUIRK_BOGUS_NID for ADATA XPG SX6000LNP (AKA SPECTRIX S40G) nvme-tcp: always fail a request when sending it failed nvmet-tcp: fix regression in data_digest calculation
2 parents fbb564a + e1c70d7 commit f3163d8

File tree

10 files changed

+109
-29
lines changed

10 files changed

+109
-29
lines changed

drivers/nvme/host/core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4595,6 +4595,8 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl)
45954595
nvme_stop_failfast_work(ctrl);
45964596
flush_work(&ctrl->async_event_work);
45974597
cancel_work_sync(&ctrl->fw_act_work);
4598+
if (ctrl->ops->stop_ctrl)
4599+
ctrl->ops->stop_ctrl(ctrl);
45984600
}
45994601
EXPORT_SYMBOL_GPL(nvme_stop_ctrl);
46004602

drivers/nvme/host/nvme.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ struct nvme_ctrl_ops {
502502
void (*free_ctrl)(struct nvme_ctrl *ctrl);
503503
void (*submit_async_event)(struct nvme_ctrl *ctrl);
504504
void (*delete_ctrl)(struct nvme_ctrl *ctrl);
505+
void (*stop_ctrl)(struct nvme_ctrl *ctrl);
505506
int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
506507
void (*print_device_info)(struct nvme_ctrl *ctrl);
507508
};

drivers/nvme/host/pci.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3469,8 +3469,11 @@ static const struct pci_device_id nvme_id_table[] = {
34693469
{ PCI_DEVICE(0x1b4b, 0x1092), /* Lexar 256 GB SSD */
34703470
.driver_data = NVME_QUIRK_NO_NS_DESC_LIST |
34713471
NVME_QUIRK_IGNORE_DEV_SUBNQN, },
3472+
{ PCI_DEVICE(0x1cc1, 0x33f8), /* ADATA IM2P33F8ABR1 1 TB */
3473+
.driver_data = NVME_QUIRK_BOGUS_NID, },
34723474
{ PCI_DEVICE(0x10ec, 0x5762), /* ADATA SX6000LNP */
3473-
.driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, },
3475+
.driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN |
3476+
NVME_QUIRK_BOGUS_NID, },
34743477
{ PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */
34753478
.driver_data = NVME_QUIRK_NO_DEEPEST_PS |
34763479
NVME_QUIRK_IGNORE_DEV_SUBNQN, },

drivers/nvme/host/rdma.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,14 @@ static void nvme_rdma_teardown_io_queues(struct nvme_rdma_ctrl *ctrl,
10481048
}
10491049
}
10501050

1051+
static void nvme_rdma_stop_ctrl(struct nvme_ctrl *nctrl)
1052+
{
1053+
struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl);
1054+
1055+
cancel_work_sync(&ctrl->err_work);
1056+
cancel_delayed_work_sync(&ctrl->reconnect_work);
1057+
}
1058+
10511059
static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl)
10521060
{
10531061
struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl);
@@ -2252,9 +2260,6 @@ static const struct blk_mq_ops nvme_rdma_admin_mq_ops = {
22522260

22532261
static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown)
22542262
{
2255-
cancel_work_sync(&ctrl->err_work);
2256-
cancel_delayed_work_sync(&ctrl->reconnect_work);
2257-
22582263
nvme_rdma_teardown_io_queues(ctrl, shutdown);
22592264
nvme_stop_admin_queue(&ctrl->ctrl);
22602265
if (shutdown)
@@ -2304,6 +2309,7 @@ static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = {
23042309
.submit_async_event = nvme_rdma_submit_async_event,
23052310
.delete_ctrl = nvme_rdma_delete_ctrl,
23062311
.get_address = nvmf_get_address,
2312+
.stop_ctrl = nvme_rdma_stop_ctrl,
23072313
};
23082314

23092315
/*

drivers/nvme/host/tcp.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,8 +1180,7 @@ static int nvme_tcp_try_send(struct nvme_tcp_queue *queue)
11801180
} else if (ret < 0) {
11811181
dev_err(queue->ctrl->ctrl.device,
11821182
"failed to send request %d\n", ret);
1183-
if (ret != -EPIPE && ret != -ECONNRESET)
1184-
nvme_tcp_fail_request(queue->request);
1183+
nvme_tcp_fail_request(queue->request);
11851184
nvme_tcp_done_send_req(queue);
11861185
}
11871186
return ret;
@@ -2194,9 +2193,6 @@ static void nvme_tcp_error_recovery_work(struct work_struct *work)
21942193

21952194
static void nvme_tcp_teardown_ctrl(struct nvme_ctrl *ctrl, bool shutdown)
21962195
{
2197-
cancel_work_sync(&to_tcp_ctrl(ctrl)->err_work);
2198-
cancel_delayed_work_sync(&to_tcp_ctrl(ctrl)->connect_work);
2199-
22002196
nvme_tcp_teardown_io_queues(ctrl, shutdown);
22012197
nvme_stop_admin_queue(ctrl);
22022198
if (shutdown)
@@ -2236,6 +2232,12 @@ static void nvme_reset_ctrl_work(struct work_struct *work)
22362232
nvme_tcp_reconnect_or_remove(ctrl);
22372233
}
22382234

2235+
static void nvme_tcp_stop_ctrl(struct nvme_ctrl *ctrl)
2236+
{
2237+
cancel_work_sync(&to_tcp_ctrl(ctrl)->err_work);
2238+
cancel_delayed_work_sync(&to_tcp_ctrl(ctrl)->connect_work);
2239+
}
2240+
22392241
static void nvme_tcp_free_ctrl(struct nvme_ctrl *nctrl)
22402242
{
22412243
struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
@@ -2557,6 +2559,7 @@ static const struct nvme_ctrl_ops nvme_tcp_ctrl_ops = {
25572559
.submit_async_event = nvme_tcp_submit_async_event,
25582560
.delete_ctrl = nvme_tcp_delete_ctrl,
25592561
.get_address = nvmf_get_address,
2562+
.stop_ctrl = nvme_tcp_stop_ctrl,
25602563
};
25612564

25622565
static bool

drivers/nvme/target/configfs.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,11 +773,31 @@ static ssize_t nvmet_passthru_io_timeout_store(struct config_item *item,
773773
}
774774
CONFIGFS_ATTR(nvmet_passthru_, io_timeout);
775775

776+
static ssize_t nvmet_passthru_clear_ids_show(struct config_item *item,
777+
char *page)
778+
{
779+
return sprintf(page, "%u\n", to_subsys(item->ci_parent)->clear_ids);
780+
}
781+
782+
static ssize_t nvmet_passthru_clear_ids_store(struct config_item *item,
783+
const char *page, size_t count)
784+
{
785+
struct nvmet_subsys *subsys = to_subsys(item->ci_parent);
786+
unsigned int clear_ids;
787+
788+
if (kstrtouint(page, 0, &clear_ids))
789+
return -EINVAL;
790+
subsys->clear_ids = clear_ids;
791+
return count;
792+
}
793+
CONFIGFS_ATTR(nvmet_passthru_, clear_ids);
794+
776795
static struct configfs_attribute *nvmet_passthru_attrs[] = {
777796
&nvmet_passthru_attr_device_path,
778797
&nvmet_passthru_attr_enable,
779798
&nvmet_passthru_attr_admin_timeout,
780799
&nvmet_passthru_attr_io_timeout,
800+
&nvmet_passthru_attr_clear_ids,
781801
NULL,
782802
};
783803

drivers/nvme/target/core.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,12 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
13741374
ctrl->port = req->port;
13751375
ctrl->ops = req->ops;
13761376

1377+
#ifdef CONFIG_NVME_TARGET_PASSTHRU
1378+
/* By default, set loop targets to clear IDS by default */
1379+
if (ctrl->port->disc_addr.trtype == NVMF_TRTYPE_LOOP)
1380+
subsys->clear_ids = 1;
1381+
#endif
1382+
13771383
INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work);
13781384
INIT_LIST_HEAD(&ctrl->async_events);
13791385
INIT_RADIX_TREE(&ctrl->p2p_ns_map, GFP_KERNEL);

drivers/nvme/target/nvmet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ struct nvmet_subsys {
249249
struct config_group passthru_group;
250250
unsigned int admin_timeout;
251251
unsigned int io_timeout;
252+
unsigned int clear_ids;
252253
#endif /* CONFIG_NVME_TARGET_PASSTHRU */
253254

254255
#ifdef CONFIG_BLK_DEV_ZONED

drivers/nvme/target/passthru.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,53 @@ void nvmet_passthrough_override_cap(struct nvmet_ctrl *ctrl)
3030
ctrl->cap &= ~(1ULL << 43);
3131
}
3232

33+
static u16 nvmet_passthru_override_id_descs(struct nvmet_req *req)
34+
{
35+
struct nvmet_ctrl *ctrl = req->sq->ctrl;
36+
u16 status = NVME_SC_SUCCESS;
37+
int pos, len;
38+
bool csi_seen = false;
39+
void *data;
40+
u8 csi;
41+
42+
if (!ctrl->subsys->clear_ids)
43+
return status;
44+
45+
data = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
46+
if (!data)
47+
return NVME_SC_INTERNAL;
48+
49+
status = nvmet_copy_from_sgl(req, 0, data, NVME_IDENTIFY_DATA_SIZE);
50+
if (status)
51+
goto out_free;
52+
53+
for (pos = 0; pos < NVME_IDENTIFY_DATA_SIZE; pos += len) {
54+
struct nvme_ns_id_desc *cur = data + pos;
55+
56+
if (cur->nidl == 0)
57+
break;
58+
if (cur->nidt == NVME_NIDT_CSI) {
59+
memcpy(&csi, cur + 1, NVME_NIDT_CSI_LEN);
60+
csi_seen = true;
61+
break;
62+
}
63+
len = sizeof(struct nvme_ns_id_desc) + cur->nidl;
64+
}
65+
66+
memset(data, 0, NVME_IDENTIFY_DATA_SIZE);
67+
if (csi_seen) {
68+
struct nvme_ns_id_desc *cur = data;
69+
70+
cur->nidt = NVME_NIDT_CSI;
71+
cur->nidl = NVME_NIDT_CSI_LEN;
72+
memcpy(cur + 1, &csi, NVME_NIDT_CSI_LEN);
73+
}
74+
status = nvmet_copy_to_sgl(req, 0, data, NVME_IDENTIFY_DATA_SIZE);
75+
out_free:
76+
kfree(data);
77+
return status;
78+
}
79+
3380
static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req)
3481
{
3582
struct nvmet_ctrl *ctrl = req->sq->ctrl;
@@ -152,6 +199,11 @@ static u16 nvmet_passthru_override_id_ns(struct nvmet_req *req)
152199
*/
153200
id->mc = 0;
154201

202+
if (req->sq->ctrl->subsys->clear_ids) {
203+
memset(id->nguid, 0, NVME_NIDT_NGUID_LEN);
204+
memset(id->eui64, 0, NVME_NIDT_EUI64_LEN);
205+
}
206+
155207
status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id));
156208

157209
out_free:
@@ -176,6 +228,9 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w)
176228
case NVME_ID_CNS_NS:
177229
nvmet_passthru_override_id_ns(req);
178230
break;
231+
case NVME_ID_CNS_NS_DESC_LIST:
232+
nvmet_passthru_override_id_descs(req);
233+
break;
179234
}
180235
} else if (status < 0)
181236
status = NVME_SC_INTERNAL;

drivers/nvme/target/tcp.c

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -405,31 +405,14 @@ static int nvmet_tcp_map_data(struct nvmet_tcp_cmd *cmd)
405405
return NVME_SC_INTERNAL;
406406
}
407407

408-
static void nvmet_tcp_send_ddgst(struct ahash_request *hash,
408+
static void nvmet_tcp_calc_ddgst(struct ahash_request *hash,
409409
struct nvmet_tcp_cmd *cmd)
410410
{
411411
ahash_request_set_crypt(hash, cmd->req.sg,
412412
(void *)&cmd->exp_ddgst, cmd->req.transfer_len);
413413
crypto_ahash_digest(hash);
414414
}
415415

416-
static void nvmet_tcp_recv_ddgst(struct ahash_request *hash,
417-
struct nvmet_tcp_cmd *cmd)
418-
{
419-
struct scatterlist sg;
420-
struct kvec *iov;
421-
int i;
422-
423-
crypto_ahash_init(hash);
424-
for (i = 0, iov = cmd->iov; i < cmd->nr_mapped; i++, iov++) {
425-
sg_init_one(&sg, iov->iov_base, iov->iov_len);
426-
ahash_request_set_crypt(hash, &sg, NULL, iov->iov_len);
427-
crypto_ahash_update(hash);
428-
}
429-
ahash_request_set_crypt(hash, NULL, (void *)&cmd->exp_ddgst, 0);
430-
crypto_ahash_final(hash);
431-
}
432-
433416
static void nvmet_setup_c2h_data_pdu(struct nvmet_tcp_cmd *cmd)
434417
{
435418
struct nvme_tcp_data_pdu *pdu = cmd->data_pdu;
@@ -454,7 +437,7 @@ static void nvmet_setup_c2h_data_pdu(struct nvmet_tcp_cmd *cmd)
454437

455438
if (queue->data_digest) {
456439
pdu->hdr.flags |= NVME_TCP_F_DDGST;
457-
nvmet_tcp_send_ddgst(queue->snd_hash, cmd);
440+
nvmet_tcp_calc_ddgst(queue->snd_hash, cmd);
458441
}
459442

460443
if (cmd->queue->hdr_digest) {
@@ -1137,7 +1120,7 @@ static void nvmet_tcp_prep_recv_ddgst(struct nvmet_tcp_cmd *cmd)
11371120
{
11381121
struct nvmet_tcp_queue *queue = cmd->queue;
11391122

1140-
nvmet_tcp_recv_ddgst(queue->rcv_hash, cmd);
1123+
nvmet_tcp_calc_ddgst(queue->rcv_hash, cmd);
11411124
queue->offset = 0;
11421125
queue->left = NVME_TCP_DIGEST_LENGTH;
11431126
queue->rcv_state = NVMET_TCP_RECV_DDGST;

0 commit comments

Comments
 (0)