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 | nvme_stop_failfast_work(ctrl); | 4595 | nvme_stop_failfast_work(ctrl); |
| 4596 | flush_work(&ctrl->async_event_work); | 4596 | flush_work(&ctrl->async_event_work); |
| 4597 | cancel_work_sync(&ctrl->fw_act_work); | 4597 | cancel_work_sync(&ctrl->fw_act_work); |
| 4598 | if (ctrl->ops->stop_ctrl) | ||
| 4599 | ctrl->ops->stop_ctrl(ctrl); | ||
| 4598 | } | 4600 | } |
| 4599 | EXPORT_SYMBOL_GPL(nvme_stop_ctrl); | 4601 | EXPORT_SYMBOL_GPL(nvme_stop_ctrl); |
| 4600 | 4602 | ||
| @@ -502,6 +502,7 @@ struct nvme_ctrl_ops { · 501 unmodified lines | |||
| 502 | void (*free_ctrl)(struct nvme_ctrl *ctrl); | 502 | void (*free_ctrl)(struct nvme_ctrl *ctrl); |
| 503 | void (*submit_async_event)(struct nvme_ctrl *ctrl); | 503 | void (*submit_async_event)(struct nvme_ctrl *ctrl); |
| 504 | void (*delete_ctrl)(struct nvme_ctrl *ctrl); | 504 | void (*delete_ctrl)(struct nvme_ctrl *ctrl); |
| 505 | void (*stop_ctrl)(struct nvme_ctrl *ctrl); | ||
| 505 | int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); | 506 | int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); |
| 506 | void (*print_device_info)(struct nvme_ctrl *ctrl); | 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 | { PCI_DEVICE(0x1b4b, 0x1092), /* Lexar 256 GB SSD */ | 3469 | { PCI_DEVICE(0x1b4b, 0x1092), /* Lexar 256 GB SSD */ |
| 3470 | .driver_data = NVME_QUIRK_NO_NS_DESC_LIST | | 3470 | .driver_data = NVME_QUIRK_NO_NS_DESC_LIST | |
| 3471 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | 3471 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| 3472 | { PCI_DEVICE(0x1cc1, 0x33f8), /* ADATA IM2P33F8ABR1 1 TB */ | ||
| 3473 | .driver_data = NVME_QUIRK_BOGUS_NID, }, | ||
| 3472 | { PCI_DEVICE(0x10ec, 0x5762), /* ADATA SX6000LNP */ | 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 | { PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */ | 3477 | { PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */ |
| 3475 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS | | 3478 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS | |
| 3476 | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | 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 | static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl) | 1059 | static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl) |
| 1052 | { | 1060 | { |
| 1053 | struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl); | 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 | static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown) | 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 | nvme_rdma_teardown_io_queues(ctrl, shutdown); | 2263 | nvme_rdma_teardown_io_queues(ctrl, shutdown); |
| 2259 | nvme_stop_admin_queue(&ctrl->ctrl); | 2264 | nvme_stop_admin_queue(&ctrl->ctrl); |
| 2260 | if (shutdown) | 2265 | if (shutdown) |
| @@ -2304,6 +2309,7 @@ static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = { · 43 unmodified lines | |||
| 2304 | .submit_async_event = nvme_rdma_submit_async_event, | 2309 | .submit_async_event = nvme_rdma_submit_async_event, |
| 2305 | .delete_ctrl = nvme_rdma_delete_ctrl, | 2310 | .delete_ctrl = nvme_rdma_delete_ctrl, |
| 2306 | .get_address = nvmf_get_address, | 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 | } else if (ret < 0) { | 1180 | } else if (ret < 0) { |
| 1181 | dev_err(queue->ctrl->ctrl.device, | 1181 | dev_err(queue->ctrl->ctrl.device, |
| 1182 | "failed to send request %d\n", ret); | 1182 | "failed to send request %d\n", ret); |
| 1183 | if (ret != -EPIPE && ret != -ECONNRESET) | 1183 | nvme_tcp_fail_request(queue->request); |
| 1184 | nvme_tcp_fail_request(queue->request); | ||
| 1185 | nvme_tcp_done_send_req(queue); | 1184 | nvme_tcp_done_send_req(queue); |
| 1186 | } | 1185 | } |
| 1187 | return ret; | 1186 | return ret; |
| @@ -2194,9 +2193,6 @@ static void nvme_tcp_error_recovery_work(struct work_struct *work) · 1006 unmodified lines | |||
| 2194 | 2193 | ||
| 2195 | static void nvme_tcp_teardown_ctrl(struct nvme_ctrl *ctrl, bool shutdown) | 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 | nvme_tcp_teardown_io_queues(ctrl, shutdown); | 2196 | nvme_tcp_teardown_io_queues(ctrl, shutdown); |
| 2201 | nvme_stop_admin_queue(ctrl); | 2197 | nvme_stop_admin_queue(ctrl); |
| 2202 | if (shutdown) | 2198 | if (shutdown) |
| @@ -2236,6 +2232,12 @@ out_fail: · 33 unmodified lines | |||
| 2236 | nvme_tcp_reconnect_or_remove(ctrl); | 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 | static void nvme_tcp_free_ctrl(struct nvme_ctrl *nctrl) | 2241 | static void nvme_tcp_free_ctrl(struct nvme_ctrl *nctrl) |
| 2240 | { | 2242 | { |
| 2241 | struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); | 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 | .submit_async_event = nvme_tcp_submit_async_event, | 2559 | .submit_async_event = nvme_tcp_submit_async_event, |
| 2558 | .delete_ctrl = nvme_tcp_delete_ctrl, | 2560 | .delete_ctrl = nvme_tcp_delete_ctrl, |
| 2559 | .get_address = nvmf_get_address, | 2561 | .get_address = nvmf_get_address, |
| 2562 | .stop_ctrl = nvme_tcp_stop_ctrl, | ||
| 2560 | }; | 2563 | }; |
| 2561 | 2564 | ||
| 2562 | static bool | 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 | CONFIGFS_ATTR(nvmet_passthru_, io_timeout); | 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 | static struct configfs_attribute *nvmet_passthru_attrs[] = { | 795 | static struct configfs_attribute *nvmet_passthru_attrs[] = { |
| 777 | &nvmet_passthru_attr_device_path, | 796 | &nvmet_passthru_attr_device_path, |
| 778 | &nvmet_passthru_attr_enable, | 797 | &nvmet_passthru_attr_enable, |
| 779 | &nvmet_passthru_attr_admin_timeout, | 798 | &nvmet_passthru_attr_admin_timeout, |
| 780 | &nvmet_passthru_attr_io_timeout, | 799 | &nvmet_passthru_attr_io_timeout, |
| 800 | &nvmet_passthru_attr_clear_ids, | ||
| 781 | NULL, | 801 | NULL, |
| 782 | }; | 802 | }; |
| 783 | 803 | ||
| @@ -1374,6 +1374,12 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, · 1373 unmodified lines | |||
| 1374 | ctrl->port = req->port; | 1374 | ctrl->port = req->port; |
| 1375 | ctrl->ops = req->ops; | 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 | INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); | 1383 | INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); |
| 1378 | INIT_LIST_HEAD(&ctrl->async_events); | 1384 | INIT_LIST_HEAD(&ctrl->async_events); |
| 1379 | INIT_RADIX_TREE(&ctrl->p2p_ns_map, GFP_KERNEL); | 1385 | INIT_RADIX_TREE(&ctrl->p2p_ns_map, GFP_KERNEL); |
| @@ -249,6 +249,7 @@ struct nvmet_subsys { · 248 unmodified lines | |||
| 249 | struct config_group passthru_group; | 249 | struct config_group passthru_group; |
| 250 | unsigned int admin_timeout; | 250 | unsigned int admin_timeout; |
| 251 | unsigned int io_timeout; | 251 | unsigned int io_timeout; |
| 252 | unsigned int clear_ids; | ||
| 252 | #endif /* CONFIG_NVME_TARGET_PASSTHRU */ | 253 | #endif /* CONFIG_NVME_TARGET_PASSTHRU */ |
| 253 | 254 | ||
| 254 | #ifdef CONFIG_BLK_DEV_ZONED | 255 | #ifdef CONFIG_BLK_DEV_ZONED |
| @@ -30,6 +30,53 @@ void nvmet_passthrough_override_cap(struct nvmet_ctrl *ctrl) · 29 unmodified lines | |||
| 30 | ctrl->cap &= ~(1ULL << 43); | 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 | static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req) | 80 | static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req) |
| 34 | { | 81 | { |
| 35 | struct nvmet_ctrl *ctrl = req->sq->ctrl; | 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 | id->mc = 0; | 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 | status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id)); | 207 | status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id)); |
| 156 | 208 | ||
| 157 | out_free: | 209 | out_free: |
| @@ -176,6 +228,9 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w) · 18 unmodified lines | |||
| 176 | case NVME_ID_CNS_NS: | 228 | case NVME_ID_CNS_NS: |
| 177 | nvmet_passthru_override_id_ns(req); | 229 | nvmet_passthru_override_id_ns(req); |
| 178 | break; | 230 | break; |
| 231 | case NVME_ID_CNS_NS_DESC_LIST: | ||
| 232 | nvmet_passthru_override_id_descs(req); | ||
| 233 | break; | ||
| 179 | } | 234 | } |
| 180 | } else if (status < 0) | 235 | } else if (status < 0) |
| 181 | status = NVME_SC_INTERNAL; | 236 | status = NVME_SC_INTERNAL; |
| @@ -405,7 +405,7 @@ err: · 404 unmodified lines | |||
| 405 | return NVME_SC_INTERNAL; | 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 | struct nvmet_tcp_cmd *cmd) | 409 | struct nvmet_tcp_cmd *cmd) |
| 410 | { | 410 | { |
| 411 | ahash_request_set_crypt(hash, cmd->req.sg, | 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 | crypto_ahash_digest(hash); | 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 | static void nvmet_setup_c2h_data_pdu(struct nvmet_tcp_cmd *cmd) | 416 | static void nvmet_setup_c2h_data_pdu(struct nvmet_tcp_cmd *cmd) |
| 434 | { | 417 | { |
| 435 | struct nvme_tcp_data_pdu *pdu = cmd->data_pdu; | 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 | if (queue->data_digest) { | 438 | if (queue->data_digest) { |
| 456 | pdu->hdr.flags |= NVME_TCP_F_DDGST; | 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 | if (cmd->queue->hdr_digest) { | 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 | struct nvmet_tcp_queue *queue = cmd->queue; | 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 | queue->offset = 0; | 1124 | queue->offset = 0; |
| 1142 | queue->left = NVME_TCP_DIGEST_LENGTH; | 1125 | queue->left = NVME_TCP_DIGEST_LENGTH; |
| 1143 | queue->rcv_state = NVMET_TCP_RECV_DDGST; | 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 | sbitmap_deferred_clear(map); | 529 | sbitmap_deferred_clear(map); |
| 530 | if (map->word == (1UL << (map_depth - 1)) - 1) | 530 | if (map->word == (1UL << (map_depth - 1)) - 1) |
| 531 | continue; | 531 | goto next; |
| 532 | 532 | ||
| 533 | nr = find_first_zero_bit(&map->word, map_depth); | 533 | nr = find_first_zero_bit(&map->word, map_depth); |
| 534 | if (nr + nr_tags <= map_depth) { | 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 | get_mask = ((1UL << map_tags) - 1) << nr; | 539 | get_mask = ((1UL << map_tags) - 1) << nr; |
| 540 | do { | 540 | do { |
| 541 | val = READ_ONCE(map->word); | 541 | val = READ_ONCE(map->word); |
| 542 | if ((val & ~get_mask) != val) | ||
| 543 | goto next; | ||
| 542 | ret = atomic_long_cmpxchg(ptr, val, get_mask | val); | 544 | ret = atomic_long_cmpxchg(ptr, val, get_mask | val); |
| 543 | } while (ret != val); | 545 | } while (ret != val); |
| 544 | get_mask = (get_mask & ~ret) >> nr; | 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 | return get_mask; | 551 | return get_mask; |
| 550 | } | 552 | } |
| 551 | } | 553 | } |
| 554 | next: | ||
| 552 | /* Jump to next index. */ | 555 | /* Jump to next index. */ |
| 553 | if (++index >= sb->map_nr) | 556 | if (++index >= sb->map_nr) |
| 554 | index = 0; | 557 | index = 0; |