[PATCH] nvme: Support user mode processing of ZNS Zone Changed AEN
Sagi Grimberg
sagi at grimberg.me
Thu Sep 29 01:18:37 PDT 2022
> The ZNS Zone-Descriptor-Changes AEN is of type notify and uses CQE.DW1
> to convey the namespace of the log page to read. Unhandled notify AENs
> now generate an NVME_AEN uevent and include the value of CQE.DW1 as a
> new property when non-zero.
But you always send it...
>
> All unhandled notify events are include to avoid command set specific
> code in the aen handling. This support is planned to be used by both
> zone based applications and another unreleased device with an alternate
> command set.
This needs to be split into two patches.
>
> Signed-off-by: Clay Mayers <clay.mayers at kioxia.com>
> ---
> drivers/nvme/host/core.c | 19 +++++++++++--------
> drivers/nvme/host/nvme.h | 1 +
> 2 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 66446f1e06cf..fa865b8da1d3 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -4615,17 +4615,20 @@ static void nvme_change_uevent(struct nvme_ctrl *ctrl, char *envdata)
>
> static void nvme_aen_uevent(struct nvme_ctrl *ctrl)
> {
> - char *envp[2] = { NULL, NULL };
> + char *envp[3] = { NULL, NULL, NULL };
> u32 aen_result = ctrl->aen_result;
> + u32 aen_data = ctrl->aen_data;
>
> ctrl->aen_result = 0;
> + ctrl->aen_data = 0;
> if (!aen_result)
> return;
>
> envp[0] = kasprintf(GFP_KERNEL, "NVME_AEN=%#08x", aen_result);
> - if (!envp[0])
> - return;
> - kobject_uevent_env(&ctrl->device->kobj, KOBJ_CHANGE, envp);
> + envp[1] = kasprintf(GFP_KERNEL, "NVME_AEN_DATA=%#08x", aen_data);
> + if (envp[0] && envp[1])
> + kobject_uevent_env(&ctrl->device->kobj, KOBJ_CHANGE, envp);
> + kfree(envp[1]);
> kfree(envp[0]);
> }
>
> @@ -4748,11 +4751,9 @@ static bool nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
> queue_work(nvme_wq, &ctrl->ana_work);
> break;
> #endif
> - case NVME_AER_NOTICE_DISC_CHANGED:
> + default:
> ctrl->aen_result = result;
> break;
> - default:
> - dev_warn(ctrl->device, "async event result %08x\n", result);
I'd keep the log... and also don't know if we want to pass any unknown
possible spam to userspace... not sure that being blindly forward
compatible is the right choice here.
> }
> return requeue;
> }
> @@ -4799,8 +4800,10 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status,
> break;
> }
>
> - if (requeue)
> + if (requeue) {
> + ctrl->aen_data = le64_to_cpu(res->u64) >> 32;
Please use a helper for that.
aen_data is not a great name... maybe use a union for that for the
specific aen subtype?
Maybe it'd be better that zoned namespace aen is handled explicitly
and passes a AEN_NSID env veriable to the uevent.
> queue_work(nvme_wq, &ctrl->async_event_work);
> + }
> }
> EXPORT_SYMBOL_GPL(nvme_complete_async_event);
>
> diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
> index 1bdf714dcd9e..a1bab447dc65 100644
> --- a/drivers/nvme/host/nvme.h
> +++ b/drivers/nvme/host/nvme.h
> @@ -299,6 +299,7 @@ struct nvme_ctrl {
> u16 cctemp;
> u32 oaes;
> u32 aen_result;
> + u32 aen_data;
> u32 ctratt;
> unsigned int shutdown_timeout;
> unsigned int kato;
More information about the Linux-nvme
mailing list