With multipath enabled, nvme_scan_work() can read from the
device (through nvme_mpath_add_disk()). However, with fabrics,
once ctrl->state is set to NVME_CTRL_DELETING, the reads will hang
(see nvmf_check_ready()).
After setting the state to deleting, nvme_remove_namespaces() will
hang waiting for scan_work to flush and these tasks will hang.
To fix this, ensure we take scan_lock before changing the ctrl-state.
Also, ensure the state is checked while the lock is held
in nvme_scan_lock_work().
That's a big hammer...
I didn't think the scan_lock was that contested or that
nvme_change_ctrl_state() was really called that often...
But this is I/O that we cannot have queued until we have a path..
I would rather have nvme_remove_namespaces() requeue all I/Os for
namespaces that serve as the current_path and have the make_request
routine to fail I/O if all controllers are deleting as well.
Would something like [1] (untested) make sense instead?
I'll have to give this a try next week and I'll let you know then. It
kind of makes sense to me but a number of things I tried to fix this
that I thought made sense did not work.
+ÂÂÂ mutex_lock(&ctrl->scan_lock);
+
ÂÂÂÂÂ if (ctrl->state != NVME_CTRL_LIVE)
ÂÂÂÂÂÂÂÂÂ return;
unlock
If we unlock here and relock below, we'd have to recheck the ctrl->state
to avoid any races. If you don't want to call nvme_identify_ctrl with
the lock held, then it would probably be better to move the state check
below it.
 @@ -3547,7 +3554,6 @@ static void nvme_scan_work(struct work_struct
*work)
ÂÂÂÂÂ if (nvme_identify_ctrl(ctrl, &id))
ÂÂÂÂÂÂÂÂÂ return;
unlock