[RFC PATCH] nvme: Submit uevents for log page notification
Sagi Grimberg
sagi at grimberg.me
Thu Jun 15 02:41:44 PDT 2017
On 24/03/17 23:49, Keith Busch wrote:
> This is a first attempt at adding uevents to nvme. The concept was
> discussed at LSFMM, so here it is for consideration. :)
>
> In this implementation, the driver will submit a "change" uevent whenever
> the controller indicates a log page contains pertinent information. This
> happens in response to an Asynchronouse Event Notification, or if a
> command completes with the "MORE" status bit set. If there are other
> events anyone thinks we'd like udev to get a chance to handle, or would
> prefer to see these variables submitted to udev in a different format,
> please let me know.
>
> Submitting a uevent from the kernel can't be done from an irq context,
> which is the context the driver learns of such event, so this path
> enqueues the log identifier of internest on a FIFO, then has the async
> event work flush the event FIFO to udev. Pretty simple.
>
> Tested with the following rule to kick an nvme-cli generic get-log to
> clear the log request and append the returned log data to a temporary
> log. This is just an example for testing and not intended for real
> life use.
>
> ACTION=="change", SUBSYSTEM=="nvme", ENV{NVME_LOG}=="*", \
> RUN+="/bin/sh -c '/usr/local/sbin/nvme get-log $env{DEVNAME} --log-id=$env{NVME_LOG} --log-len=4096 >> /tmp/nvme-log'"
>
> Signed-off-by: Keith Busch <keith.busch at intel.com>
> ---
> drivers/nvme/host/core.c | 35 +++++++++++++++++++++++++++++++++--
> drivers/nvme/host/fc.c | 2 ++
> drivers/nvme/host/nvme.h | 4 ++++
> drivers/nvme/host/pci.c | 2 ++
> drivers/nvme/host/rdma.c | 2 ++
> drivers/nvme/target/loop.c | 2 ++
> include/linux/nvme.h | 2 ++
> 7 files changed, 47 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 9b3b57f..a757deb 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -1879,6 +1879,27 @@ static const struct attribute_group *nvme_dev_attr_groups[] = {
> NULL,
> };
>
> +void nvme_uevent_work(struct nvme_ctrl *ctrl, int log)
> +{
> + char buffer[13]; /* NVME_LOG=255\0 */
> + char *envp[2] = {buffer, NULL};
> +
> + snprintf(buffer, sizeof(buffer), "NVME_LOG=%d", log);
> + kobject_uevent_env(&ctrl->device->kobj, KOBJ_CHANGE, envp);
> +}
> +
> +void nvme_uevent(struct nvme_ctrl *ctrl, int log_page)
> +{
> + unsigned long flags;
> +
> + spin_lock_irqsave(&ctrl->lock, flags);
> + kfifo_put(&ctrl->log_event_fifo, log_page);
> + spin_unlock_irqrestore(&ctrl->lock, flags);
> +
Check kfifo_put rc?
> + schedule_work(&ctrl->async_event_work);
Can you explain why scheduling async_event_work (again) instead
of having a separate work for it?
Also, we should use the nvme_wq here to avoid a warning on flush
dependency violations on shutdown (see
dab469a893f40cdd9d41f52515a4ffa745bef655).
More information about the Linux-nvme
mailing list