[PATCH 2/2] nvme: add context annotation for nvme_ns_head::nr_openers

Nilay Shroff nilay at linux.ibm.com
Mon Aug 31 08:19:55 PDT 2026


nvme_ns_head::nr_openers is protected by nvme_subsystem::lock. Annotate
it with __guarded_by(&subsys->lock) so that Clang's context analyzer can
validate that all accesses to nvme_ns_head::nr_openers are protected by
nvme_subsystem::lock.

Clang's context analyzer cannot currently model the same lock when it
is accessed through different object paths. Explicitly add the
capability in nvme_init_ns_head() using
__assume_ctx_lock(&head->subsys->lock) to avoid a false positive, as
ctrl->subsys->lock and head->subsys->lock refer to the same lock.

Similarly, in nvme_ns_remove(), replace ns->ctrl->subsys->lock with
ns->head->subsys->lock so that the lock expression matches the
capability used by the __guarded_by() annotation and avoids a false
positive from the context analyzer.

Cc: Marco Elver <elver at google.com>
Signed-off-by: Nilay Shroff <nilay at linux.ibm.com>
---
 drivers/nvme/host/core.c | 5 +++--
 drivers/nvme/host/nvme.h | 3 ++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index fdf760c57e02..29e3f2a7b5dd 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4173,6 +4173,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
 
 	list_add_tail_rcu(&ns->siblings, &head->list);
 	ns->head = head;
+	__assume_ctx_lock(&head->subsys->lock);
 	ret = nvme_module_get(ns, head->nr_openers);
 	if (ret)
 		goto out_err_module_get;
@@ -4368,7 +4369,7 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 	if (nvme_mpath_clear_current_path(ns))
 		synchronize_srcu(&ns->head->srcu);
 
-	mutex_lock(&ns->ctrl->subsys->lock);
+	mutex_lock(&ns->head->subsys->lock);
 	list_del_rcu(&ns->siblings);
 	if (list_empty(&ns->head->list)) {
 		if (!nvme_mpath_queue_if_no_path(ns->head))
@@ -4376,7 +4377,7 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 		last_path = true;
 	}
 	nvme_module_put(ns, ns->head->nr_openers);
-	mutex_unlock(&ns->ctrl->subsys->lock);
+	mutex_unlock(&ns->head->subsys->lock);
 
 	/* guarantee not available in head->list */
 	synchronize_srcu(&ns->head->srcu);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index db08f4618f92..d2b91140712c 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -569,7 +569,8 @@ struct nvme_ns_head {
 
 	struct gendisk		*disk;
 
-	unsigned int		nr_openers;
+	unsigned int		nr_openers
+		__guarded_by(&subsys->lock);
 
 	u16			nr_plids;
 	u16			*plids;
-- 
2.53.0




More information about the Linux-nvme mailing list