Linux-NVME Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Guixin Liu <kanie@linux.alibaba.com>
To: Chaitanya Kulkarni <chaitanyak@nvidia.com>
Cc: "linux-nvme@lists.infradead.org" <linux-nvme@lists.infradead.org>,
	"hch@lst.de" <hch@lst.de>, "sagi@grimberg.me" <sagi@grimberg.me>
Subject: Re: [PATCH] nvmet: support reservation feature
Date: Wed, 10 Jan 2024 16:45:50 +0800	[thread overview]
Message-ID: <54de4b6d-e5e6-4caf-85f3-a1ea6ddbfe6a@linux.alibaba.com> (raw)
In-Reply-To: <0652d478-9b46-400b-85ec-b3a2bb54ff67@nvidia.com>


在 2024/1/10 16:31, Chaitanya Kulkarni 写道:
> On 1/9/24 21:58, Guixin Liu wrote:
>> 在 2024/1/10 12:34, Chaitanya Kulkarni 写道:
>>> On 1/9/24 04:10, Guixin Liu wrote:
>>>> This patch implements the reservation feature, includes:
>>>> 1. reservation register(register, unregister and replace).
>>>> 2. reservation acquire(acquire, preempt, preempt and abort).
>>>> 3. reservation release(release and clear).
>>>> 4. reservation report.
>>>>
>>>> And also make reservation configurable, one can set ns to support
>>>> reservation before enable ns. The default of resv_enable is false.
>>>>
>>>> Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
>>>> ---
>>>> Hi guys,
>>>>        I've implemented the NVMe reservation feature. Please review
>>>> it, all
>>>> comments are welcome.
>>>>        In addtion, I didn't implement event reporting because I
>>>> didn't see
>>>> any handling of these events on the host side. If these events are
>>>> mandatory
>>>> to report, please let me know so that I can implement them.
>>>>
>>>>     drivers/nvme/target/Makefile    |   2 +-
>>>>     drivers/nvme/target/admin-cmd.c |  14 +-
>>>>     drivers/nvme/target/configfs.c  |  27 ++
>>>>     drivers/nvme/target/core.c      |  37 +-
>>>>     drivers/nvme/target/nvmet.h     |  26 ++
>>>>     drivers/nvme/target/pr.c        | 806
>>>> ++++++++++++++++++++++++++++++++
>>>>     include/linux/nvme.h            |  30 ++
>>>>     7 files changed, 939 insertions(+), 3 deletions(-)
>>>>     create mode 100644 drivers/nvme/target/pr.c
>>>>
>>>> diff --git a/drivers/nvme/target/Makefile
>>>> b/drivers/nvme/target/Makefile
>>>> index c66820102493..f9bfc904a5b3 100644
>>>> --- a/drivers/nvme/target/Makefile
>>>> +++ b/drivers/nvme/target/Makefile
>>>> @@ -10,7 +10,7 @@ obj-$(CONFIG_NVME_TARGET_FCLOOP)    += nvme-fcloop.o
>>>>     obj-$(CONFIG_NVME_TARGET_TCP)        += nvmet-tcp.o
>>>>        nvmet-y        += core.o configfs.o admin-cmd.o fabrics-cmd.o \
>>>> -            discovery.o io-cmd-file.o io-cmd-bdev.o
>>>> +            discovery.o io-cmd-file.o io-cmd-bdev.o pr.o
>>>>     nvmet-$(CONFIG_NVME_TARGET_PASSTHRU)    += passthru.o
>>>>     nvmet-$(CONFIG_BLK_DEV_ZONED)        += zns.o
>>>>     nvmet-$(CONFIG_NVME_TARGET_AUTH)    += fabrics-cmd-auth.o auth.o
>>>> diff --git a/drivers/nvme/target/admin-cmd.c
>>>> b/drivers/nvme/target/admin-cmd.c
>>>> index 39cb570f833d..7da6f3085a4c 100644
>>>> --- a/drivers/nvme/target/admin-cmd.c
>>>> +++ b/drivers/nvme/target/admin-cmd.c
>>>> @@ -550,7 +550,13 @@ static void nvmet_execute_identify_ns(struct
>>>> nvmet_req *req)
>>>>          */
>>>>         id->nmic = NVME_NS_NMIC_SHARED;
>>>>         id->anagrpid = cpu_to_le32(req->ns->anagrpid);
>>>> -
>>>> +    id->rescap = NVME_PR_SUPPORT_WRITE_EXCLUSIVE |
>>>> +             NVME_PR_SUPPORT_EXCLUSIVE_ACCESS |
>>>> +             NVME_PR_SUPPORT_WRITE_EXCLUSIVE_REG_ONLY |
>>>> +             NVME_PR_SUPPORT_EXCLUSIVE_ACCESS_REG_ONLY |
>>>> +             NVME_PR_SUPPORT_WRITE_EXCLUSIVE_ALL_REGS |
>>>> +             NVME_PR_SUPPORT_EXCLUSIVE_ACCESS_ALL_REGS |
>>>> +             NVME_PR_SUPPORT_IEKEY_DEF_LATER_VER_1_3;
>>>>         memcpy(&id->nguid, &req->ns->nguid, sizeof(id->nguid));
>>>>            id->lbaf[0].ds = req->ns->blksize_shift;
>>>> @@ -1017,6 +1023,12 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
>>>>         if (nvmet_is_passthru_req(req))
>>>>             return nvmet_parse_passthru_admin_cmd(req);
>>>>     +    ret = nvmet_pr_check_cmd_access(req);
>>>> +    if (unlikely(ret)) {
>>>> +        req->error_loc = offsetof(struct nvme_common_command, opcode);
>>>> +        return ret;
>>>> +    }
>>>> +
>>>>         switch (cmd->common.opcode) {
>>>>         case nvme_admin_get_log_page:
>>>>             req->execute = nvmet_execute_get_log_page;
>>>> diff --git a/drivers/nvme/target/configfs.c
>>>> b/drivers/nvme/target/configfs.c
>>>> index d937fe05129e..1ac4802ec818 100644
>>>> --- a/drivers/nvme/target/configfs.c
>>>> +++ b/drivers/nvme/target/configfs.c
>>>> @@ -714,6 +714,32 @@ static ssize_t
>>>> nvmet_ns_revalidate_size_store(struct config_item *item,
>>>>        CONFIGFS_ATTR_WO(nvmet_ns_, revalidate_size);
>>>>     +static ssize_t nvmet_ns_resv_enable_show(struct config_item
>>>> *item, char *page)
>>>> +{
>>>> +    return sprintf(page, "%d\n", to_nvmet_ns(item)->pr.enable);
>>>> +}
>>>> +
>>>> +static ssize_t nvmet_ns_resv_enable_store(struct config_item *item,
>>>> +                    const char *page, size_t count)
>>>> +{
>>>> +    struct nvmet_ns *ns = to_nvmet_ns(item);
>>>> +    bool val;
>>>> +
>>>> +    if (kstrtobool(page, &val))
>>>> +        return -EINVAL;
>>>> +
>>>> +    mutex_lock(&ns->subsys->lock);
>>>> +    if (ns->enabled) {
>>>> +        pr_err("the ns:%d is already enabled.\n", ns->nsid);
>>>> +        mutex_unlock(&ns->subsys->lock);
>>>> +        return -EINVAL;
>>>> +    }
>>>> +    ns->pr.enable = val;
>>>> +    mutex_unlock(&ns->subsys->lock);
>>>> +    return count;
>>>> +}
>>>> +CONFIGFS_ATTR(nvmet_ns_, resv_enable);
>>>> +
>>>>     static struct configfs_attribute *nvmet_ns_attrs[] = {
>>>>         &nvmet_ns_attr_device_path,
>>>>         &nvmet_ns_attr_device_nguid,
>>>> @@ -722,6 +748,7 @@ static struct configfs_attribute
>>>> *nvmet_ns_attrs[] = {
>>>>         &nvmet_ns_attr_enable,
>>>>         &nvmet_ns_attr_buffered_io,
>>>>         &nvmet_ns_attr_revalidate_size,
>>>> +    &nvmet_ns_attr_resv_enable,
>>>>     #ifdef CONFIG_PCI_P2PDMA
>>>>         &nvmet_ns_attr_p2pmem,
>>>>     #endif
>>>> diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
>>>> index 3935165048e7..8eab81804b14 100644
>>>> --- a/drivers/nvme/target/core.c
>>>> +++ b/drivers/nvme/target/core.c
>>>> @@ -598,6 +598,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
>>>>         subsys->nr_namespaces++;
>>>>            nvmet_ns_changed(subsys, ns->nsid);
>>>> +    nvmet_pr_init_ns(ns);
>>>>         ns->enabled = true;
>>>>         ret = 0;
>>>>     out_unlock:
>>>> @@ -651,6 +652,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
>>>>            subsys->nr_namespaces--;
>>>>         nvmet_ns_changed(subsys, ns->nsid);
>>>> +    nvmet_pr_clean_all_registrants(&ns->pr);
>>>>         nvmet_ns_dev_disable(ns);
>>>>     out_unlock:
>>>>         mutex_unlock(&subsys->lock);
>>>> @@ -904,6 +906,16 @@ static u16 nvmet_parse_io_cmd(struct nvmet_req
>>>> *req)
>>>>             return ret;
>>>>         }
>>>>     +    ret = nvmet_pr_check_cmd_access(req);
>>>> +    if (unlikely(ret)) {
>>>> +        req->error_loc = offsetof(struct nvme_common_command, opcode);
>>>> +        return ret;
>>>> +    }
>>>> +
>>>> +    ret = nvmet_parse_pr_cmd(req);
>>>> +    if (!ret)
>>>> +        return ret;
>>>> +
>>> Can we make this feature configurable via Kconfig? If someone doesn't
>>> want to
>>> use PR, they will have to bear the cost of these checks in the fast
>>> path.
>> Yeah, I have added a resv_enable in configfs, the default is false,
>> one can
>>
>> make reservation enable before enable namespace.
> Why can't we make it KConfig option ? Is there any particular reason for
> not doing that ? That will also allow user to avoid kernel compilation
> of code if they want to turn it off.
>
> -ck
>
OK, I will add a Kconfig option.


  reply	other threads:[~2024-01-10  8:46 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-09 12:10 [PATCH] nvmet: support reservation feature Guixin Liu
2024-01-09 17:01 ` Keith Busch
2024-01-10  3:19   ` Guixin Liu
2024-01-10  4:36     ` Chaitanya Kulkarni
2024-01-10  5:59       ` Guixin Liu
2024-01-10 17:57     ` Keith Busch
2024-01-10  4:34 ` Chaitanya Kulkarni
2024-01-10  5:58   ` Guixin Liu
2024-01-10  8:31     ` Chaitanya Kulkarni
2024-01-10  8:45       ` Guixin Liu [this message]
2024-01-10 17:16       ` Jens Axboe
2024-01-10 15:47 ` Sagi Grimberg
     [not found]   ` <d9cf6a40-e0bc-4b2c-b421-b313e1f57f10@linux.alibaba.com>
2024-01-11 12:09     ` Guixin Liu

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=54de4b6d-e5e6-4caf-85f3-a1ea6ddbfe6a@linux.alibaba.com \
    --to=kanie@linux.alibaba.com \
    --cc=chaitanyak@nvidia.com \
    --cc=hch@lst.de \
    --cc=linux-nvme@lists.infradead.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox