]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - pending-5.1/nvme-release-namespace-srcu-protection-before-perfor.patch
move existing queues out of the way for the moment...
[thirdparty/kernel/stable-queue.git] / pending-5.1 / nvme-release-namespace-srcu-protection-before-perfor.patch
CommitLineData
fb43722c
SL
1From c1e7f5043239b4a293a630b31a5f45bad1f37a4c Mon Sep 17 00:00:00 2001
2From: Christoph Hellwig <hch@lst.de>
3Date: Fri, 17 May 2019 11:47:36 +0200
4Subject: nvme: release namespace SRCU protection before performing controller
5 ioctls
6
7[ Upstream commit 5fb4aac756acacf260b9ebd88747251effa3a2f2 ]
8
9Holding the SRCU critical section protecting the namespace list can
10cause deadlocks when using the per-namespace admin passthrough ioctl to
11delete as namespace. Release it earlier when performing per-controller
12ioctls to avoid that.
13
14Reported-by: Kenneth Heitke <kenneth.heitke@intel.com>
15Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
16Reviewed-by: Keith Busch <keith.busch@intel.com>
17Signed-off-by: Christoph Hellwig <hch@lst.de>
18Signed-off-by: Sasha Levin <sashal@kernel.org>
19---
20 drivers/nvme/host/core.c | 25 ++++++++++++++++++++-----
21 1 file changed, 20 insertions(+), 5 deletions(-)
22
23diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
24index 8b77e6a05f4b..23c90382a515 100644
25--- a/drivers/nvme/host/core.c
26+++ b/drivers/nvme/host/core.c
27@@ -1395,14 +1395,31 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
28 if (unlikely(!ns))
29 return -EWOULDBLOCK;
30
31+ /*
32+ * Handle ioctls that apply to the controller instead of the namespace
33+ * seperately and drop the ns SRCU reference early. This avoids a
34+ * deadlock when deleting namespaces using the passthrough interface.
35+ */
36+ if (cmd == NVME_IOCTL_ADMIN_CMD || is_sed_ioctl(cmd)) {
37+ struct nvme_ctrl *ctrl = ns->ctrl;
38+
39+ nvme_get_ctrl(ns->ctrl);
40+ nvme_put_ns_from_disk(head, srcu_idx);
41+
42+ if (cmd == NVME_IOCTL_ADMIN_CMD)
43+ ret = nvme_user_cmd(ctrl, NULL, argp);
44+ else
45+ ret = sed_ioctl(ctrl->opal_dev, cmd, argp);
46+
47+ nvme_put_ctrl(ctrl);
48+ return ret;
49+ }
50+
51 switch (cmd) {
52 case NVME_IOCTL_ID:
53 force_successful_syscall_return();
54 ret = ns->head->ns_id;
55 break;
56- case NVME_IOCTL_ADMIN_CMD:
57- ret = nvme_user_cmd(ns->ctrl, NULL, argp);
58- break;
59 case NVME_IOCTL_IO_CMD:
60 ret = nvme_user_cmd(ns->ctrl, ns, argp);
61 break;
62@@ -1412,8 +1429,6 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
63 default:
64 if (ns->ndev)
65 ret = nvme_nvm_ioctl(ns, cmd, arg);
66- else if (is_sed_ioctl(cmd))
67- ret = sed_ioctl(ns->ctrl->opal_dev, cmd, argp);
68 else
69 ret = -ENOTTY;
70 }
71--
722.20.1
73