diff options
| -rw-r--r-- | block/blk-core.c | 9 | ||||
| -rw-r--r-- | block/blk-mq.c | 2 | ||||
| -rw-r--r-- | block/blk.h | 2 | ||||
| -rw-r--r-- | drivers/block/loop.c | 10 | ||||
| -rw-r--r-- | drivers/nvme/host/core.c | 7 | ||||
| -rw-r--r-- | drivers/nvme/host/nvme.h | 12 | ||||
| -rw-r--r-- | drivers/nvme/host/pci.c | 42 | ||||
| -rw-r--r-- | drivers/nvme/host/rdma.c | 14 | ||||
| -rw-r--r-- | drivers/nvme/target/fcloop.c | 2 |
9 files changed, 71 insertions, 29 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index b8881750a3ac..3ba4326a63b5 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
| @@ -562,6 +562,13 @@ static void __blk_drain_queue(struct request_queue *q, bool drain_all) | |||
| 562 | } | 562 | } |
| 563 | } | 563 | } |
| 564 | 564 | ||
| 565 | void blk_drain_queue(struct request_queue *q) | ||
| 566 | { | ||
| 567 | spin_lock_irq(q->queue_lock); | ||
| 568 | __blk_drain_queue(q, true); | ||
| 569 | spin_unlock_irq(q->queue_lock); | ||
| 570 | } | ||
| 571 | |||
| 565 | /** | 572 | /** |
| 566 | * blk_queue_bypass_start - enter queue bypass mode | 573 | * blk_queue_bypass_start - enter queue bypass mode |
| 567 | * @q: queue of interest | 574 | * @q: queue of interest |
| @@ -689,8 +696,6 @@ void blk_cleanup_queue(struct request_queue *q) | |||
| 689 | */ | 696 | */ |
| 690 | blk_freeze_queue(q); | 697 | blk_freeze_queue(q); |
| 691 | spin_lock_irq(lock); | 698 | spin_lock_irq(lock); |
| 692 | if (!q->mq_ops) | ||
| 693 | __blk_drain_queue(q, true); | ||
| 694 | queue_flag_set(QUEUE_FLAG_DEAD, q); | 699 | queue_flag_set(QUEUE_FLAG_DEAD, q); |
| 695 | spin_unlock_irq(lock); | 700 | spin_unlock_irq(lock); |
| 696 | 701 | ||
diff --git a/block/blk-mq.c b/block/blk-mq.c index 11097477eeab..3d3797327491 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -161,6 +161,8 @@ void blk_freeze_queue(struct request_queue *q) | |||
| 161 | * exported to drivers as the only user for unfreeze is blk_mq. | 161 | * exported to drivers as the only user for unfreeze is blk_mq. |
| 162 | */ | 162 | */ |
| 163 | blk_freeze_queue_start(q); | 163 | blk_freeze_queue_start(q); |
| 164 | if (!q->mq_ops) | ||
| 165 | blk_drain_queue(q); | ||
| 164 | blk_mq_freeze_queue_wait(q); | 166 | blk_mq_freeze_queue_wait(q); |
| 165 | } | 167 | } |
| 166 | 168 | ||
diff --git a/block/blk.h b/block/blk.h index 3f1446937aec..442098aa9463 100644 --- a/block/blk.h +++ b/block/blk.h | |||
| @@ -330,4 +330,6 @@ static inline void blk_queue_bounce(struct request_queue *q, struct bio **bio) | |||
| 330 | } | 330 | } |
| 331 | #endif /* CONFIG_BOUNCE */ | 331 | #endif /* CONFIG_BOUNCE */ |
| 332 | 332 | ||
| 333 | extern void blk_drain_queue(struct request_queue *q); | ||
| 334 | |||
| 333 | #endif /* BLK_INTERNAL_H */ | 335 | #endif /* BLK_INTERNAL_H */ |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index bc8e61506968..d5fe720cf149 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -1581,9 +1581,8 @@ out: | |||
| 1581 | return err; | 1581 | return err; |
| 1582 | } | 1582 | } |
| 1583 | 1583 | ||
| 1584 | static void lo_release(struct gendisk *disk, fmode_t mode) | 1584 | static void __lo_release(struct loop_device *lo) |
| 1585 | { | 1585 | { |
| 1586 | struct loop_device *lo = disk->private_data; | ||
| 1587 | int err; | 1586 | int err; |
| 1588 | 1587 | ||
| 1589 | if (atomic_dec_return(&lo->lo_refcnt)) | 1588 | if (atomic_dec_return(&lo->lo_refcnt)) |
| @@ -1610,6 +1609,13 @@ static void lo_release(struct gendisk *disk, fmode_t mode) | |||
| 1610 | mutex_unlock(&lo->lo_ctl_mutex); | 1609 | mutex_unlock(&lo->lo_ctl_mutex); |
| 1611 | } | 1610 | } |
| 1612 | 1611 | ||
| 1612 | static void lo_release(struct gendisk *disk, fmode_t mode) | ||
| 1613 | { | ||
| 1614 | mutex_lock(&loop_index_mutex); | ||
| 1615 | __lo_release(disk->private_data); | ||
| 1616 | mutex_unlock(&loop_index_mutex); | ||
| 1617 | } | ||
| 1618 | |||
| 1613 | static const struct block_device_operations lo_fops = { | 1619 | static const struct block_device_operations lo_fops = { |
| 1614 | .owner = THIS_MODULE, | 1620 | .owner = THIS_MODULE, |
| 1615 | .open = lo_open, | 1621 | .open = lo_open, |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 1e46e60b8f10..839650e0926a 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
| @@ -1335,6 +1335,7 @@ static void nvme_update_disk_info(struct gendisk *disk, | |||
| 1335 | struct nvme_ns *ns, struct nvme_id_ns *id) | 1335 | struct nvme_ns *ns, struct nvme_id_ns *id) |
| 1336 | { | 1336 | { |
| 1337 | sector_t capacity = le64_to_cpup(&id->nsze) << (ns->lba_shift - 9); | 1337 | sector_t capacity = le64_to_cpup(&id->nsze) << (ns->lba_shift - 9); |
| 1338 | unsigned short bs = 1 << ns->lba_shift; | ||
| 1338 | unsigned stream_alignment = 0; | 1339 | unsigned stream_alignment = 0; |
| 1339 | 1340 | ||
| 1340 | if (ns->ctrl->nr_streams && ns->sws && ns->sgs) | 1341 | if (ns->ctrl->nr_streams && ns->sws && ns->sgs) |
| @@ -1343,7 +1344,10 @@ static void nvme_update_disk_info(struct gendisk *disk, | |||
| 1343 | blk_mq_freeze_queue(disk->queue); | 1344 | blk_mq_freeze_queue(disk->queue); |
| 1344 | blk_integrity_unregister(disk); | 1345 | blk_integrity_unregister(disk); |
| 1345 | 1346 | ||
| 1346 | blk_queue_logical_block_size(disk->queue, 1 << ns->lba_shift); | 1347 | blk_queue_logical_block_size(disk->queue, bs); |
| 1348 | blk_queue_physical_block_size(disk->queue, bs); | ||
| 1349 | blk_queue_io_min(disk->queue, bs); | ||
| 1350 | |||
| 1347 | if (ns->ms && !ns->ext && | 1351 | if (ns->ms && !ns->ext && |
| 1348 | (ns->ctrl->ops->flags & NVME_F_METADATA_SUPPORTED)) | 1352 | (ns->ctrl->ops->flags & NVME_F_METADATA_SUPPORTED)) |
| 1349 | nvme_init_integrity(disk, ns->ms, ns->pi_type); | 1353 | nvme_init_integrity(disk, ns->ms, ns->pi_type); |
| @@ -2987,6 +2991,7 @@ static void nvme_ns_remove(struct nvme_ns *ns) | |||
| 2987 | mutex_unlock(&ns->ctrl->namespaces_mutex); | 2991 | mutex_unlock(&ns->ctrl->namespaces_mutex); |
| 2988 | 2992 | ||
| 2989 | synchronize_srcu(&ns->head->srcu); | 2993 | synchronize_srcu(&ns->head->srcu); |
| 2994 | nvme_mpath_check_last_path(ns); | ||
| 2990 | nvme_put_ns(ns); | 2995 | nvme_put_ns(ns); |
| 2991 | } | 2996 | } |
| 2992 | 2997 | ||
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index ea1aa5283e8e..a00eabd06427 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h | |||
| @@ -417,6 +417,15 @@ static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) | |||
| 417 | rcu_assign_pointer(head->current_path, NULL); | 417 | rcu_assign_pointer(head->current_path, NULL); |
| 418 | } | 418 | } |
| 419 | struct nvme_ns *nvme_find_path(struct nvme_ns_head *head); | 419 | struct nvme_ns *nvme_find_path(struct nvme_ns_head *head); |
| 420 | |||
| 421 | static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) | ||
| 422 | { | ||
| 423 | struct nvme_ns_head *head = ns->head; | ||
| 424 | |||
| 425 | if (head->disk && list_empty(&head->list)) | ||
| 426 | kblockd_schedule_work(&head->requeue_work); | ||
| 427 | } | ||
| 428 | |||
| 420 | #else | 429 | #else |
| 421 | static inline void nvme_failover_req(struct request *req) | 430 | static inline void nvme_failover_req(struct request *req) |
| 422 | { | 431 | { |
| @@ -448,6 +457,9 @@ static inline void nvme_mpath_remove_disk_links(struct nvme_ns *ns) | |||
| 448 | static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) | 457 | static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) |
| 449 | { | 458 | { |
| 450 | } | 459 | } |
| 460 | static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) | ||
| 461 | { | ||
| 462 | } | ||
| 451 | #endif /* CONFIG_NVME_MULTIPATH */ | 463 | #endif /* CONFIG_NVME_MULTIPATH */ |
| 452 | 464 | ||
| 453 | #ifdef CONFIG_NVM | 465 | #ifdef CONFIG_NVM |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index f5800c3c9082..d53550e612bc 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
| @@ -448,12 +448,31 @@ static void **nvme_pci_iod_list(struct request *req) | |||
| 448 | return (void **)(iod->sg + blk_rq_nr_phys_segments(req)); | 448 | return (void **)(iod->sg + blk_rq_nr_phys_segments(req)); |
| 449 | } | 449 | } |
| 450 | 450 | ||
| 451 | static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req) | ||
| 452 | { | ||
| 453 | struct nvme_iod *iod = blk_mq_rq_to_pdu(req); | ||
| 454 | unsigned int avg_seg_size; | ||
| 455 | |||
| 456 | avg_seg_size = DIV_ROUND_UP(blk_rq_payload_bytes(req), | ||
| 457 | blk_rq_nr_phys_segments(req)); | ||
| 458 | |||
| 459 | if (!(dev->ctrl.sgls & ((1 << 0) | (1 << 1)))) | ||
| 460 | return false; | ||
| 461 | if (!iod->nvmeq->qid) | ||
| 462 | return false; | ||
| 463 | if (!sgl_threshold || avg_seg_size < sgl_threshold) | ||
| 464 | return false; | ||
| 465 | return true; | ||
| 466 | } | ||
| 467 | |||
| 451 | static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev) | 468 | static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev) |
| 452 | { | 469 | { |
| 453 | struct nvme_iod *iod = blk_mq_rq_to_pdu(rq); | 470 | struct nvme_iod *iod = blk_mq_rq_to_pdu(rq); |
| 454 | int nseg = blk_rq_nr_phys_segments(rq); | 471 | int nseg = blk_rq_nr_phys_segments(rq); |
| 455 | unsigned int size = blk_rq_payload_bytes(rq); | 472 | unsigned int size = blk_rq_payload_bytes(rq); |
| 456 | 473 | ||
| 474 | iod->use_sgl = nvme_pci_use_sgls(dev, rq); | ||
| 475 | |||
| 457 | if (nseg > NVME_INT_PAGES || size > NVME_INT_BYTES(dev)) { | 476 | if (nseg > NVME_INT_PAGES || size > NVME_INT_BYTES(dev)) { |
| 458 | size_t alloc_size = nvme_pci_iod_alloc_size(dev, size, nseg, | 477 | size_t alloc_size = nvme_pci_iod_alloc_size(dev, size, nseg, |
| 459 | iod->use_sgl); | 478 | iod->use_sgl); |
| @@ -604,8 +623,6 @@ static blk_status_t nvme_pci_setup_prps(struct nvme_dev *dev, | |||
| 604 | dma_addr_t prp_dma; | 623 | dma_addr_t prp_dma; |
| 605 | int nprps, i; | 624 | int nprps, i; |
| 606 | 625 | ||
| 607 | iod->use_sgl = false; | ||
| 608 | |||
| 609 | length -= (page_size - offset); | 626 | length -= (page_size - offset); |
| 610 | if (length <= 0) { | 627 | if (length <= 0) { |
| 611 | iod->first_dma = 0; | 628 | iod->first_dma = 0; |
| @@ -715,8 +732,6 @@ static blk_status_t nvme_pci_setup_sgls(struct nvme_dev *dev, | |||
| 715 | int entries = iod->nents, i = 0; | 732 | int entries = iod->nents, i = 0; |
| 716 | dma_addr_t sgl_dma; | 733 | dma_addr_t sgl_dma; |
| 717 | 734 | ||
| 718 | iod->use_sgl = true; | ||
| 719 | |||
| 720 | /* setting the transfer type as SGL */ | 735 | /* setting the transfer type as SGL */ |
| 721 | cmd->flags = NVME_CMD_SGL_METABUF; | 736 | cmd->flags = NVME_CMD_SGL_METABUF; |
| 722 | 737 | ||
| @@ -770,23 +785,6 @@ static blk_status_t nvme_pci_setup_sgls(struct nvme_dev *dev, | |||
| 770 | return BLK_STS_OK; | 785 | return BLK_STS_OK; |
| 771 | } | 786 | } |
| 772 | 787 | ||
| 773 | static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req) | ||
| 774 | { | ||
| 775 | struct nvme_iod *iod = blk_mq_rq_to_pdu(req); | ||
| 776 | unsigned int avg_seg_size; | ||
| 777 | |||
| 778 | avg_seg_size = DIV_ROUND_UP(blk_rq_payload_bytes(req), | ||
| 779 | blk_rq_nr_phys_segments(req)); | ||
| 780 | |||
| 781 | if (!(dev->ctrl.sgls & ((1 << 0) | (1 << 1)))) | ||
| 782 | return false; | ||
| 783 | if (!iod->nvmeq->qid) | ||
| 784 | return false; | ||
| 785 | if (!sgl_threshold || avg_seg_size < sgl_threshold) | ||
| 786 | return false; | ||
| 787 | return true; | ||
| 788 | } | ||
| 789 | |||
| 790 | static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, | 788 | static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, |
| 791 | struct nvme_command *cmnd) | 789 | struct nvme_command *cmnd) |
| 792 | { | 790 | { |
| @@ -806,7 +804,7 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, | |||
| 806 | DMA_ATTR_NO_WARN)) | 804 | DMA_ATTR_NO_WARN)) |
| 807 | goto out; | 805 | goto out; |
| 808 | 806 | ||
| 809 | if (nvme_pci_use_sgls(dev, req)) | 807 | if (iod->use_sgl) |
| 810 | ret = nvme_pci_setup_sgls(dev, req, &cmnd->rw); | 808 | ret = nvme_pci_setup_sgls(dev, req, &cmnd->rw); |
| 811 | else | 809 | else |
| 812 | ret = nvme_pci_setup_prps(dev, req, &cmnd->rw); | 810 | ret = nvme_pci_setup_prps(dev, req, &cmnd->rw); |
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 37af56596be6..2a0bba7f50cf 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c | |||
| @@ -974,12 +974,18 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work) | |||
| 974 | blk_mq_unquiesce_queue(ctrl->ctrl.admin_q); | 974 | blk_mq_unquiesce_queue(ctrl->ctrl.admin_q); |
| 975 | nvme_start_queues(&ctrl->ctrl); | 975 | nvme_start_queues(&ctrl->ctrl); |
| 976 | 976 | ||
| 977 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) { | ||
| 978 | /* state change failure should never happen */ | ||
| 979 | WARN_ON_ONCE(1); | ||
| 980 | return; | ||
| 981 | } | ||
| 982 | |||
| 977 | nvme_rdma_reconnect_or_remove(ctrl); | 983 | nvme_rdma_reconnect_or_remove(ctrl); |
| 978 | } | 984 | } |
| 979 | 985 | ||
| 980 | static void nvme_rdma_error_recovery(struct nvme_rdma_ctrl *ctrl) | 986 | static void nvme_rdma_error_recovery(struct nvme_rdma_ctrl *ctrl) |
| 981 | { | 987 | { |
| 982 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) | 988 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING)) |
| 983 | return; | 989 | return; |
| 984 | 990 | ||
| 985 | queue_work(nvme_wq, &ctrl->err_work); | 991 | queue_work(nvme_wq, &ctrl->err_work); |
| @@ -1753,6 +1759,12 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work) | |||
| 1753 | nvme_stop_ctrl(&ctrl->ctrl); | 1759 | nvme_stop_ctrl(&ctrl->ctrl); |
| 1754 | nvme_rdma_shutdown_ctrl(ctrl, false); | 1760 | nvme_rdma_shutdown_ctrl(ctrl, false); |
| 1755 | 1761 | ||
| 1762 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) { | ||
| 1763 | /* state change failure should never happen */ | ||
| 1764 | WARN_ON_ONCE(1); | ||
| 1765 | return; | ||
| 1766 | } | ||
| 1767 | |||
| 1756 | ret = nvme_rdma_configure_admin_queue(ctrl, false); | 1768 | ret = nvme_rdma_configure_admin_queue(ctrl, false); |
| 1757 | if (ret) | 1769 | if (ret) |
| 1758 | goto out_fail; | 1770 | goto out_fail; |
diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c index 7b75d9de55ab..6a018a0bd6ce 100644 --- a/drivers/nvme/target/fcloop.c +++ b/drivers/nvme/target/fcloop.c | |||
| @@ -1085,7 +1085,7 @@ fcloop_delete_target_port(struct device *dev, struct device_attribute *attr, | |||
| 1085 | const char *buf, size_t count) | 1085 | const char *buf, size_t count) |
| 1086 | { | 1086 | { |
| 1087 | struct fcloop_nport *nport = NULL, *tmpport; | 1087 | struct fcloop_nport *nport = NULL, *tmpport; |
| 1088 | struct fcloop_tport *tport; | 1088 | struct fcloop_tport *tport = NULL; |
| 1089 | u64 nodename, portname; | 1089 | u64 nodename, portname; |
| 1090 | unsigned long flags; | 1090 | unsigned long flags; |
| 1091 | int ret; | 1091 | int ret; |
