Pull block fixes from Jens Axboe: - Fix for batch getting of tags in sbitmap (wuchi) - NVMe pull request via Christoph: - 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 'block-5.19-2022-07-01' of git://git.kernel.dk/linux-block: 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 lib/sbitmap: Fix invalid loop in __sbitmap_queue_get_batch()
Unified · Split
| @@ -4595,6 +4595,8 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl) · 4594 unmodified lines | ||
| 4595 | 4595 | nvme_stop_failfast_work(ctrl); |
| 4596 | 4596 | flush_work(&ctrl->async_event_work); |
| 4597 | 4597 | cancel_work_sync(&ctrl->fw_act_work); |
| 4598 | + if (ctrl->ops->stop_ctrl) | |
| 4599 | + ctrl->ops->stop_ctrl(ctrl); | |
| 4598 | 4600 | } |
| 4599 | 4601 | EXPORT_SYMBOL_GPL(nvme_stop_ctrl); |
| 4600 | 4602 | |
| @@ -502,6 +502,7 @@ struct nvme_ctrl_ops { · 501 unmodified lines | ||
| 502 | 502 | void (*free_ctrl)(struct nvme_ctrl *ctrl); |
| 503 | 503 | void (*submit_async_event)(struct nvme_ctrl *ctrl); |
| 504 | 504 | void (*delete_ctrl)(struct nvme_ctrl *ctrl); |
| 505 | + void (*stop_ctrl)(struct nvme_ctrl *ctrl); | |
| 505 | 506 | int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); |
| 506 | 507 | void (*print_device_info)(struct nvme_ctrl *ctrl); |
| 507 | 508 | }; |
| @@ -3469,8 +3469,11 @@ static const struct pci_device_id nvme_id_table[] = { · 3468 unmodified lines | ||
| 3469 | 3469 | { PCI_DEVICE(0x1b4b, 0x1092), /* Lexar 256 GB SSD */ |
| 3470 | 3470 | .driver_data = NVME_QUIRK_NO_NS_DESC_LIST | |
| 3471 | 3471 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| 3472 | + { PCI_DEVICE(0x1cc1, 0x33f8), /* ADATA IM2P33F8ABR1 1 TB */ | |
| 3473 | + .driver_data = NVME_QUIRK_BOGUS_NID, }, | |
| 3472 | 3474 | { 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, }, | |
| 3474 | 3477 | { PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */ |
| 3475 | 3478 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS | |
| 3476 | 3479 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| @@ -1048,6 +1048,14 @@ static void nvme_rdma_teardown_io_queues(struct nvme_rdma_ctrl *ctrl, · 1047 unmodified lines | ||
| 1048 | 1048 | } |
| 1049 | 1049 | } |
| 1050 | 1050 | |
| 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 | + | |
| 1051 | 1059 | static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl) |
| 1052 | 1060 | { |
| 1053 | 1061 | struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl); |
| @@ -2252,9 +2260,6 @@ static const struct blk_mq_ops nvme_rdma_admin_mq_ops = { · 1198 unmodified lines | ||
| 2252 | 2260 | |
| 2253 | 2261 | static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown) |
| 2254 | 2262 | { |
| 2255 | − cancel_work_sync(&ctrl->err_work); | |
| 2256 | − cancel_delayed_work_sync(&ctrl->reconnect_work); | |
| 2257 | − | |
| 2258 | 2263 | nvme_rdma_teardown_io_queues(ctrl, shutdown); |
| 2259 | 2264 | nvme_stop_admin_queue(&ctrl->ctrl); |
| 2260 | 2265 | if (shutdown) |
| @@ -2304,6 +2309,7 @@ static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = { · 43 unmodified lines | ||
| 2304 | 2309 | .submit_async_event = nvme_rdma_submit_async_event, |
| 2305 | 2310 | .delete_ctrl = nvme_rdma_delete_ctrl, |
| 2306 | 2311 | .get_address = nvmf_get_address, |
| 2312 | + .stop_ctrl = nvme_rdma_stop_ctrl, | |
| 2307 | 2313 | }; |
| 2308 | 2314 | |
| 2309 | 2315 | /* |
| @@ -1180,8 +1180,7 @@ done: · 1179 unmodified lines | ||
| 1180 | 1180 | } else if (ret < 0) { |
| 1181 | 1181 | dev_err(queue->ctrl->ctrl.device, |
| 1182 | 1182 | "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); | |
| 1185 | 1184 | nvme_tcp_done_send_req(queue); |
| 1186 | 1185 | } |
| 1187 | 1186 | return ret; |
| @@ -2194,9 +2193,6 @@ static void nvme_tcp_error_recovery_work(struct work_struct *work) · 1006 unmodified lines | ||
| 2194 | 2193 | |
| 2195 | 2194 | static void nvme_tcp_teardown_ctrl(struct nvme_ctrl *ctrl, bool shutdown) |
| 2196 | 2195 | { |
| 2197 | − cancel_work_sync(&to_tcp_ctrl(ctrl)->err_work); | |
| 2198 | − cancel_delayed_work_sync(&to_tcp_ctrl(ctrl)->connect_work); | |
| 2199 | − | |
| 2200 | 2196 | nvme_tcp_teardown_io_queues(ctrl, shutdown); |
| 2201 | 2197 | nvme_stop_admin_queue(ctrl); |
| 2202 | 2198 | if (shutdown) |
| @@ -2236,6 +2232,12 @@ out_fail: · 33 unmodified lines | ||
| 2236 | 2232 | nvme_tcp_reconnect_or_remove(ctrl); |
| 2237 | 2233 | } |
| 2238 | 2234 | |
| 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 | + | |
| 2239 | 2241 | static void nvme_tcp_free_ctrl(struct nvme_ctrl *nctrl) |
| 2240 | 2242 | { |
| 2241 | 2243 | struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); |
| @@ -2557,6 +2559,7 @@ static const struct nvme_ctrl_ops nvme_tcp_ctrl_ops = { · 315 unmodified lines | ||
| 2557 | 2559 | .submit_async_event = nvme_tcp_submit_async_event, |
| 2558 | 2560 | .delete_ctrl = nvme_tcp_delete_ctrl, |
| 2559 | 2561 | .get_address = nvmf_get_address, |
| 2562 | + .stop_ctrl = nvme_tcp_stop_ctrl, | |
| 2560 | 2563 | }; |
| 2561 | 2564 | |
| 2562 | 2565 | static bool |
| @@ -773,11 +773,31 @@ static ssize_t nvmet_passthru_io_timeout_store(struct config_item *item, · 772 unmodified lines | ||
| 773 | 773 | } |
| 774 | 774 | CONFIGFS_ATTR(nvmet_passthru_, io_timeout); |
| 775 | 775 | |
| 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 | + | |
| 776 | 795 | static struct configfs_attribute *nvmet_passthru_attrs[] = { |
| 777 | 796 | &nvmet_passthru_attr_device_path, |
| 778 | 797 | &nvmet_passthru_attr_enable, |
| 779 | 798 | &nvmet_passthru_attr_admin_timeout, |
| 780 | 799 | &nvmet_passthru_attr_io_timeout, |
| 800 | + &nvmet_passthru_attr_clear_ids, | |
| 781 | 801 | NULL, |
| 782 | 802 | }; |
| 783 | 803 | |
| @@ -1374,6 +1374,12 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, · 1373 unmodified lines | ||
| 1374 | 1374 | ctrl->port = req->port; |
| 1375 | 1375 | ctrl->ops = req->ops; |
| 1376 | 1376 | |
| 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 | + | |
| 1377 | 1383 | INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); |
| 1378 | 1384 | INIT_LIST_HEAD(&ctrl->async_events); |
| 1379 | 1385 | INIT_RADIX_TREE(&ctrl->p2p_ns_map, GFP_KERNEL); |
| @@ -249,6 +249,7 @@ struct nvmet_subsys { · 248 unmodified lines | ||
| 249 | 249 | struct config_group passthru_group; |
| 250 | 250 | unsigned int admin_timeout; |
| 251 | 251 | unsigned int io_timeout; |
| 252 | + unsigned int clear_ids; | |
| 252 | 253 | #endif /* CONFIG_NVME_TARGET_PASSTHRU */ |
| 253 | 254 | |
| 254 | 255 | #ifdef CONFIG_BLK_DEV_ZONED |
| @@ -30,6 +30,53 @@ void nvmet_passthrough_override_cap(struct nvmet_ctrl *ctrl) · 29 unmodified lines | ||
| 30 | 30 | ctrl->cap &= ~(1ULL << 43); |
| 31 | 31 | } |
| 32 | 32 | |
| 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 | + | |
| 33 | 80 | static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req) |
| 34 | 81 | { |
| 35 | 82 | struct nvmet_ctrl *ctrl = req->sq->ctrl; |
| @@ -152,6 +199,11 @@ static u16 nvmet_passthru_override_id_ns(struct nvmet_req *req) · 116 unmodified lines | ||
| 152 | 199 | */ |
| 153 | 200 | id->mc = 0; |
| 154 | 201 | |
| 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 | + | |
| 155 | 207 | status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id)); |
| 156 | 208 | |
| 157 | 209 | out_free: |
| @@ -176,6 +228,9 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w) · 18 unmodified lines | ||
| 176 | 228 | case NVME_ID_CNS_NS: |
| 177 | 229 | nvmet_passthru_override_id_ns(req); |
| 178 | 230 | break; |
| 231 | + case NVME_ID_CNS_NS_DESC_LIST: | |
| 232 | + nvmet_passthru_override_id_descs(req); | |
| 233 | + break; | |
| 179 | 234 | } |
| 180 | 235 | } else if (status < 0) |
| 181 | 236 | status = NVME_SC_INTERNAL; |
| @@ -405,7 +405,7 @@ err: · 404 unmodified lines | ||
| 405 | 405 | return NVME_SC_INTERNAL; |
| 406 | 406 | } |
| 407 | 407 | |
| 408 | −static void nvmet_tcp_send_ddgst(struct ahash_request *hash, | |
| 408 | +static void nvmet_tcp_calc_ddgst(struct ahash_request *hash, | |
| 409 | 409 | struct nvmet_tcp_cmd *cmd) |
| 410 | 410 | { |
| 411 | 411 | ahash_request_set_crypt(hash, cmd->req.sg, |
| @@ -413,23 +413,6 @@ static void nvmet_tcp_send_ddgst(struct ahash_request *hash, · 1 unmodified line | ||
| 413 | 413 | crypto_ahash_digest(hash); |
| 414 | 414 | } |
| 415 | 415 | |
| 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 | − | |
| 433 | 416 | static void nvmet_setup_c2h_data_pdu(struct nvmet_tcp_cmd *cmd) |
| 434 | 417 | { |
| 435 | 418 | 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) · 18 unmodified lines | ||
| 454 | 437 | |
| 455 | 438 | if (queue->data_digest) { |
| 456 | 439 | 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); | |
| 458 | 441 | } |
| 459 | 442 | |
| 460 | 443 | if (cmd->queue->hdr_digest) { |
| @@ -1137,7 +1120,7 @@ static void nvmet_tcp_prep_recv_ddgst(struct nvmet_tcp_cmd *cmd) · 676 unmodified lines | ||
| 1137 | 1120 | { |
| 1138 | 1121 | struct nvmet_tcp_queue *queue = cmd->queue; |
| 1139 | 1122 | |
| 1140 | − nvmet_tcp_recv_ddgst(queue->rcv_hash, cmd); | |
| 1123 | + nvmet_tcp_calc_ddgst(queue->rcv_hash, cmd); | |
| 1141 | 1124 | queue->offset = 0; |
| 1142 | 1125 | queue->left = NVME_TCP_DIGEST_LENGTH; |
| 1143 | 1126 | queue->rcv_state = NVMET_TCP_RECV_DDGST; |
| @@ -528,7 +528,7 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags, · 527 unmodified lines | ||
| 528 | 528 | |
| 529 | 529 | sbitmap_deferred_clear(map); |
| 530 | 530 | if (map->word == (1UL << (map_depth - 1)) - 1) |
| 531 | − continue; | |
| 531 | + goto next; | |
| 532 | 532 | |
| 533 | 533 | nr = find_first_zero_bit(&map->word, map_depth); |
| 534 | 534 | if (nr + nr_tags <= map_depth) { |
| @@ -539,6 +539,8 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags, · 4 unmodified lines | ||
| 539 | 539 | get_mask = ((1UL << map_tags) - 1) << nr; |
| 540 | 540 | do { |
| 541 | 541 | val = READ_ONCE(map->word); |
| 542 | + if ((val & ~get_mask) != val) | |
| 543 | + goto next; | |
| 542 | 544 | ret = atomic_long_cmpxchg(ptr, val, get_mask | val); |
| 543 | 545 | } while (ret != val); |
| 544 | 546 | get_mask = (get_mask & ~ret) >> nr; |
| @@ -549,6 +551,7 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags, · 4 unmodified lines | ||
| 549 | 551 | return get_mask; |
| 550 | 552 | } |
| 551 | 553 | } |
| 554 | +next: | |
| 552 | 555 | /* Jump to next index. */ |
| 553 | 556 | if (++index >= sb->map_nr) |
| 554 | 557 | index = 0; |