* [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk
@ 2019-05-17 9:47 Christoph Hellwig
2019-05-17 9:47 ` [PATCH 2/4] nvme: remove the ifdef around nvme_nvm_ioctl Christoph Hellwig
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Christoph Hellwig @ 2019-05-17 9:47 UTC (permalink / raw)
If we can't get a namespace don't leak the SRCU lock. nvme_ioctl was
working around this, but nvme_pr_command wasn't handling this properly.
Just do what callers would usually expect.
Signed-off-by: Christoph Hellwig <hch at lst.de>
Reviewed-by: Keith Busch <keith.busch at intel.com>
Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni at wdc.com>
---
drivers/nvme/host/core.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 7da80f375315..63146060df66 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1361,9 +1361,14 @@ static struct nvme_ns *nvme_get_ns_from_disk(struct gendisk *disk,
{
#ifdef CONFIG_NVME_MULTIPATH
if (disk->fops == &nvme_ns_head_ops) {
+ struct nvme_ns *ns;
+
*head = disk->private_data;
*srcu_idx = srcu_read_lock(&(*head)->srcu);
- return nvme_find_path(*head);
+ ns = nvme_find_path(*head);
+ if (!ns)
+ srcu_read_unlock(&(*head)->srcu, *srcu_idx);
+ return ns;
}
#endif
*head = NULL;
@@ -1410,9 +1415,9 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
ns = nvme_get_ns_from_disk(bdev->bd_disk, &head, &srcu_idx);
if (unlikely(!ns))
- ret = -EWOULDBLOCK;
- else
- ret = nvme_ns_ioctl(ns, cmd, arg);
+ return -EWOULDBLOCK;
+
+ ret = nvme_ns_ioctl(ns, cmd, arg);
nvme_put_ns_from_disk(head, srcu_idx);
return ret;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/4] nvme: remove the ifdef around nvme_nvm_ioctl
2019-05-17 9:47 [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk Christoph Hellwig
@ 2019-05-17 9:47 ` Christoph Hellwig
2019-05-17 9:47 ` [PATCH 3/4] nvme: merge nvme_ns_ioctl into nvme_ioctl Christoph Hellwig
` (2 subsequent siblings)
3 siblings, 0 replies; 11+ messages in thread
From: Christoph Hellwig @ 2019-05-17 9:47 UTC (permalink / raw)
We already have a proper stub if lightnvm is not enabled, so don't bother
with the ifdef.
Signed-off-by: Christoph Hellwig <hch at lst.de>
Reviewed-by: Keith Busch <keith.busch at intel.com>
Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni at wdc.com>
---
drivers/nvme/host/core.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 63146060df66..66ca17898282 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1395,10 +1395,8 @@ static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned cmd, unsigned long arg)
case NVME_IOCTL_SUBMIT_IO:
return nvme_submit_io(ns, (void __user *)arg);
default:
-#ifdef CONFIG_NVM
if (ns->ndev)
return nvme_nvm_ioctl(ns, cmd, arg);
-#endif
if (is_sed_ioctl(cmd))
return sed_ioctl(ns->ctrl->opal_dev, cmd,
(void __user *) arg);
--
2.20.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/4] nvme: merge nvme_ns_ioctl into nvme_ioctl
2019-05-17 9:47 [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk Christoph Hellwig
2019-05-17 9:47 ` [PATCH 2/4] nvme: remove the ifdef around nvme_nvm_ioctl Christoph Hellwig
@ 2019-05-17 9:47 ` Christoph Hellwig
2019-05-17 15:31 ` Minwoo Im
2019-05-17 9:47 ` [PATCH v2 4/4] nvme: release namespace SRCU protection before performing controller ioctls Christoph Hellwig
2019-05-17 18:36 ` [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk Keith Busch
3 siblings, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2019-05-17 9:47 UTC (permalink / raw)
Merge the two functions to make future changes a little easier.
Signed-off-by: Christoph Hellwig <hch at lst.de>
Reviewed-by: Keith Busch <keith.busch at intel.com>
Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni at wdc.com>
---
drivers/nvme/host/core.c | 47 ++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 23 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 66ca17898282..2d56cca1cded 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1382,32 +1382,11 @@ static void nvme_put_ns_from_disk(struct nvme_ns_head *head, int idx)
srcu_read_unlock(&head->srcu, idx);
}
-static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned cmd, unsigned long arg)
-{
- switch (cmd) {
- case NVME_IOCTL_ID:
- force_successful_syscall_return();
- return ns->head->ns_id;
- case NVME_IOCTL_ADMIN_CMD:
- return nvme_user_cmd(ns->ctrl, NULL, (void __user *)arg);
- case NVME_IOCTL_IO_CMD:
- return nvme_user_cmd(ns->ctrl, ns, (void __user *)arg);
- case NVME_IOCTL_SUBMIT_IO:
- return nvme_submit_io(ns, (void __user *)arg);
- default:
- if (ns->ndev)
- return nvme_nvm_ioctl(ns, cmd, arg);
- if (is_sed_ioctl(cmd))
- return sed_ioctl(ns->ctrl->opal_dev, cmd,
- (void __user *) arg);
- return -ENOTTY;
- }
-}
-
static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
struct nvme_ns_head *head = NULL;
+ void __user *argp = (void __user *)arg;
struct nvme_ns *ns;
int srcu_idx, ret;
@@ -1415,7 +1394,29 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
if (unlikely(!ns))
return -EWOULDBLOCK;
- ret = nvme_ns_ioctl(ns, cmd, arg);
+ switch (cmd) {
+ case NVME_IOCTL_ID:
+ force_successful_syscall_return();
+ ret = ns->head->ns_id;
+ break;
+ case NVME_IOCTL_ADMIN_CMD:
+ ret = nvme_user_cmd(ns->ctrl, NULL, argp);
+ break;
+ case NVME_IOCTL_IO_CMD:
+ ret = nvme_user_cmd(ns->ctrl, ns, argp);
+ break;
+ case NVME_IOCTL_SUBMIT_IO:
+ ret = nvme_submit_io(ns, argp);
+ break;
+ default:
+ if (ns->ndev)
+ ret = nvme_nvm_ioctl(ns, cmd, arg);
+ else if (is_sed_ioctl(cmd))
+ ret = sed_ioctl(ns->ctrl->opal_dev, cmd, argp);
+ else
+ ret = -ENOTTY;
+ }
+
nvme_put_ns_from_disk(head, srcu_idx);
return ret;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 4/4] nvme: release namespace SRCU protection before performing controller ioctls
2019-05-17 9:47 [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk Christoph Hellwig
2019-05-17 9:47 ` [PATCH 2/4] nvme: remove the ifdef around nvme_nvm_ioctl Christoph Hellwig
2019-05-17 9:47 ` [PATCH 3/4] nvme: merge nvme_ns_ioctl into nvme_ioctl Christoph Hellwig
@ 2019-05-17 9:47 ` Christoph Hellwig
2019-05-17 14:41 ` Keith Busch
2019-05-17 16:30 ` Chaitanya Kulkarni
2019-05-17 18:36 ` [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk Keith Busch
3 siblings, 2 replies; 11+ messages in thread
From: Christoph Hellwig @ 2019-05-17 9:47 UTC (permalink / raw)
Holding the SRCU critical section protecting the namespace list can
cause deadlocks when using the per-namespace admin passthrough ioctl to
delete as namespace. Release it earlier when performing per-controller
ioctls to avoid that.
Reported-by: Kenneth Heitke <kenneth.heitke at intel.com>
Signed-off-by: Christoph Hellwig <hch at lst.de>
---
drivers/nvme/host/core.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 2d56cca1cded..6af88de83ea7 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1394,14 +1394,31 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
if (unlikely(!ns))
return -EWOULDBLOCK;
+ /*
+ * Handle ioctls that apply to the controller instead of the namespace
+ * seperately and drop the ns SRCU reference early. This avoids a
+ * deadlock when deleting namespaces using the passthrough interface.
+ */
+ if (cmd == NVME_IOCTL_ADMIN_CMD || is_sed_ioctl(cmd)) {
+ struct nvme_ctrl *ctrl = ns->ctrl;
+
+ nvme_get_ctrl(ns->ctrl);
+ nvme_put_ns_from_disk(head, srcu_idx);
+
+ if (cmd == NVME_IOCTL_ADMIN_CMD)
+ ret = nvme_user_cmd(ctrl, NULL, argp);
+ else
+ ret = sed_ioctl(ctrl->opal_dev, cmd, argp);
+
+ nvme_put_ctrl(ctrl);
+ return ret;
+ }
+
switch (cmd) {
case NVME_IOCTL_ID:
force_successful_syscall_return();
ret = ns->head->ns_id;
break;
- case NVME_IOCTL_ADMIN_CMD:
- ret = nvme_user_cmd(ns->ctrl, NULL, argp);
- break;
case NVME_IOCTL_IO_CMD:
ret = nvme_user_cmd(ns->ctrl, ns, argp);
break;
@@ -1411,8 +1428,6 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
default:
if (ns->ndev)
ret = nvme_nvm_ioctl(ns, cmd, arg);
- else if (is_sed_ioctl(cmd))
- ret = sed_ioctl(ns->ctrl->opal_dev, cmd, argp);
else
ret = -ENOTTY;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 4/4] nvme: release namespace SRCU protection before performing controller ioctls
2019-05-17 9:47 ` [PATCH v2 4/4] nvme: release namespace SRCU protection before performing controller ioctls Christoph Hellwig
@ 2019-05-17 14:41 ` Keith Busch
2019-05-17 16:30 ` Chaitanya Kulkarni
1 sibling, 0 replies; 11+ messages in thread
From: Keith Busch @ 2019-05-17 14:41 UTC (permalink / raw)
On Fri, May 17, 2019@11:47:36AM +0200, Christoph Hellwig wrote:
> Holding the SRCU critical section protecting the namespace list can
> cause deadlocks when using the per-namespace admin passthrough ioctl to
> delete as namespace. Release it earlier when performing per-controller
> ioctls to avoid that.
>
> Reported-by: Kenneth Heitke <kenneth.heitke at intel.com>
> Signed-off-by: Christoph Hellwig <hch at lst.de>
This looks fine.
Reviewed-by: Keith Busch <keith.busch at intel.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/4] nvme: merge nvme_ns_ioctl into nvme_ioctl
2019-05-17 9:47 ` [PATCH 3/4] nvme: merge nvme_ns_ioctl into nvme_ioctl Christoph Hellwig
@ 2019-05-17 15:31 ` Minwoo Im
0 siblings, 0 replies; 11+ messages in thread
From: Minwoo Im @ 2019-05-17 15:31 UTC (permalink / raw)
It has always been what I really wanted it to be like.
This looks good to me.
Reviewed-by: Minwoo Im <minwoo.im.dev at gmail.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 4/4] nvme: release namespace SRCU protection before performing controller ioctls
2019-05-17 9:47 ` [PATCH v2 4/4] nvme: release namespace SRCU protection before performing controller ioctls Christoph Hellwig
2019-05-17 14:41 ` Keith Busch
@ 2019-05-17 16:30 ` Chaitanya Kulkarni
1 sibling, 0 replies; 11+ messages in thread
From: Chaitanya Kulkarni @ 2019-05-17 16:30 UTC (permalink / raw)
Looks good.
Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni at wdc.com>
On 5/17/19 2:48 AM, Christoph Hellwig wrote:
> Holding the SRCU critical section protecting the namespace list can
> cause deadlocks when using the per-namespace admin passthrough ioctl to
> delete as namespace. Release it earlier when performing per-controller
> ioctls to avoid that.
>
> Reported-by: Kenneth Heitke <kenneth.heitke at intel.com>
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---
> drivers/nvme/host/core.c | 25 ++++++++++++++++++++-----
> 1 file changed, 20 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 2d56cca1cded..6af88de83ea7 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -1394,14 +1394,31 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
> if (unlikely(!ns))
> return -EWOULDBLOCK;
>
> + /*
> + * Handle ioctls that apply to the controller instead of the namespace
> + * seperately and drop the ns SRCU reference early. This avoids a
> + * deadlock when deleting namespaces using the passthrough interface.
> + */
> + if (cmd == NVME_IOCTL_ADMIN_CMD || is_sed_ioctl(cmd)) {
> + struct nvme_ctrl *ctrl = ns->ctrl;
> +
> + nvme_get_ctrl(ns->ctrl);
> + nvme_put_ns_from_disk(head, srcu_idx);
> +
> + if (cmd == NVME_IOCTL_ADMIN_CMD)
> + ret = nvme_user_cmd(ctrl, NULL, argp);
> + else
> + ret = sed_ioctl(ctrl->opal_dev, cmd, argp);
> +
> + nvme_put_ctrl(ctrl);
> + return ret;
> + }
> +
> switch (cmd) {
> case NVME_IOCTL_ID:
> force_successful_syscall_return();
> ret = ns->head->ns_id;
> break;
> - case NVME_IOCTL_ADMIN_CMD:
> - ret = nvme_user_cmd(ns->ctrl, NULL, argp);
> - break;
> case NVME_IOCTL_IO_CMD:
> ret = nvme_user_cmd(ns->ctrl, ns, argp);
> break;
> @@ -1411,8 +1428,6 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
> default:
> if (ns->ndev)
> ret = nvme_nvm_ioctl(ns, cmd, arg);
> - else if (is_sed_ioctl(cmd))
> - ret = sed_ioctl(ns->ctrl->opal_dev, cmd, argp);
> else
> ret = -ENOTTY;
> }
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk
2019-05-17 9:47 [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk Christoph Hellwig
` (2 preceding siblings ...)
2019-05-17 9:47 ` [PATCH v2 4/4] nvme: release namespace SRCU protection before performing controller ioctls Christoph Hellwig
@ 2019-05-17 18:36 ` Keith Busch
3 siblings, 0 replies; 11+ messages in thread
From: Keith Busch @ 2019-05-17 18:36 UTC (permalink / raw)
Series applied for 5.2.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk
2019-05-16 18:50 Christoph Hellwig
2019-05-16 19:01 ` Keith Busch
@ 2019-05-16 22:33 ` Chaitanya Kulkarni
1 sibling, 0 replies; 11+ messages in thread
From: Chaitanya Kulkarni @ 2019-05-16 22:33 UTC (permalink / raw)
Looks good.
Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni at wdc.com>
On 5/16/19 11:51 AM, Christoph Hellwig wrote:
> If we can't get a namespace don't leak the SRCU lock. nvme_ioctl was
> working around this, but nvme_pr_command wasn't handling this properly.
> Just do what callers would usually expect.
>
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---
> drivers/nvme/host/core.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index d7de0642c832..eb1c2c349014 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -1361,9 +1361,14 @@ static struct nvme_ns *nvme_get_ns_from_disk(struct gendisk *disk,
> {
> #ifdef CONFIG_NVME_MULTIPATH
> if (disk->fops == &nvme_ns_head_ops) {
> + struct nvme_ns *ns;
> +
> *head = disk->private_data;
> *srcu_idx = srcu_read_lock(&(*head)->srcu);
> - return nvme_find_path(*head);
> + ns = nvme_find_path(*head);
> + if (!ns)
> + srcu_read_unlock(&(*head)->srcu, *srcu_idx);
> + return ns;
> }
> #endif
> *head = NULL;
> @@ -1410,9 +1415,9 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
>
> ns = nvme_get_ns_from_disk(bdev->bd_disk, &head, &srcu_idx);
> if (unlikely(!ns))
> - ret = -EWOULDBLOCK;
> - else
> - ret = nvme_ns_ioctl(ns, cmd, arg);
> + return -EWOULDBLOCK;
> +
> + ret = nvme_ns_ioctl(ns, cmd, arg);
> nvme_put_ns_from_disk(head, srcu_idx);
> return ret;
> }
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk
2019-05-16 18:50 Christoph Hellwig
@ 2019-05-16 19:01 ` Keith Busch
2019-05-16 22:33 ` Chaitanya Kulkarni
1 sibling, 0 replies; 11+ messages in thread
From: Keith Busch @ 2019-05-16 19:01 UTC (permalink / raw)
On Thu, May 16, 2019@08:50:33PM +0200, Christoph Hellwig wrote:
> If we can't get a namespace don't leak the SRCU lock. nvme_ioctl was
> working around this, but nvme_pr_command wasn't handling this properly.
> Just do what callers would usually expect.
>
> Signed-off-by: Christoph Hellwig <hch at lst.de>
Looks good.
Reviewed-by: Keith Busch <keith.busch at intel.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk
@ 2019-05-16 18:50 Christoph Hellwig
2019-05-16 19:01 ` Keith Busch
2019-05-16 22:33 ` Chaitanya Kulkarni
0 siblings, 2 replies; 11+ messages in thread
From: Christoph Hellwig @ 2019-05-16 18:50 UTC (permalink / raw)
If we can't get a namespace don't leak the SRCU lock. nvme_ioctl was
working around this, but nvme_pr_command wasn't handling this properly.
Just do what callers would usually expect.
Signed-off-by: Christoph Hellwig <hch at lst.de>
---
drivers/nvme/host/core.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index d7de0642c832..eb1c2c349014 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1361,9 +1361,14 @@ static struct nvme_ns *nvme_get_ns_from_disk(struct gendisk *disk,
{
#ifdef CONFIG_NVME_MULTIPATH
if (disk->fops == &nvme_ns_head_ops) {
+ struct nvme_ns *ns;
+
*head = disk->private_data;
*srcu_idx = srcu_read_lock(&(*head)->srcu);
- return nvme_find_path(*head);
+ ns = nvme_find_path(*head);
+ if (!ns)
+ srcu_read_unlock(&(*head)->srcu, *srcu_idx);
+ return ns;
}
#endif
*head = NULL;
@@ -1410,9 +1415,9 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
ns = nvme_get_ns_from_disk(bdev->bd_disk, &head, &srcu_idx);
if (unlikely(!ns))
- ret = -EWOULDBLOCK;
- else
- ret = nvme_ns_ioctl(ns, cmd, arg);
+ return -EWOULDBLOCK;
+
+ ret = nvme_ns_ioctl(ns, cmd, arg);
nvme_put_ns_from_disk(head, srcu_idx);
return ret;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2019-05-17 18:36 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-17 9:47 [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk Christoph Hellwig
2019-05-17 9:47 ` [PATCH 2/4] nvme: remove the ifdef around nvme_nvm_ioctl Christoph Hellwig
2019-05-17 9:47 ` [PATCH 3/4] nvme: merge nvme_ns_ioctl into nvme_ioctl Christoph Hellwig
2019-05-17 15:31 ` Minwoo Im
2019-05-17 9:47 ` [PATCH v2 4/4] nvme: release namespace SRCU protection before performing controller ioctls Christoph Hellwig
2019-05-17 14:41 ` Keith Busch
2019-05-17 16:30 ` Chaitanya Kulkarni
2019-05-17 18:36 ` [PATCH 1/4] nvme: fix srcu locking on error return in nvme_get_ns_from_disk Keith Busch
-- strict thread matches above, loose matches on Subject: below --
2019-05-16 18:50 Christoph Hellwig
2019-05-16 19:01 ` Keith Busch
2019-05-16 22:33 ` Chaitanya Kulkarni
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.