From: hare@suse.de (Hannes Reinecke)
Subject: [PATCH 3/4] nvme: implement 'discovery' sysfs entry and discovery uevents
Date: Wed, 22 Aug 2018 10:51:16 +0200 [thread overview]
Message-ID: <b5674a4c-ce2a-e536-45b3-fe4bab2ccccb@suse.de> (raw)
In-Reply-To: <a41d463e-5690-499a-9f7e-0c1bbebf0fb3@suse.de>
On 08/22/2018 09:23 AM, Hannes Reinecke wrote:
> On 08/21/2018 11:01 PM, James Smart wrote:
>>
>>
>> On 8/21/2018 6:43 AM, Hannes Reinecke wrote:
>>> When establishing a connection to the discovery controller with the
>>> 'async-connect' option the cli has no means of actually getting the
>>> discovery log page entries.
>>> This patch implements a 'discovery' sysfs attribute for the controller
>>> which holds the information of the discovery log page. Additionally
>>> an uevent is generated for each discovery log page entry.
>>>
>>> Signed-off-by: Hannes Reinecke <hare at suse.com>
>>> ---
>>> ? drivers/nvme/host/core.c | 163
>>> ++++++++++++++++++++++++++++++++++++++++++++++-
>>> ? drivers/nvme/host/nvme.h |?? 1 +
>>> ? 2 files changed, 163 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
>>> index dd8ec1dd9219..358be6d217d9 100644
>>> --- a/drivers/nvme/host/core.c
>>> +++ b/drivers/nvme/host/core.c
>>> @@ -2325,6 +2325,133 @@ static int nvme_get_effects_log(struct
>>> nvme_ctrl *ctrl)
>>> ????? return ret;
>>> ? }
>>> ? +static int nvme_get_discovery_log(struct nvme_ctrl *ctrl)
>>> +{
>>> +??? int ret, disc_log_len = 4096;
>>> +
>>> +retry:
>>> +??? if (!ctrl->discovery)
>>> +??????? ctrl->discovery = kzalloc(disc_log_len, GFP_KERNEL);
>>> +
>>> +??? if (!ctrl->discovery)
>>> +??????? return 0;
>>> +
>>> +??? ret = nvme_get_log(ctrl, NVME_NSID_ALL, NVME_LOG_DISC, 0,
>>> +?????????????? ctrl->discovery, disc_log_len, 0);
>>> +??? if (ret) {
>>> +??????? kfree(ctrl->discovery);
>>> +??????? ctrl->discovery = NULL;
>>> +??????? return ret;
>>> +??? }
>>> +??? if (ctrl->discovery->numrec > 3 && disc_log_len == 4096) {
>>> +??????? disc_log_len = (ctrl->discovery->numrec + 1) * 1024;
>>> +??????? kfree(ctrl->discovery);
>>> +??????? ctrl->discovery = NULL;
>>> +??????? goto retry;
>>
>> This is missing logic to detect a change in GENCTR and restart the log
>> read.
>>
> Yeah, I'll be implementing this for the next round.
>
>>> +??? }
>>> +??? return ret;
>>> +}
>>> +
>>> ...
>>> +static int nvme_configure_discovery(struct nvme_ctrl *ctrl)
>>> +{
>>> +??? int ret = 0;
>>> +
>>> +??? if (!ctrl->opts || !ctrl->opts->discovery_nqn)
>>> +??????? return 0;
>>> +
>>> +??? if (!ctrl->opts->async_connect)
>>> +??????? return 0;
>>
>> I don't understand why async_connect parameter means anything in this
>> context...? why is this looked at?
>>
>> is it strictly to avoid delay while reading the discovery log ?? I don't
>> know that waiting for yet another command or two is a big deal, so I
>> would think just proceeding with reading the discovery log is fine.
>>
> Originally I did that so as to restore the original functionality, and
> tie discovery events to the use of the 'async_connect' parameter.
> But you are right, both are not necessarily connected.
> I'll drop this for the next round.
>
>>> +
>>> +??? ret = nvme_get_discovery_log(ctrl);
>>> +??? if (!ret && ctrl->discovery) {
>>> +??????? int i;
>>> +??????? struct nvmf_disc_rsp_page_entry *entry =
>>> +??????????? ctrl->discovery->entries;
>>> +
>>> +??????? for (i = 0; i < ctrl->discovery->numrec; i++) {
>>> +??????????? nvme_discovery_uevent(ctrl, entry);
>>> +??????????? entry++;
>>> +??????? }
>>> +??? }
>>> +??? return ret;
>>> +}
>>> +
>>> ? /*
>>> ?? * Initialize the cached copies of the Identify data and various
>>> controller
>>> ?? * register in our nvme_ctrl structure.? This should be called as
>>> soon as
>>> @@ -2491,6 +2618,10 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
>>> ????? if (ret < 0)
>>> ????????? return ret;
>>> ? +??? ret = nvme_configure_discovery(ctrl);
>>> +??? if (ret < 0)
>>> +??????? return ret;
>>> +
>>> ????? ctrl->identified = true;
>>> ? ????? return 0;
>>> @@ -2825,6 +2956,32 @@ static ssize_t nvme_sysfs_show_address(struct
>>> device *dev,
>>> ? }
>>> ? static DEVICE_ATTR(address, S_IRUGO, nvme_sysfs_show_address, NULL);
>>> ? +static ssize_t nvme_discovery_show(struct device *dev,
>>> +?????????????????? struct device_attribute *attr,
>>> +?????????????????? char *buf)
>>> +{
>>> +??? struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
>>> +??? struct nvmf_disc_rsp_page_entry *entry;
>>> +??? int i;
>>> +??? ssize_t len = 0;
>>> +
>>> +??? if (!ctrl->discovery)
>>> +??????? return -EINVAL;
>>> +
>>> +??? entry = ctrl->discovery->entries;
>>> +??? for (i = 0; i < ctrl->discovery->numrec; i++) {
>>> +??????? len += snprintf(buf, PAGE_SIZE,
>>> +??????????????? "trtype %d adrfam %d traddr %s "
>>> +??????????????? "trsvcid %s portid %d subnqn %s\n",
>>> +??????????????? entry->trtype, entry->adrfam, entry->traddr,
>>> +??????????????? entry->trsvcid, le16_to_cpu(entry->portid),
>>> +??????????????? entry->subnqn);
>>> +??????? entry++;
>>> +??? }
>>> +??? return len;
>>> +}
>>> +static DEVICE_ATTR(discovery, S_IRUGO, nvme_discovery_show, NULL);
>>> +
>>
>> I really don't like that it's reporting a cached log. ? It may be
>> completely inconsistent with what's on the discovery controller now
>> (consider a nvmetcli done then a reconfig done). ?? There may not even
>> be connectivity to the discovery controller at the time the sysfs entry
>> is read - so validity to the content is in question.? I would much
>> rather have the attribute read the log then display contents - so it's
>> always current.??? Of course that does make it interesting if you read
>> it while the controller is paused doing a reconnect.
>>
> For the next round I'll split this patch in two, one for getting the
> discovery log and issueing uevents, and a next onw for the sysfs attribute.
> After all, I've implemented the sysfs attribute just for completeness,
> to show the contents of the internal discovery buffer. Re-reading it
> when reading kind of defeats that purpose IMO.
>
Actually, I think it would be better to make 'discovery' a _bin_ attribute.
With that 'nvme cli' could parse it directly without having to implement
yet another parser, we don't have this awkward multiple entry sysfs
attribute, and would actually provide additional value.
I'll give it a go.
Cheers,
Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
hare at suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)
next prev parent reply other threads:[~2018-08-22 8:51 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-21 13:43 [RFC PATCH 0/4] nvme async-connect and discovery uevents Hannes Reinecke
2018-08-21 13:43 ` [PATCH 1/4] nvme-rdma: use reconnect_work for initial connect Hannes Reinecke
2018-08-21 14:10 ` Max Gurtovoy
2018-08-21 14:18 ` Hannes Reinecke
2018-08-21 13:43 ` [PATCH 2/4] nvme: implement 'async_connect' cli option Hannes Reinecke
2018-08-21 21:01 ` James Smart
2018-08-21 13:43 ` [PATCH 3/4] nvme: implement 'discovery' sysfs entry and discovery uevents Hannes Reinecke
2018-08-21 21:01 ` James Smart
2018-08-22 7:23 ` Hannes Reinecke
2018-08-22 8:51 ` Hannes Reinecke [this message]
2018-08-21 13:43 ` [PATCH 4/4] nvme: delete discovery controller after 2 minutes Hannes Reinecke
2018-08-21 21:01 ` James Smart
2018-08-22 7:32 ` Hannes Reinecke
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=b5674a4c-ce2a-e536-45b3-fe4bab2ccccb@suse.de \
--to=hare@suse.de \
/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