Skip to content

Commit 30980ea

Browse files
nvmet: fix ns enable/disable possible hang
JIRA: https://issues.redhat.com/browse/RHEL-37676 When disabling an nvmet namespace, there is a period where the subsys->lock is released, as the ns disable waits for backend IO to complete, and the ns percpu ref to be properly killed. The original intent was to avoid taking the subsystem lock for a prolong period as other processes may need to acquire it (for example new incoming connections). However, it opens up a window where another process may come in and enable the ns, (re)intiailizing the ns percpu_ref, causing the disable sequence to hang. Solve this by taking the global nvmet_config_sem over the entire configfs enable/disable sequence. Fixes: a07b497 ("nvmet: add a generic NVMe target") Signed-off-by: Sagi Grimberg <sagi@grimberg.me> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com> Signed-off-by: Keith Busch <kbusch@kernel.org> (cherry picked from commit f97914e) Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
1 parent 0e5b8cd commit 30980ea

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

drivers/nvme/target/configfs.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,10 +676,18 @@ static ssize_t nvmet_ns_enable_store(struct config_item *item,
676676
if (kstrtobool(page, &enable))
677677
return -EINVAL;
678678

679+
/*
680+
* take a global nvmet_config_sem because the disable routine has a
681+
* window where it releases the subsys-lock, giving a chance to
682+
* a parallel enable to concurrently execute causing the disable to
683+
* have a misaccounting of the ns percpu_ref.
684+
*/
685+
down_write(&nvmet_config_sem);
679686
if (enable)
680687
ret = nvmet_ns_enable(ns);
681688
else
682689
nvmet_ns_disable(ns);
690+
up_write(&nvmet_config_sem);
683691

684692
return ret ? ret : count;
685693
}

0 commit comments

Comments
 (0)