[PATCH v6 15/18] nvme-fc: Hold inflight requests while in FENCING state
Daniel Wagner
dwagner at suse.de
Tue Oct 20 05:21:59 PDT 2026
On Sun, Sep 20, 2026 at 11:28:13AM -0700, Mohamed Khalfella wrote:
> static void
> -nvme_fc_delete_association(struct nvme_fc_ctrl *ctrl)
> +__nvme_fc_teardown_association(struct nvme_fc_ctrl *ctrl)
> {
> struct nvmefc_ls_rcv_op *disls = NULL;
> unsigned long flags;
>
> - if (!test_and_clear_bit(ASSOC_ACTIVE, &ctrl->flags))
> - return;
> -
> spin_lock_irqsave(&ctrl->lock, flags);
> set_bit(FCCTRL_TERMIO, &ctrl->flags);
> - ctrl->iocnt = 0;
> + atomic_set(&ctrl->iocnt, 0);
> spin_unlock_irqrestore(&ctrl->lock, flags);
>
> __nvme_fc_abort_outstanding_ios(ctrl, false);
> @@ -3287,11 +3328,18 @@ nvme_fc_delete_association(struct nvme_fc_ctrl *ctrl)
> nvme_fc_abort_aen_ops(ctrl);
>
> /* wait for all io that had to be aborted */
> + wait_event(ctrl->ioabort_wait, atomic_read(&ctrl->iocnt) == 0);
> spin_lock_irq(&ctrl->lock);
> - wait_event_lock_irq(ctrl->ioabort_wait, ctrl->iocnt == 0, ctrl->lock);
> clear_bit(FCCTRL_TERMIO, &ctrl->flags);
> spin_unlock_irq(&ctrl->lock);
>
> + /*
> + * Wait for a started nvme_fc_fcpio_done() to complete before we
> + * proceed with cancelling inflight requests. This guarantees a
> + * request is completed by one of the two codepaths, not both.
> + */
> + synchronize_rcu();
> +
The synchronize_rcu() protects against nvme_cancel_tagset() racing with
an fcpio_done() for an op that completed normally and therefore wasn't
counted in iocnt. Wouldn't it be clearer to make the hold explicit in
op->state (e.g. FCPOP_STATE_HELD) and only complete held ops in
nvme_fc_flush_held_requests(), instead of using RCU as a barrier for
running callbacks?
More information about the Linux-nvme
mailing list