From: "Javier González" <javier@javigon.com>
To: Keith Busch <kbusch@kernel.org>
Cc: linux-nvme@lists.infradead.org, linux-block@vger.kernel.org,
hch@lst.de, sagi@grimberg.me, minwoo.im.dev@gmail.com
Subject: Re: nvme: enable char device per namespace
Date: Wed, 16 Dec 2020 18:43:22 +0100 [thread overview]
Message-ID: <20201216174322.v2ahfdhvgix536gd@unifi> (raw)
In-Reply-To: <20201216162631.GA77639@dhcp-10-100-145-180.wdc.com>
On 16.12.2020 08:26, Keith Busch wrote:
>On Wed, Dec 16, 2020 at 09:01:51AM +0100, Javier González wrote:
>> > On 15 Dec 2020, at 23.46, Keith Busch <kbusch@kernel.org> wrote:
>> > On Tue, Dec 15, 2020 at 08:55:57PM +0100, javier@javigon.com wrote:
>> >> +static int nvme_alloc_chardev_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns)
>> >> +{
>> >> + char cdisk_name[DISK_NAME_LEN];
>> >> + int ret;
>> >> +
>> >> + device_initialize(&ns->cdev_device);
>> >> + ns->cdev_device.devt = MKDEV(MAJOR(nvme_ns_base_chr_devt),
>> >> + ns->head->instance);
>> >
>> > Ah, I see now. We are making these generic handles for each path, but
>> > the ns->head->instance is the same for all paths to a namespace, so it's
>> > not unique for that. Further, that head->instance is allocated per
>> > subsystem, so it's not unique from namespace heads seen in other
>> > subsystems.
>> >
>> > So, I think you need to allocate a new dev_t for each subsystem rather
>> > than the global nvme_ns_base_chr_devt, and I guess we also need a new
>> > nvme_ns instance field assigned from yet another ida?
>>
>> Ok. I’ll look into it.
>
>The suggestion may be overkill as we don't need unique majors for each
>controller right now (that may change if people need more than a
>million generic handles, but I think we're a ways off from that reality).
>
>The following on top of your patch makes it all work for me. Also, I
>don't think we should abort adding the namespace if the generic handle
>fails, so that's included here too:
>
>---
>diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
>index c1aa4bccdeb2..cc9eaf4eba32 100644
>--- a/drivers/nvme/host/core.c
>+++ b/drivers/nvme/host/core.c
>@@ -86,6 +86,8 @@ static DEFINE_MUTEX(nvme_subsystems_lock);
>
> static DEFINE_IDA(nvme_instance_ida);
> static dev_t nvme_ctrl_base_chr_devt;
>+
>+static DEFINE_IDA(nvme_gen_minor_ida);
> static dev_t nvme_ns_base_chr_devt;
> static struct class *nvme_class;
> static struct class *nvme_ns_class;
>@@ -539,7 +541,8 @@ static void nvme_free_ns(struct kref *kref)
>
> if (ns->ndev)
> nvme_nvm_unregister(ns);
>-
>+ if (ns->minor)
>+ ida_simple_remove(&nvme_gen_minor_ida, ns->minor - 1);
> cdev_device_del(&ns->cdev, &ns->cdev_device);
> put_disk(ns->disk);
> nvme_put_ns_head(ns->head);
>@@ -3932,9 +3935,13 @@ static int nvme_alloc_chardev_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns)
> char cdisk_name[DISK_NAME_LEN];
> int ret;
>
>+ ret = ida_simple_get(&nvme_gen_minor_ida, 0, 0, GFP_KERNEL);
>+ if (ret < 0)
>+ return ret;
>+
>+ ns->minor = ret + 1;
> device_initialize(&ns->cdev_device);
>- ns->cdev_device.devt = MKDEV(MAJOR(nvme_ns_base_chr_devt),
>- ns->head->instance);
>+ ns->cdev_device.devt = MKDEV(MAJOR(nvme_ns_base_chr_devt), ret);
> ns->cdev_device.class = nvme_ns_class;
> ns->cdev_device.parent = ctrl->device;
> ns->cdev_device.groups = nvme_ns_char_id_attr_groups;
>@@ -3945,15 +3952,22 @@ static int nvme_alloc_chardev_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns)
>
> ret = dev_set_name(&ns->cdev_device, "%s", cdisk_name);
> if (ret)
>- return ret;
>+ goto put_ida;
>
> cdev_init(&ns->cdev, &nvme_cdev_fops);
> ns->cdev.owner = ctrl->ops->module;
>
> ret = cdev_device_add(&ns->cdev, &ns->cdev_device);
> if (ret)
>- kfree_const(ns->cdev_device.kobj.name);
>+ goto free_kobj;
>+
>+ return ret;
>
>+free_kobj:
>+ kfree_const(ns->cdev_device.kobj.name);
>+put_ida:
>+ ida_simple_remove(&nvme_gen_minor_ida, ns->minor - 1);
>+ ns->minor = 0;
> return ret;
> }
>
>@@ -4023,7 +4037,9 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
> nvme_fault_inject_init(&ns->fault_inject, ns->disk->disk_name);
>
> if (nvme_alloc_chardev_ns(ctrl, ns))
>- goto out_put_disk;
>+ dev_warn(ctrl->device,
>+ "failed to create generic handle for nsid:%d\n",
>+ nsid);
>
> kfree(id);
>
>diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
>index 168c7719cda4..ccfd49d2a030 100644
>--- a/drivers/nvme/host/nvme.h
>+++ b/drivers/nvme/host/nvme.h
>@@ -435,6 +435,7 @@ struct nvme_ns {
>
> struct device cdev_device; /* char device */
> struct cdev cdev;
>+ int minor;
>
> int lba_shift;
> u16 ms;
>--
Thanks Keith. I will send a new version today.
Regarding nvme-cli: what are your thoughts?
WARNING: multiple messages have this Message-ID (diff)
From: "Javier González" <javier@javigon.com>
To: Keith Busch <kbusch@kernel.org>
Cc: linux-block@vger.kernel.org, minwoo.im.dev@gmail.com, hch@lst.de,
linux-nvme@lists.infradead.org, sagi@grimberg.me
Subject: Re: nvme: enable char device per namespace
Date: Wed, 16 Dec 2020 18:43:22 +0100 [thread overview]
Message-ID: <20201216174322.v2ahfdhvgix536gd@unifi> (raw)
In-Reply-To: <20201216162631.GA77639@dhcp-10-100-145-180.wdc.com>
On 16.12.2020 08:26, Keith Busch wrote:
>On Wed, Dec 16, 2020 at 09:01:51AM +0100, Javier González wrote:
>> > On 15 Dec 2020, at 23.46, Keith Busch <kbusch@kernel.org> wrote:
>> > On Tue, Dec 15, 2020 at 08:55:57PM +0100, javier@javigon.com wrote:
>> >> +static int nvme_alloc_chardev_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns)
>> >> +{
>> >> + char cdisk_name[DISK_NAME_LEN];
>> >> + int ret;
>> >> +
>> >> + device_initialize(&ns->cdev_device);
>> >> + ns->cdev_device.devt = MKDEV(MAJOR(nvme_ns_base_chr_devt),
>> >> + ns->head->instance);
>> >
>> > Ah, I see now. We are making these generic handles for each path, but
>> > the ns->head->instance is the same for all paths to a namespace, so it's
>> > not unique for that. Further, that head->instance is allocated per
>> > subsystem, so it's not unique from namespace heads seen in other
>> > subsystems.
>> >
>> > So, I think you need to allocate a new dev_t for each subsystem rather
>> > than the global nvme_ns_base_chr_devt, and I guess we also need a new
>> > nvme_ns instance field assigned from yet another ida?
>>
>> Ok. I’ll look into it.
>
>The suggestion may be overkill as we don't need unique majors for each
>controller right now (that may change if people need more than a
>million generic handles, but I think we're a ways off from that reality).
>
>The following on top of your patch makes it all work for me. Also, I
>don't think we should abort adding the namespace if the generic handle
>fails, so that's included here too:
>
>---
>diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
>index c1aa4bccdeb2..cc9eaf4eba32 100644
>--- a/drivers/nvme/host/core.c
>+++ b/drivers/nvme/host/core.c
>@@ -86,6 +86,8 @@ static DEFINE_MUTEX(nvme_subsystems_lock);
>
> static DEFINE_IDA(nvme_instance_ida);
> static dev_t nvme_ctrl_base_chr_devt;
>+
>+static DEFINE_IDA(nvme_gen_minor_ida);
> static dev_t nvme_ns_base_chr_devt;
> static struct class *nvme_class;
> static struct class *nvme_ns_class;
>@@ -539,7 +541,8 @@ static void nvme_free_ns(struct kref *kref)
>
> if (ns->ndev)
> nvme_nvm_unregister(ns);
>-
>+ if (ns->minor)
>+ ida_simple_remove(&nvme_gen_minor_ida, ns->minor - 1);
> cdev_device_del(&ns->cdev, &ns->cdev_device);
> put_disk(ns->disk);
> nvme_put_ns_head(ns->head);
>@@ -3932,9 +3935,13 @@ static int nvme_alloc_chardev_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns)
> char cdisk_name[DISK_NAME_LEN];
> int ret;
>
>+ ret = ida_simple_get(&nvme_gen_minor_ida, 0, 0, GFP_KERNEL);
>+ if (ret < 0)
>+ return ret;
>+
>+ ns->minor = ret + 1;
> device_initialize(&ns->cdev_device);
>- ns->cdev_device.devt = MKDEV(MAJOR(nvme_ns_base_chr_devt),
>- ns->head->instance);
>+ ns->cdev_device.devt = MKDEV(MAJOR(nvme_ns_base_chr_devt), ret);
> ns->cdev_device.class = nvme_ns_class;
> ns->cdev_device.parent = ctrl->device;
> ns->cdev_device.groups = nvme_ns_char_id_attr_groups;
>@@ -3945,15 +3952,22 @@ static int nvme_alloc_chardev_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns)
>
> ret = dev_set_name(&ns->cdev_device, "%s", cdisk_name);
> if (ret)
>- return ret;
>+ goto put_ida;
>
> cdev_init(&ns->cdev, &nvme_cdev_fops);
> ns->cdev.owner = ctrl->ops->module;
>
> ret = cdev_device_add(&ns->cdev, &ns->cdev_device);
> if (ret)
>- kfree_const(ns->cdev_device.kobj.name);
>+ goto free_kobj;
>+
>+ return ret;
>
>+free_kobj:
>+ kfree_const(ns->cdev_device.kobj.name);
>+put_ida:
>+ ida_simple_remove(&nvme_gen_minor_ida, ns->minor - 1);
>+ ns->minor = 0;
> return ret;
> }
>
>@@ -4023,7 +4037,9 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
> nvme_fault_inject_init(&ns->fault_inject, ns->disk->disk_name);
>
> if (nvme_alloc_chardev_ns(ctrl, ns))
>- goto out_put_disk;
>+ dev_warn(ctrl->device,
>+ "failed to create generic handle for nsid:%d\n",
>+ nsid);
>
> kfree(id);
>
>diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
>index 168c7719cda4..ccfd49d2a030 100644
>--- a/drivers/nvme/host/nvme.h
>+++ b/drivers/nvme/host/nvme.h
>@@ -435,6 +435,7 @@ struct nvme_ns {
>
> struct device cdev_device; /* char device */
> struct cdev cdev;
>+ int minor;
>
> int lba_shift;
> u16 ms;
>--
Thanks Keith. I will send a new version today.
Regarding nvme-cli: what are your thoughts?
_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
next prev parent reply other threads:[~2020-12-16 17:44 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-15 19:55 [PATCH V3] nvme: enable char device per namespace javier
2020-12-15 19:55 ` javier
2020-12-15 22:12 ` Keith Busch
2020-12-15 22:12 ` Keith Busch
2020-12-16 8:01 ` Javier González
2020-12-16 8:01 ` Javier González
2020-12-15 22:46 ` Keith Busch
2020-12-15 22:46 ` Keith Busch
2020-12-16 8:01 ` Javier González
2020-12-16 8:01 ` Javier González
2020-12-16 16:26 ` Keith Busch
2020-12-16 16:26 ` Keith Busch
2020-12-16 17:43 ` Javier González [this message]
2020-12-16 17:43 ` Javier González
2020-12-16 17:53 ` Keith Busch
2020-12-16 17:53 ` Keith Busch
2020-12-17 13:29 ` Javier González
2020-12-17 13:29 ` Javier González
[not found] <CGME20201216181838eucas1p15c687e5d1319d3fa581990e6cca73295@eucas1p1.samsung.com>
2020-12-16 18:18 ` [PATCH V4] " javier
2021-01-11 18:53 ` Javier González
2021-01-11 18:53 ` Javier González
2021-01-12 9:22 ` Minwoo Im
2021-01-12 9:22 ` Minwoo Im
2021-01-12 11:26 ` Minwoo Im
2021-01-12 11:26 ` Minwoo Im
2021-01-12 18:30 ` Javier González
2021-01-12 18:30 ` Javier González
2021-01-12 18:33 ` Christoph Hellwig
2021-01-12 18:33 ` Christoph Hellwig
2021-01-12 18:41 ` Javier González
2021-01-12 18:41 ` Javier González
-- strict thread matches above, loose matches on Subject: below --
2020-12-08 13:29 [PATCH V2] " javier
2020-12-08 14:21 ` Christoph Hellwig
2020-12-09 9:16 ` Javier González
2020-12-09 9:16 ` Javier González
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201216174322.v2ahfdhvgix536gd@unifi \
--to=javier@javigon.com \
--cc=hch@lst.de \
--cc=kbusch@kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=minwoo.im.dev@gmail.com \
--cc=sagi@grimberg.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.