diff options
| author | Jens Axboe <axboe@kernel.dk> | 2018-01-05 12:39:01 -0500 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2018-01-05 12:39:01 -0500 |
| commit | cbf3a95924d515c1883aec2322fec277e4726134 (patch) | |
| tree | 18acc054fb144802404920e700274b6e6b4e1d3a /drivers | |
| parent | 454be724f6f99cc7e7bbf15067128be9868186c6 (diff) | |
| parent | 254beb84faccbe2f4eda0b51924857bdfb679969 (diff) | |
Merge branch 'nvme-4.15' of git://git.infradead.org/nvme into for-linus
Pull a handful of NVMe fixes from Christoph that should go into 4.15.
Diffstat (limited to 'drivers')
| -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 |
5 files changed, 52 insertions, 25 deletions
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; |
