Re: [PATCH v2 05/14] nvmet: Send an AEN on CCR completion

Mohamed Khalfella
2026-02-03T18:48:11Z

On Tue 2026-02-03 04:27:39 +0100, Hannes Reinecke wrote:
> On 1/30/26 23:34, Mohamed Khalfella wrote:
> > Send an AEN to initiator when impacted controller exists. The
> > notification points to CCR log page that initiator can read to check
> > which CCR operation completed.
> >
> > Signed-off-by: Mohamed Khalfella <mkhalfella@purestorage.com>
> > ---
> > drivers/nvme/target/core.c | 25 ++++++++++++++++++++++---
> > drivers/nvme/target/nvmet.h | 3 ++-
> > include/linux/nvme.h | 3 +++
> > 3 files changed, 27 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
> > index 54dd0dcfa12b..ae2fe9f90bcd 100644
> > --- a/drivers/nvme/target/core.c
> > +++ b/drivers/nvme/target/core.c
> > @@ -202,7 +202,7 @@ static void nvmet_async_event_work(struct work_struct *work)
> > nvmet_async_events_process(ctrl);
> > }
> >
> > -void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
> > +static void nvmet_add_async_event_locked(struct nvmet_ctrl *ctrl, u8 event_type,
> > u8 event_info, u8 log_page)
> > {
> > struct nvmet_async_event *aen;
> > @@ -215,13 +215,19 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
> > aen->event_info = event_info;
> > aen->log_page = log_page;
> >
> > - mutex_lock(&ctrl->lock);
> > list_add_tail(&aen->entry, &ctrl->async_events);
> > - mutex_unlock(&ctrl->lock);
> >
> > queue_work(nvmet_wq, &ctrl->async_event_work);
> > }
> >
> > +void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
> > + u8 event_info, u8 log_page)
> > +{
> > + mutex_lock(&ctrl->lock);
> > + nvmet_add_async_event_locked(ctrl, event_type, event_info, log_page);
> > + mutex_unlock(&ctrl->lock);
> > +}
> > +
> > static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid)
> > {
> > u32 i;
> > @@ -1788,6 +1794,18 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args)
> > }
> > EXPORT_SYMBOL_GPL(nvmet_alloc_ctrl);
> >
> > +static void nvmet_ctrl_notify_ccr(struct nvmet_ctrl *ctrl)
> > +{
> > + lockdep_assert_held(&ctrl->lock);
> > +
> > + if (nvmet_aen_bit_disabled(ctrl, NVME_AEN_BIT_CCR_COMPLETE))
> > + return;
> > +
> > + nvmet_add_async_event_locked(ctrl, NVME_AER_NOTICE,
> > + NVME_AER_NOTICE_CCR_COMPLETED,
> > + NVME_LOG_CCR);
> > +}
> > +
> > static void nvmet_ctrl_complete_pending_ccr(struct nvmet_ctrl *ctrl)
> > {
> > struct nvmet_subsys *subsys = ctrl->subsys;
>
> But what does the CCR command actually _do_?
> At the very lease I would have expected it to trigger a controller reset
> (eg calling into nvmet_ctrl_fatal_error()), yet I don't see it doing
> that anywhere ...

[PATCH v2 03/14] nvmet: Implement CCR nvme command
is where impacted controller is told to fail. It does exactly what you
mentioned above.

+out_unlock:
+ mutex_unlock(&sctrl->lock);
+ if (status == NVME_SC_SUCCESS)
+ nvmet_ctrl_fatal_error(ictrl);
+ nvmet_ctrl_put(ictrl);
+out:
+ nvmet_req_complete(req, status);

I refactored the error handling codepath into success codepath. That is
why I think it is kind of hidden. If this is not obvious I can separate
the two codepaths. What do you think?