]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - pending-4.19/nvme-release-namespace-srcu-protection-before-perfor.patch
Fix up backported ptrace patch
[thirdparty/kernel/stable-queue.git] / pending-4.19 / nvme-release-namespace-srcu-protection-before-perfor.patch
1 From db251685664dd1cf36456732d5372b31b0f69d12 Mon Sep 17 00:00:00 2001
2 From: Christoph Hellwig <hch@lst.de>
3 Date: Fri, 17 May 2019 11:47:36 +0200
4 Subject: nvme: release namespace SRCU protection before performing controller
5 ioctls
6
7 [ Upstream commit 5fb4aac756acacf260b9ebd88747251effa3a2f2 ]
8
9 Holding the SRCU critical section protecting the namespace list can
10 cause deadlocks when using the per-namespace admin passthrough ioctl to
11 delete as namespace. Release it earlier when performing per-controller
12 ioctls to avoid that.
13
14 Reported-by: Kenneth Heitke <kenneth.heitke@intel.com>
15 Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
16 Reviewed-by: Keith Busch <keith.busch@intel.com>
17 Signed-off-by: Christoph Hellwig <hch@lst.de>
18 Signed-off-by: Sasha Levin <sashal@kernel.org>
19 ---
20 drivers/nvme/host/core.c | 25 ++++++++++++++++++++-----
21 1 file changed, 20 insertions(+), 5 deletions(-)
22
23 diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
24 index 82f5f1d030d4..818788275406 100644
25 --- a/drivers/nvme/host/core.c
26 +++ b/drivers/nvme/host/core.c
27 @@ -1310,14 +1310,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 @@ -1327,8 +1344,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 --
72 2.20.1
73