Skip to content

Commit 6d1c699

Browse files
leitaokeithbusch
authored andcommitted
nvme/host: Fix RCU list traversal to use SRCU primitive
The code currently uses list_for_each_entry_rcu() while holding an SRCU lock, triggering false positive warnings with CONFIG_PROVE_RCU=y enabled: drivers/nvme/host/core.c:3770 RCU-list traversed in non-reader section!! While the list is properly protected by SRCU lock, the code uses the wrong list traversal primitive. Replace list_for_each_entry_rcu() with list_for_each_entry_srcu() to correctly indicate SRCU-based protection and eliminate the false warning. Fixes: be647e2 ("nvme: use srcu for iterating namespace list") Signed-off-by: Breno Leitao <leitao@debian.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Keith Busch <kbusch@kernel.org>
1 parent d0c6cc6 commit 6d1c699

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

drivers/nvme/host/core.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3795,7 +3795,8 @@ struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid)
37953795
int srcu_idx;
37963796

37973797
srcu_idx = srcu_read_lock(&ctrl->srcu);
3798-
list_for_each_entry_rcu(ns, &ctrl->namespaces, list) {
3798+
list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
3799+
srcu_read_lock_held(&ctrl->srcu)) {
37993800
if (ns->head->ns_id == nsid) {
38003801
if (!nvme_get_ns(ns))
38013802
continue;
@@ -4879,7 +4880,8 @@ void nvme_mark_namespaces_dead(struct nvme_ctrl *ctrl)
48794880
int srcu_idx;
48804881

48814882
srcu_idx = srcu_read_lock(&ctrl->srcu);
4882-
list_for_each_entry_rcu(ns, &ctrl->namespaces, list)
4883+
list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
4884+
srcu_read_lock_held(&ctrl->srcu))
48834885
blk_mark_disk_dead(ns->disk);
48844886
srcu_read_unlock(&ctrl->srcu, srcu_idx);
48854887
}
@@ -4891,7 +4893,8 @@ void nvme_unfreeze(struct nvme_ctrl *ctrl)
48914893
int srcu_idx;
48924894

48934895
srcu_idx = srcu_read_lock(&ctrl->srcu);
4894-
list_for_each_entry_rcu(ns, &ctrl->namespaces, list)
4896+
list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
4897+
srcu_read_lock_held(&ctrl->srcu))
48954898
blk_mq_unfreeze_queue(ns->queue);
48964899
srcu_read_unlock(&ctrl->srcu, srcu_idx);
48974900
clear_bit(NVME_CTRL_FROZEN, &ctrl->flags);
@@ -4904,7 +4907,8 @@ int nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout)
49044907
int srcu_idx;
49054908

49064909
srcu_idx = srcu_read_lock(&ctrl->srcu);
4907-
list_for_each_entry_rcu(ns, &ctrl->namespaces, list) {
4910+
list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
4911+
srcu_read_lock_held(&ctrl->srcu)) {
49084912
timeout = blk_mq_freeze_queue_wait_timeout(ns->queue, timeout);
49094913
if (timeout <= 0)
49104914
break;
@@ -4920,7 +4924,8 @@ void nvme_wait_freeze(struct nvme_ctrl *ctrl)
49204924
int srcu_idx;
49214925

49224926
srcu_idx = srcu_read_lock(&ctrl->srcu);
4923-
list_for_each_entry_rcu(ns, &ctrl->namespaces, list)
4927+
list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
4928+
srcu_read_lock_held(&ctrl->srcu))
49244929
blk_mq_freeze_queue_wait(ns->queue);
49254930
srcu_read_unlock(&ctrl->srcu, srcu_idx);
49264931
}
@@ -4933,7 +4938,8 @@ void nvme_start_freeze(struct nvme_ctrl *ctrl)
49334938

49344939
set_bit(NVME_CTRL_FROZEN, &ctrl->flags);
49354940
srcu_idx = srcu_read_lock(&ctrl->srcu);
4936-
list_for_each_entry_rcu(ns, &ctrl->namespaces, list)
4941+
list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
4942+
srcu_read_lock_held(&ctrl->srcu))
49374943
blk_freeze_queue_start(ns->queue);
49384944
srcu_read_unlock(&ctrl->srcu, srcu_idx);
49394945
}
@@ -4981,7 +4987,8 @@ void nvme_sync_io_queues(struct nvme_ctrl *ctrl)
49814987
int srcu_idx;
49824988

49834989
srcu_idx = srcu_read_lock(&ctrl->srcu);
4984-
list_for_each_entry_rcu(ns, &ctrl->namespaces, list)
4990+
list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
4991+
srcu_read_lock_held(&ctrl->srcu))
49854992
blk_sync_queue(ns->queue);
49864993
srcu_read_unlock(&ctrl->srcu, srcu_idx);
49874994
}

0 commit comments

Comments
 (0)