diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-13 12:56:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-13 12:56:45 -0400 |
commit | a1e210331bbc69511898cd46dd09625ddeee5af8 (patch) | |
tree | b4c9e1074d35c92e37c47398a873ca0c77bedfc4 | |
parent | f31494bd05b06b0cdb4da6aebe92eaafab970df6 (diff) | |
parent | 1ea049b2de5d803374fdbf43add23c8d1c518e7b (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe:
- an NVMe fix from Gabriel, fixing a suspend/resume issue on some
setups
- addition of a few missing entries in the block queue sysfs
documentation, from Joe
- a fix for a sparse shadow warning for the bvec iterator, from
Johannes
- a writeback deadlock involving raid issuing barriers, and not
flushing the plug when we wakeup the flusher threads. From
Konstantin
- a set of patches for the NVMe target/loop/rdma code, from Roland and
Sagi
* 'for-linus' of git://git.kernel.dk/linux-block:
bvec: avoid variable shadowing warning
doc: update block/queue-sysfs.txt entries
nvme: Suspend all queues before deletion
mm, writeback: flush plugged IO in wakeup_flusher_threads()
nvme-rdma: Remove unused includes
nvme-rdma: start async event handler after reconnecting to a controller
nvmet: Fix controller serial number inconsistency
nvmet-rdma: Don't use the inline buffer in order to avoid allocation for small reads
nvmet-rdma: Correctly handle RDMA device hot removal
nvme-rdma: Make sure to shutdown the controller if we can
nvme-loop: Remove duplicate call to nvme_remove_namespaces
nvme-rdma: Free the I/O tags when we delete the controller
nvme-rdma: Remove duplicate call to nvme_remove_namespaces
nvme-rdma: Fix device removal handling
nvme-rdma: Queue ns scanning after a sucessful reconnection
nvme-rdma: Don't leak uninitialized memory in connect request private data
-rw-r--r-- | Documentation/block/queue-sysfs.txt | 18 | ||||
-rw-r--r-- | drivers/nvme/host/pci.c | 20 | ||||
-rw-r--r-- | drivers/nvme/host/rdma.c | 83 | ||||
-rw-r--r-- | drivers/nvme/target/admin-cmd.c | 6 | ||||
-rw-r--r-- | drivers/nvme/target/core.c | 4 | ||||
-rw-r--r-- | drivers/nvme/target/loop.c | 4 | ||||
-rw-r--r-- | drivers/nvme/target/nvmet.h | 1 | ||||
-rw-r--r-- | drivers/nvme/target/rdma.c | 100 | ||||
-rw-r--r-- | fs/fs-writeback.c | 6 | ||||
-rw-r--r-- | include/linux/bvec.h | 3 |
10 files changed, 160 insertions, 85 deletions
diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt index d515d58962b9..2a3904030dea 100644 --- a/Documentation/block/queue-sysfs.txt +++ b/Documentation/block/queue-sysfs.txt | |||
@@ -14,6 +14,12 @@ add_random (RW) | |||
14 | This file allows to turn off the disk entropy contribution. Default | 14 | This file allows to turn off the disk entropy contribution. Default |
15 | value of this file is '1'(on). | 15 | value of this file is '1'(on). |
16 | 16 | ||
17 | dax (RO) | ||
18 | -------- | ||
19 | This file indicates whether the device supports Direct Access (DAX), | ||
20 | used by CPU-addressable storage to bypass the pagecache. It shows '1' | ||
21 | if true, '0' if not. | ||
22 | |||
17 | discard_granularity (RO) | 23 | discard_granularity (RO) |
18 | ----------------------- | 24 | ----------------------- |
19 | This shows the size of internal allocation of the device in bytes, if | 25 | This shows the size of internal allocation of the device in bytes, if |
@@ -46,6 +52,12 @@ hw_sector_size (RO) | |||
46 | ------------------- | 52 | ------------------- |
47 | This is the hardware sector size of the device, in bytes. | 53 | This is the hardware sector size of the device, in bytes. |
48 | 54 | ||
55 | io_poll (RW) | ||
56 | ------------ | ||
57 | When read, this file shows the total number of block IO polls and how | ||
58 | many returned success. Writing '0' to this file will disable polling | ||
59 | for this device. Writing any non-zero value will enable this feature. | ||
60 | |||
49 | iostats (RW) | 61 | iostats (RW) |
50 | ------------- | 62 | ------------- |
51 | This file is used to control (on/off) the iostats accounting of the | 63 | This file is used to control (on/off) the iostats accounting of the |
@@ -151,5 +163,11 @@ device state. This means that it might not be safe to toggle the | |||
151 | setting from "write back" to "write through", since that will also | 163 | setting from "write back" to "write through", since that will also |
152 | eliminate cache flushes issued by the kernel. | 164 | eliminate cache flushes issued by the kernel. |
153 | 165 | ||
166 | write_same_max_bytes (RO) | ||
167 | ------------------------- | ||
168 | This is the number of bytes the device can write in a single write-same | ||
169 | command. A value of '0' means write-same is not supported by this | ||
170 | device. | ||
171 | |||
154 | 172 | ||
155 | Jens Axboe <jens.axboe@oracle.com>, February 2009 | 173 | Jens Axboe <jens.axboe@oracle.com>, February 2009 |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index d7c33f9361aa..8dcf5a960951 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
@@ -1543,15 +1543,10 @@ static void nvme_disable_io_queues(struct nvme_dev *dev) | |||
1543 | reinit_completion(&dev->ioq_wait); | 1543 | reinit_completion(&dev->ioq_wait); |
1544 | retry: | 1544 | retry: |
1545 | timeout = ADMIN_TIMEOUT; | 1545 | timeout = ADMIN_TIMEOUT; |
1546 | for (; i > 0; i--) { | 1546 | for (; i > 0; i--, sent++) |
1547 | struct nvme_queue *nvmeq = dev->queues[i]; | 1547 | if (nvme_delete_queue(dev->queues[i], opcode)) |
1548 | |||
1549 | if (!pass) | ||
1550 | nvme_suspend_queue(nvmeq); | ||
1551 | if (nvme_delete_queue(nvmeq, opcode)) | ||
1552 | break; | 1548 | break; |
1553 | ++sent; | 1549 | |
1554 | } | ||
1555 | while (sent--) { | 1550 | while (sent--) { |
1556 | timeout = wait_for_completion_io_timeout(&dev->ioq_wait, timeout); | 1551 | timeout = wait_for_completion_io_timeout(&dev->ioq_wait, timeout); |
1557 | if (timeout == 0) | 1552 | if (timeout == 0) |
@@ -1693,11 +1688,12 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) | |||
1693 | nvme_stop_queues(&dev->ctrl); | 1688 | nvme_stop_queues(&dev->ctrl); |
1694 | csts = readl(dev->bar + NVME_REG_CSTS); | 1689 | csts = readl(dev->bar + NVME_REG_CSTS); |
1695 | } | 1690 | } |
1691 | |||
1692 | for (i = dev->queue_count - 1; i > 0; i--) | ||
1693 | nvme_suspend_queue(dev->queues[i]); | ||
1694 | |||
1696 | if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { | 1695 | if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { |
1697 | for (i = dev->queue_count - 1; i >= 0; i--) { | 1696 | nvme_suspend_queue(dev->queues[0]); |
1698 | struct nvme_queue *nvmeq = dev->queues[i]; | ||
1699 | nvme_suspend_queue(nvmeq); | ||
1700 | } | ||
1701 | } else { | 1697 | } else { |
1702 | nvme_disable_io_queues(dev); | 1698 | nvme_disable_io_queues(dev); |
1703 | nvme_disable_admin_queue(dev, shutdown); | 1699 | nvme_disable_admin_queue(dev, shutdown); |
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 3e3ce2b0424e..8d2875b4c56d 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c | |||
@@ -12,13 +12,11 @@ | |||
12 | * more details. | 12 | * more details. |
13 | */ | 13 | */ |
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
15 | #include <linux/delay.h> | ||
16 | #include <linux/module.h> | 15 | #include <linux/module.h> |
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
19 | #include <linux/err.h> | 18 | #include <linux/err.h> |
20 | #include <linux/string.h> | 19 | #include <linux/string.h> |
21 | #include <linux/jiffies.h> | ||
22 | #include <linux/atomic.h> | 20 | #include <linux/atomic.h> |
23 | #include <linux/blk-mq.h> | 21 | #include <linux/blk-mq.h> |
24 | #include <linux/types.h> | 22 | #include <linux/types.h> |
@@ -26,7 +24,6 @@ | |||
26 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
27 | #include <linux/scatterlist.h> | 25 | #include <linux/scatterlist.h> |
28 | #include <linux/nvme.h> | 26 | #include <linux/nvme.h> |
29 | #include <linux/t10-pi.h> | ||
30 | #include <asm/unaligned.h> | 27 | #include <asm/unaligned.h> |
31 | 28 | ||
32 | #include <rdma/ib_verbs.h> | 29 | #include <rdma/ib_verbs.h> |
@@ -169,7 +166,6 @@ MODULE_PARM_DESC(register_always, | |||
169 | static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id, | 166 | static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id, |
170 | struct rdma_cm_event *event); | 167 | struct rdma_cm_event *event); |
171 | static void nvme_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc); | 168 | static void nvme_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc); |
172 | static int __nvme_rdma_del_ctrl(struct nvme_rdma_ctrl *ctrl); | ||
173 | 169 | ||
174 | /* XXX: really should move to a generic header sooner or later.. */ | 170 | /* XXX: really should move to a generic header sooner or later.. */ |
175 | static inline void put_unaligned_le24(u32 val, u8 *p) | 171 | static inline void put_unaligned_le24(u32 val, u8 *p) |
@@ -687,11 +683,6 @@ static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl) | |||
687 | list_del(&ctrl->list); | 683 | list_del(&ctrl->list); |
688 | mutex_unlock(&nvme_rdma_ctrl_mutex); | 684 | mutex_unlock(&nvme_rdma_ctrl_mutex); |
689 | 685 | ||
690 | if (ctrl->ctrl.tagset) { | ||
691 | blk_cleanup_queue(ctrl->ctrl.connect_q); | ||
692 | blk_mq_free_tag_set(&ctrl->tag_set); | ||
693 | nvme_rdma_dev_put(ctrl->device); | ||
694 | } | ||
695 | kfree(ctrl->queues); | 686 | kfree(ctrl->queues); |
696 | nvmf_free_options(nctrl->opts); | 687 | nvmf_free_options(nctrl->opts); |
697 | free_ctrl: | 688 | free_ctrl: |
@@ -748,8 +739,11 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work) | |||
748 | changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE); | 739 | changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE); |
749 | WARN_ON_ONCE(!changed); | 740 | WARN_ON_ONCE(!changed); |
750 | 741 | ||
751 | if (ctrl->queue_count > 1) | 742 | if (ctrl->queue_count > 1) { |
752 | nvme_start_queues(&ctrl->ctrl); | 743 | nvme_start_queues(&ctrl->ctrl); |
744 | nvme_queue_scan(&ctrl->ctrl); | ||
745 | nvme_queue_async_events(&ctrl->ctrl); | ||
746 | } | ||
753 | 747 | ||
754 | dev_info(ctrl->ctrl.device, "Successfully reconnected\n"); | 748 | dev_info(ctrl->ctrl.device, "Successfully reconnected\n"); |
755 | 749 | ||
@@ -1269,7 +1263,7 @@ static int nvme_rdma_route_resolved(struct nvme_rdma_queue *queue) | |||
1269 | { | 1263 | { |
1270 | struct nvme_rdma_ctrl *ctrl = queue->ctrl; | 1264 | struct nvme_rdma_ctrl *ctrl = queue->ctrl; |
1271 | struct rdma_conn_param param = { }; | 1265 | struct rdma_conn_param param = { }; |
1272 | struct nvme_rdma_cm_req priv; | 1266 | struct nvme_rdma_cm_req priv = { }; |
1273 | int ret; | 1267 | int ret; |
1274 | 1268 | ||
1275 | param.qp_num = queue->qp->qp_num; | 1269 | param.qp_num = queue->qp->qp_num; |
@@ -1318,37 +1312,39 @@ out_destroy_queue_ib: | |||
1318 | * that caught the event. Since we hold the callout until the controller | 1312 | * that caught the event. Since we hold the callout until the controller |
1319 | * deletion is completed, we'll deadlock if the controller deletion will | 1313 | * deletion is completed, we'll deadlock if the controller deletion will |
1320 | * call rdma_destroy_id on this queue's cm_id. Thus, we claim ownership | 1314 | * call rdma_destroy_id on this queue's cm_id. Thus, we claim ownership |
1321 | * of destroying this queue before-hand, destroy the queue resources | 1315 | * of destroying this queue before-hand, destroy the queue resources, |
1322 | * after the controller deletion completed with the exception of destroying | 1316 | * then queue the controller deletion which won't destroy this queue and |
1323 | * the cm_id implicitely by returning a non-zero rc to the callout. | 1317 | * we destroy the cm_id implicitely by returning a non-zero rc to the callout. |
1324 | */ | 1318 | */ |
1325 | static int nvme_rdma_device_unplug(struct nvme_rdma_queue *queue) | 1319 | static int nvme_rdma_device_unplug(struct nvme_rdma_queue *queue) |
1326 | { | 1320 | { |
1327 | struct nvme_rdma_ctrl *ctrl = queue->ctrl; | 1321 | struct nvme_rdma_ctrl *ctrl = queue->ctrl; |
1328 | int ret, ctrl_deleted = 0; | 1322 | int ret; |
1329 | 1323 | ||
1330 | /* First disable the queue so ctrl delete won't free it */ | 1324 | /* Own the controller deletion */ |
1331 | if (!test_and_clear_bit(NVME_RDMA_Q_CONNECTED, &queue->flags)) | 1325 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING)) |
1332 | goto out; | 1326 | return 0; |
1333 | 1327 | ||
1334 | /* delete the controller */ | 1328 | dev_warn(ctrl->ctrl.device, |
1335 | ret = __nvme_rdma_del_ctrl(ctrl); | 1329 | "Got rdma device removal event, deleting ctrl\n"); |
1336 | if (!ret) { | ||
1337 | dev_warn(ctrl->ctrl.device, | ||
1338 | "Got rdma device removal event, deleting ctrl\n"); | ||
1339 | flush_work(&ctrl->delete_work); | ||
1340 | 1330 | ||
1341 | /* Return non-zero so the cm_id will destroy implicitly */ | 1331 | /* Get rid of reconnect work if its running */ |
1342 | ctrl_deleted = 1; | 1332 | cancel_delayed_work_sync(&ctrl->reconnect_work); |
1343 | 1333 | ||
1334 | /* Disable the queue so ctrl delete won't free it */ | ||
1335 | if (test_and_clear_bit(NVME_RDMA_Q_CONNECTED, &queue->flags)) { | ||
1344 | /* Free this queue ourselves */ | 1336 | /* Free this queue ourselves */ |
1345 | rdma_disconnect(queue->cm_id); | 1337 | nvme_rdma_stop_queue(queue); |
1346 | ib_drain_qp(queue->qp); | ||
1347 | nvme_rdma_destroy_queue_ib(queue); | 1338 | nvme_rdma_destroy_queue_ib(queue); |
1339 | |||
1340 | /* Return non-zero so the cm_id will destroy implicitly */ | ||
1341 | ret = 1; | ||
1348 | } | 1342 | } |
1349 | 1343 | ||
1350 | out: | 1344 | /* Queue controller deletion */ |
1351 | return ctrl_deleted; | 1345 | queue_work(nvme_rdma_wq, &ctrl->delete_work); |
1346 | flush_work(&ctrl->delete_work); | ||
1347 | return ret; | ||
1352 | } | 1348 | } |
1353 | 1349 | ||
1354 | static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id, | 1350 | static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id, |
@@ -1648,7 +1644,7 @@ static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl) | |||
1648 | nvme_rdma_free_io_queues(ctrl); | 1644 | nvme_rdma_free_io_queues(ctrl); |
1649 | } | 1645 | } |
1650 | 1646 | ||
1651 | if (ctrl->ctrl.state == NVME_CTRL_LIVE) | 1647 | if (test_bit(NVME_RDMA_Q_CONNECTED, &ctrl->queues[0].flags)) |
1652 | nvme_shutdown_ctrl(&ctrl->ctrl); | 1648 | nvme_shutdown_ctrl(&ctrl->ctrl); |
1653 | 1649 | ||
1654 | blk_mq_stop_hw_queues(ctrl->ctrl.admin_q); | 1650 | blk_mq_stop_hw_queues(ctrl->ctrl.admin_q); |
@@ -1657,15 +1653,27 @@ static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl) | |||
1657 | nvme_rdma_destroy_admin_queue(ctrl); | 1653 | nvme_rdma_destroy_admin_queue(ctrl); |
1658 | } | 1654 | } |
1659 | 1655 | ||
1656 | static void __nvme_rdma_remove_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown) | ||
1657 | { | ||
1658 | nvme_uninit_ctrl(&ctrl->ctrl); | ||
1659 | if (shutdown) | ||
1660 | nvme_rdma_shutdown_ctrl(ctrl); | ||
1661 | |||
1662 | if (ctrl->ctrl.tagset) { | ||
1663 | blk_cleanup_queue(ctrl->ctrl.connect_q); | ||
1664 | blk_mq_free_tag_set(&ctrl->tag_set); | ||
1665 | nvme_rdma_dev_put(ctrl->device); | ||
1666 | } | ||
1667 | |||
1668 | nvme_put_ctrl(&ctrl->ctrl); | ||
1669 | } | ||
1670 | |||
1660 | static void nvme_rdma_del_ctrl_work(struct work_struct *work) | 1671 | static void nvme_rdma_del_ctrl_work(struct work_struct *work) |
1661 | { | 1672 | { |
1662 | struct nvme_rdma_ctrl *ctrl = container_of(work, | 1673 | struct nvme_rdma_ctrl *ctrl = container_of(work, |
1663 | struct nvme_rdma_ctrl, delete_work); | 1674 | struct nvme_rdma_ctrl, delete_work); |
1664 | 1675 | ||
1665 | nvme_remove_namespaces(&ctrl->ctrl); | 1676 | __nvme_rdma_remove_ctrl(ctrl, true); |
1666 | nvme_rdma_shutdown_ctrl(ctrl); | ||
1667 | nvme_uninit_ctrl(&ctrl->ctrl); | ||
1668 | nvme_put_ctrl(&ctrl->ctrl); | ||
1669 | } | 1677 | } |
1670 | 1678 | ||
1671 | static int __nvme_rdma_del_ctrl(struct nvme_rdma_ctrl *ctrl) | 1679 | static int __nvme_rdma_del_ctrl(struct nvme_rdma_ctrl *ctrl) |
@@ -1698,9 +1706,7 @@ static void nvme_rdma_remove_ctrl_work(struct work_struct *work) | |||
1698 | struct nvme_rdma_ctrl *ctrl = container_of(work, | 1706 | struct nvme_rdma_ctrl *ctrl = container_of(work, |
1699 | struct nvme_rdma_ctrl, delete_work); | 1707 | struct nvme_rdma_ctrl, delete_work); |
1700 | 1708 | ||
1701 | nvme_remove_namespaces(&ctrl->ctrl); | 1709 | __nvme_rdma_remove_ctrl(ctrl, false); |
1702 | nvme_uninit_ctrl(&ctrl->ctrl); | ||
1703 | nvme_put_ctrl(&ctrl->ctrl); | ||
1704 | } | 1710 | } |
1705 | 1711 | ||
1706 | static void nvme_rdma_reset_ctrl_work(struct work_struct *work) | 1712 | static void nvme_rdma_reset_ctrl_work(struct work_struct *work) |
@@ -1739,6 +1745,7 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work) | |||
1739 | if (ctrl->queue_count > 1) { | 1745 | if (ctrl->queue_count > 1) { |
1740 | nvme_start_queues(&ctrl->ctrl); | 1746 | nvme_start_queues(&ctrl->ctrl); |
1741 | nvme_queue_scan(&ctrl->ctrl); | 1747 | nvme_queue_scan(&ctrl->ctrl); |
1748 | nvme_queue_async_events(&ctrl->ctrl); | ||
1742 | } | 1749 | } |
1743 | 1750 | ||
1744 | return; | 1751 | return; |
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 2fac17a5ad53..47c564b5a289 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c | |||
@@ -13,7 +13,6 @@ | |||
13 | */ | 13 | */ |
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/random.h> | ||
17 | #include <generated/utsrelease.h> | 16 | #include <generated/utsrelease.h> |
18 | #include "nvmet.h" | 17 | #include "nvmet.h" |
19 | 18 | ||
@@ -83,7 +82,6 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) | |||
83 | { | 82 | { |
84 | struct nvmet_ctrl *ctrl = req->sq->ctrl; | 83 | struct nvmet_ctrl *ctrl = req->sq->ctrl; |
85 | struct nvme_id_ctrl *id; | 84 | struct nvme_id_ctrl *id; |
86 | u64 serial; | ||
87 | u16 status = 0; | 85 | u16 status = 0; |
88 | 86 | ||
89 | id = kzalloc(sizeof(*id), GFP_KERNEL); | 87 | id = kzalloc(sizeof(*id), GFP_KERNEL); |
@@ -96,10 +94,8 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) | |||
96 | id->vid = 0; | 94 | id->vid = 0; |
97 | id->ssvid = 0; | 95 | id->ssvid = 0; |
98 | 96 | ||
99 | /* generate a random serial number as our controllers are ephemeral: */ | ||
100 | get_random_bytes(&serial, sizeof(serial)); | ||
101 | memset(id->sn, ' ', sizeof(id->sn)); | 97 | memset(id->sn, ' ', sizeof(id->sn)); |
102 | snprintf(id->sn, sizeof(id->sn), "%llx", serial); | 98 | snprintf(id->sn, sizeof(id->sn), "%llx", ctrl->serial); |
103 | 99 | ||
104 | memset(id->mn, ' ', sizeof(id->mn)); | 100 | memset(id->mn, ' ', sizeof(id->mn)); |
105 | strncpy((char *)id->mn, "Linux", sizeof(id->mn)); | 101 | strncpy((char *)id->mn, "Linux", sizeof(id->mn)); |
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 8a891ca53367..6559d5afa7bf 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/random.h> | ||
16 | #include "nvmet.h" | 17 | #include "nvmet.h" |
17 | 18 | ||
18 | static struct nvmet_fabrics_ops *nvmet_transports[NVMF_TRTYPE_MAX]; | 19 | static struct nvmet_fabrics_ops *nvmet_transports[NVMF_TRTYPE_MAX]; |
@@ -728,6 +729,9 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, | |||
728 | memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE); | 729 | memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE); |
729 | memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE); | 730 | memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE); |
730 | 731 | ||
732 | /* generate a random serial number as our controllers are ephemeral: */ | ||
733 | get_random_bytes(&ctrl->serial, sizeof(ctrl->serial)); | ||
734 | |||
731 | kref_init(&ctrl->ref); | 735 | kref_init(&ctrl->ref); |
732 | ctrl->subsys = subsys; | 736 | ctrl->subsys = subsys; |
733 | 737 | ||
diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c index 94e782987cc9..7affd40a6b33 100644 --- a/drivers/nvme/target/loop.c +++ b/drivers/nvme/target/loop.c | |||
@@ -414,9 +414,8 @@ static void nvme_loop_del_ctrl_work(struct work_struct *work) | |||
414 | struct nvme_loop_ctrl *ctrl = container_of(work, | 414 | struct nvme_loop_ctrl *ctrl = container_of(work, |
415 | struct nvme_loop_ctrl, delete_work); | 415 | struct nvme_loop_ctrl, delete_work); |
416 | 416 | ||
417 | nvme_remove_namespaces(&ctrl->ctrl); | ||
418 | nvme_loop_shutdown_ctrl(ctrl); | ||
419 | nvme_uninit_ctrl(&ctrl->ctrl); | 417 | nvme_uninit_ctrl(&ctrl->ctrl); |
418 | nvme_loop_shutdown_ctrl(ctrl); | ||
420 | nvme_put_ctrl(&ctrl->ctrl); | 419 | nvme_put_ctrl(&ctrl->ctrl); |
421 | } | 420 | } |
422 | 421 | ||
@@ -501,7 +500,6 @@ out_free_queues: | |||
501 | nvme_loop_destroy_admin_queue(ctrl); | 500 | nvme_loop_destroy_admin_queue(ctrl); |
502 | out_disable: | 501 | out_disable: |
503 | dev_warn(ctrl->ctrl.device, "Removing after reset failure\n"); | 502 | dev_warn(ctrl->ctrl.device, "Removing after reset failure\n"); |
504 | nvme_remove_namespaces(&ctrl->ctrl); | ||
505 | nvme_uninit_ctrl(&ctrl->ctrl); | 503 | nvme_uninit_ctrl(&ctrl->ctrl); |
506 | nvme_put_ctrl(&ctrl->ctrl); | 504 | nvme_put_ctrl(&ctrl->ctrl); |
507 | } | 505 | } |
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 57dd6d834c28..76b6eedccaf9 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h | |||
@@ -113,6 +113,7 @@ struct nvmet_ctrl { | |||
113 | 113 | ||
114 | struct mutex lock; | 114 | struct mutex lock; |
115 | u64 cap; | 115 | u64 cap; |
116 | u64 serial; | ||
116 | u32 cc; | 117 | u32 cc; |
117 | u32 csts; | 118 | u32 csts; |
118 | 119 | ||
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c index e06d504bdf0c..b4d648536c3e 100644 --- a/drivers/nvme/target/rdma.c +++ b/drivers/nvme/target/rdma.c | |||
@@ -77,6 +77,7 @@ enum nvmet_rdma_queue_state { | |||
77 | NVMET_RDMA_Q_CONNECTING, | 77 | NVMET_RDMA_Q_CONNECTING, |
78 | NVMET_RDMA_Q_LIVE, | 78 | NVMET_RDMA_Q_LIVE, |
79 | NVMET_RDMA_Q_DISCONNECTING, | 79 | NVMET_RDMA_Q_DISCONNECTING, |
80 | NVMET_RDMA_IN_DEVICE_REMOVAL, | ||
80 | }; | 81 | }; |
81 | 82 | ||
82 | struct nvmet_rdma_queue { | 83 | struct nvmet_rdma_queue { |
@@ -615,15 +616,10 @@ static u16 nvmet_rdma_map_sgl_keyed(struct nvmet_rdma_rsp *rsp, | |||
615 | if (!len) | 616 | if (!len) |
616 | return 0; | 617 | return 0; |
617 | 618 | ||
618 | /* use the already allocated data buffer if possible */ | 619 | status = nvmet_rdma_alloc_sgl(&rsp->req.sg, &rsp->req.sg_cnt, |
619 | if (len <= NVMET_RDMA_INLINE_DATA_SIZE && rsp->queue->host_qid) { | 620 | len); |
620 | nvmet_rdma_use_inline_sg(rsp, len, 0); | 621 | if (status) |
621 | } else { | 622 | return status; |
622 | status = nvmet_rdma_alloc_sgl(&rsp->req.sg, &rsp->req.sg_cnt, | ||
623 | len); | ||
624 | if (status) | ||
625 | return status; | ||
626 | } | ||
627 | 623 | ||
628 | ret = rdma_rw_ctx_init(&rsp->rw, cm_id->qp, cm_id->port_num, | 624 | ret = rdma_rw_ctx_init(&rsp->rw, cm_id->qp, cm_id->port_num, |
629 | rsp->req.sg, rsp->req.sg_cnt, 0, addr, key, | 625 | rsp->req.sg, rsp->req.sg_cnt, 0, addr, key, |
@@ -984,7 +980,10 @@ static void nvmet_rdma_release_queue_work(struct work_struct *w) | |||
984 | struct nvmet_rdma_device *dev = queue->dev; | 980 | struct nvmet_rdma_device *dev = queue->dev; |
985 | 981 | ||
986 | nvmet_rdma_free_queue(queue); | 982 | nvmet_rdma_free_queue(queue); |
987 | rdma_destroy_id(cm_id); | 983 | |
984 | if (queue->state != NVMET_RDMA_IN_DEVICE_REMOVAL) | ||
985 | rdma_destroy_id(cm_id); | ||
986 | |||
988 | kref_put(&dev->ref, nvmet_rdma_free_dev); | 987 | kref_put(&dev->ref, nvmet_rdma_free_dev); |
989 | } | 988 | } |
990 | 989 | ||
@@ -1233,8 +1232,9 @@ static void __nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue) | |||
1233 | switch (queue->state) { | 1232 | switch (queue->state) { |
1234 | case NVMET_RDMA_Q_CONNECTING: | 1233 | case NVMET_RDMA_Q_CONNECTING: |
1235 | case NVMET_RDMA_Q_LIVE: | 1234 | case NVMET_RDMA_Q_LIVE: |
1236 | disconnect = true; | ||
1237 | queue->state = NVMET_RDMA_Q_DISCONNECTING; | 1235 | queue->state = NVMET_RDMA_Q_DISCONNECTING; |
1236 | case NVMET_RDMA_IN_DEVICE_REMOVAL: | ||
1237 | disconnect = true; | ||
1238 | break; | 1238 | break; |
1239 | case NVMET_RDMA_Q_DISCONNECTING: | 1239 | case NVMET_RDMA_Q_DISCONNECTING: |
1240 | break; | 1240 | break; |
@@ -1272,6 +1272,62 @@ static void nvmet_rdma_queue_connect_fail(struct rdma_cm_id *cm_id, | |||
1272 | schedule_work(&queue->release_work); | 1272 | schedule_work(&queue->release_work); |
1273 | } | 1273 | } |
1274 | 1274 | ||
1275 | /** | ||
1276 | * nvme_rdma_device_removal() - Handle RDMA device removal | ||
1277 | * @queue: nvmet rdma queue (cm id qp_context) | ||
1278 | * @addr: nvmet address (cm_id context) | ||
1279 | * | ||
1280 | * DEVICE_REMOVAL event notifies us that the RDMA device is about | ||
1281 | * to unplug so we should take care of destroying our RDMA resources. | ||
1282 | * This event will be generated for each allocated cm_id. | ||
1283 | * | ||
1284 | * Note that this event can be generated on a normal queue cm_id | ||
1285 | * and/or a device bound listener cm_id (where in this case | ||
1286 | * queue will be null). | ||
1287 | * | ||
1288 | * we claim ownership on destroying the cm_id. For queues we move | ||
1289 | * the queue state to NVMET_RDMA_IN_DEVICE_REMOVAL and for port | ||
1290 | * we nullify the priv to prevent double cm_id destruction and destroying | ||
1291 | * the cm_id implicitely by returning a non-zero rc to the callout. | ||
1292 | */ | ||
1293 | static int nvmet_rdma_device_removal(struct rdma_cm_id *cm_id, | ||
1294 | struct nvmet_rdma_queue *queue) | ||
1295 | { | ||
1296 | unsigned long flags; | ||
1297 | |||
1298 | if (!queue) { | ||
1299 | struct nvmet_port *port = cm_id->context; | ||
1300 | |||
1301 | /* | ||
1302 | * This is a listener cm_id. Make sure that | ||
1303 | * future remove_port won't invoke a double | ||
1304 | * cm_id destroy. use atomic xchg to make sure | ||
1305 | * we don't compete with remove_port. | ||
1306 | */ | ||
1307 | if (xchg(&port->priv, NULL) != cm_id) | ||
1308 | return 0; | ||
1309 | } else { | ||
1310 | /* | ||
1311 | * This is a queue cm_id. Make sure that | ||
1312 | * release queue will not destroy the cm_id | ||
1313 | * and schedule all ctrl queues removal (only | ||
1314 | * if the queue is not disconnecting already). | ||
1315 | */ | ||
1316 | spin_lock_irqsave(&queue->state_lock, flags); | ||
1317 | if (queue->state != NVMET_RDMA_Q_DISCONNECTING) | ||
1318 | queue->state = NVMET_RDMA_IN_DEVICE_REMOVAL; | ||
1319 | spin_unlock_irqrestore(&queue->state_lock, flags); | ||
1320 | nvmet_rdma_queue_disconnect(queue); | ||
1321 | flush_scheduled_work(); | ||
1322 | } | ||
1323 | |||
1324 | /* | ||
1325 | * We need to return 1 so that the core will destroy | ||
1326 | * it's own ID. What a great API design.. | ||
1327 | */ | ||
1328 | return 1; | ||
1329 | } | ||
1330 | |||
1275 | static int nvmet_rdma_cm_handler(struct rdma_cm_id *cm_id, | 1331 | static int nvmet_rdma_cm_handler(struct rdma_cm_id *cm_id, |
1276 | struct rdma_cm_event *event) | 1332 | struct rdma_cm_event *event) |
1277 | { | 1333 | { |
@@ -1294,20 +1350,11 @@ static int nvmet_rdma_cm_handler(struct rdma_cm_id *cm_id, | |||
1294 | break; | 1350 | break; |
1295 | case RDMA_CM_EVENT_ADDR_CHANGE: | 1351 | case RDMA_CM_EVENT_ADDR_CHANGE: |
1296 | case RDMA_CM_EVENT_DISCONNECTED: | 1352 | case RDMA_CM_EVENT_DISCONNECTED: |
1297 | case RDMA_CM_EVENT_DEVICE_REMOVAL: | ||
1298 | case RDMA_CM_EVENT_TIMEWAIT_EXIT: | 1353 | case RDMA_CM_EVENT_TIMEWAIT_EXIT: |
1299 | /* | 1354 | nvmet_rdma_queue_disconnect(queue); |
1300 | * We can get the device removal callback even for a | 1355 | break; |
1301 | * CM ID that we aren't actually using. In that case | 1356 | case RDMA_CM_EVENT_DEVICE_REMOVAL: |
1302 | * the context pointer is NULL, so we shouldn't try | 1357 | ret = nvmet_rdma_device_removal(cm_id, queue); |
1303 | * to disconnect a non-existing queue. But we also | ||
1304 | * need to return 1 so that the core will destroy | ||
1305 | * it's own ID. What a great API design.. | ||
1306 | */ | ||
1307 | if (queue) | ||
1308 | nvmet_rdma_queue_disconnect(queue); | ||
1309 | else | ||
1310 | ret = 1; | ||
1311 | break; | 1358 | break; |
1312 | case RDMA_CM_EVENT_REJECTED: | 1359 | case RDMA_CM_EVENT_REJECTED: |
1313 | case RDMA_CM_EVENT_UNREACHABLE: | 1360 | case RDMA_CM_EVENT_UNREACHABLE: |
@@ -1396,9 +1443,10 @@ out_destroy_id: | |||
1396 | 1443 | ||
1397 | static void nvmet_rdma_remove_port(struct nvmet_port *port) | 1444 | static void nvmet_rdma_remove_port(struct nvmet_port *port) |
1398 | { | 1445 | { |
1399 | struct rdma_cm_id *cm_id = port->priv; | 1446 | struct rdma_cm_id *cm_id = xchg(&port->priv, NULL); |
1400 | 1447 | ||
1401 | rdma_destroy_id(cm_id); | 1448 | if (cm_id) |
1449 | rdma_destroy_id(cm_id); | ||
1402 | } | 1450 | } |
1403 | 1451 | ||
1404 | static struct nvmet_fabrics_ops nvmet_rdma_ops = { | 1452 | static struct nvmet_fabrics_ops nvmet_rdma_ops = { |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 4d09d4441e3e..05713a5da083 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -1949,6 +1949,12 @@ void wakeup_flusher_threads(long nr_pages, enum wb_reason reason) | |||
1949 | { | 1949 | { |
1950 | struct backing_dev_info *bdi; | 1950 | struct backing_dev_info *bdi; |
1951 | 1951 | ||
1952 | /* | ||
1953 | * If we are expecting writeback progress we must submit plugged IO. | ||
1954 | */ | ||
1955 | if (blk_needs_flush_plug(current)) | ||
1956 | blk_schedule_flush_plug(current); | ||
1957 | |||
1952 | if (!nr_pages) | 1958 | if (!nr_pages) |
1953 | nr_pages = get_nr_dirty_pages(); | 1959 | nr_pages = get_nr_dirty_pages(); |
1954 | 1960 | ||
diff --git a/include/linux/bvec.h b/include/linux/bvec.h index 701b64a3b7c5..89b65b82d98f 100644 --- a/include/linux/bvec.h +++ b/include/linux/bvec.h | |||
@@ -74,7 +74,8 @@ static inline void bvec_iter_advance(const struct bio_vec *bv, | |||
74 | "Attempted to advance past end of bvec iter\n"); | 74 | "Attempted to advance past end of bvec iter\n"); |
75 | 75 | ||
76 | while (bytes) { | 76 | while (bytes) { |
77 | unsigned len = min(bytes, bvec_iter_len(bv, *iter)); | 77 | unsigned iter_len = bvec_iter_len(bv, *iter); |
78 | unsigned len = min(bytes, iter_len); | ||
78 | 79 | ||
79 | bytes -= len; | 80 | bytes -= len; |
80 | iter->bi_size -= len; | 81 | iter->bi_size -= len; |