* [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers
@ 2026-07-06 14:14 Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 01/18] nvme: update nvme_passthru_end() signature Nilay Shroff
` (17 more replies)
0 siblings, 18 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
This series adds support for Clang's context analysis to the NVMe host
drivers.
Recent work[1] by Marco Elver introduced infrastructure for lock context
analysis in the kernel, allowing Clang to verify locking requirements at
compile time through various annotations.
This series build on top of that infrastructure by annotating the NVMe
host drivers with the appropriate locking requirements and by addressing
warnings reported by the analyzer.
The series was built and tested with LLVM/Clang 23.x and enables the
NVMe host drivers to build cleanly with CONFIG_CONTEXT_ANALYSIS enabled.
Support for the NVMe target drivers will be addressed separately.
As usual, comments/feedback/suggestions are most welcome!
Thanks!
[1] https://lore.kernel.org/lkml/20251219154418.3592607-1-elver@google.com/
Changes from v2:
- removed "Clang" from each commit subject line (hch)
- for zero-initialized struct bio_list_init() is redundant and also to
suppress false-positive context analysis warning for a list variable
guarded by lock, remove bio_list_init(&head->requeue_list) from
nvme_mpath_alloc_disk() (hch)
- get rid off wrapping rcu_access_pointer() using context_unsafe() as
the access to __rcu_guarded pointer using helper rcu_access_pointer()
should be implicitly safe (hch, Marco, Paul)
- wrap INIT_LIST_HEAD() under context_unsafe(...) instead of interleaving
it under scoped_guard(...) to suppress context analysis warning while
initializing subsys->nsheads (hch)
- initializing head->delayed_removal_secs from nvme_mpath_alloc_disk() is
redudnamt as struct nvme_ns_head is zero allocated. This also helps
avoid false positive conext analysis warning (hch)
- introduce LIST_HEAD_GUARDED(_name, _lock) and use it for guarding a
list (hch)
- dropped context annotations for nvme_queue::cq_poll_lock as this
requires a annotation which could support guarding multiple
valid synchronization mechanisms for a single object, which is
,as of today, not yet avalilable (hch)
- new patch in the series from Marco Elver <elver@google.com>, which
annotates list_empty_careful() using __context_unsafe
- context_unsafe() has a statement expression inside so group
multiple scope guarded variables before those are publsihed
under context_unsafe(...) where possible (Marco)
Link to v2: https://lore.kernel.org/all/20260614131541.2017845-1-nilay@linux.ibm.com/
Changes from v1:
- replace guard() with scoped_guard() for guarding request_list (Bart)
- annotate nvme_alloc_ns_head() using __must_hold(&ctrl->subsys->lock)
(Sashiko)
- guard nvme_queue::sq_cmds using nvme_queue::sq_lock
- annotate nvme_cqe_pending() using context_unsafe in nvme_poll()
(Keith)
- Split patch #13 and #14 to separate the context annotation change
from functionality change (Bart)
Marco Elver (1):
list: Permit context-unguarded access with list_empty_careful()
Nilay Shroff (17):
nvme: update nvme_passthru_end() signature
nvme: add context annotations for nvme_passthru_{start|stop}
nvme: add context annotations for nvme_ns_head::srcu
nvme: add context annotations for nvme_ns_head::requeue_list
nvme: add context annotations for nvme_ns_head::current_path
nvme: add context annotations for nvme_dev::shutdown_lock
nvme: add context annotations for nvme_subsystem::lock
nvme: add context annotations for nvme_ctrl::ana_lock
list: introduce LIST_HEAD_GUARDED
nvme: add context annotations for nvme_subsystems_lock
nvme: add context annotations in fabric.c
nvme: add context annotations for nvme_queue::sq_lock
nvme: add context annotations in rdma.c
nvme: fix context analysis warning in rdma.c
nvme: add context annotations in tcp.c
nvme: fix context analysis warning in tcp.c
nvme: enable context analysis support for nvme host driver
drivers/nvme/host/Makefile | 1 +
drivers/nvme/host/core.c | 20 ++++++++++++----
drivers/nvme/host/fabrics.c | 4 ++--
drivers/nvme/host/ioctl.c | 2 +-
drivers/nvme/host/multipath.c | 7 ++++--
drivers/nvme/host/nvme.h | 44 ++++++++++++++++++++++++-----------
drivers/nvme/host/pci.c | 28 +++++++++++++++++-----
drivers/nvme/host/rdma.c | 25 ++++++++++++--------
drivers/nvme/host/tcp.c | 15 ++++++++----
include/linux/list.h | 9 +++++++
10 files changed, 110 insertions(+), 45 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 01/18] nvme: update nvme_passthru_end() signature
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 02/18] nvme: add context annotations for nvme_passthru_{start|stop} Nilay Shroff
` (16 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
Change nvme_passthru_end() to return the command effects value passed
to it.
This is a preparatory change for Clang's context/thread-safety analysis
support. The conditional release annotations (__cond_releases()) model
lock release based on a function's return value. Returning the existing
effects value allows a subsequent patch to annotate nvme_passthru_end()
as conditionally releasing locks acquired by nvme_passthru_start().
No functional change intended.
A follow-up patch will add the corresponding context analysis
annotations.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/core.c | 6 ++++--
drivers/nvme/host/nvme.h | 2 +-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 453c1f0b2dd0..d6a095e1e44e 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1268,7 +1268,7 @@ u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
}
EXPORT_SYMBOL_NS_GPL(nvme_passthru_start, "NVME_TARGET_PASSTHRU");
-void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects,
+u32 nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects,
struct nvme_command *cmd, int status)
{
if (effects & NVME_CMD_EFFECTS_CSE_MASK) {
@@ -1289,7 +1289,7 @@ void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects,
flush_work(&ctrl->scan_work);
}
if (ns)
- return;
+ return effects;
switch (cmd->common.opcode) {
case nvme_admin_set_features:
@@ -1310,6 +1310,8 @@ void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects,
default:
break;
}
+
+ return effects;
}
EXPORT_SYMBOL_NS_GPL(nvme_passthru_end, "NVME_TARGET_PASSTHRU");
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 824651cc898d..0797c3a6a9c1 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -1292,7 +1292,7 @@ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
u8 opcode);
u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode);
int nvme_execute_rq(struct request *rq, bool at_head);
-void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects,
+u32 nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects,
struct nvme_command *cmd, int status);
struct nvme_ctrl *nvme_ctrl_from_file(struct file *file);
struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 02/18] nvme: add context annotations for nvme_passthru_{start|stop}
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 01/18] nvme: update nvme_passthru_end() signature Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 03/18] nvme: add context annotations for nvme_ns_head::srcu Nilay Shroff
` (15 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
Annotate nvme_passthru_start() and nvme_passthru_end() for Clang
context/thread-safety analysis.
The __cond_acquires() and __cond_releases() annotations model
conditional lock acquisition and release based on a function's return
value. Use a nonzero return value as the abstract condition denoting
that the associated locks have been acquired or released.
This allows the analyzer to track the lock state across the
nvme_passthru_start() / nvme_passthru_end() pair and verify correct
locking semantics.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/nvme.h | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 0797c3a6a9c1..fba2d7674623 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -1290,10 +1290,16 @@ static inline void nvme_auth_revoke_tls_key(struct nvme_ctrl *ctrl) {};
u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
u8 opcode);
-u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode);
+u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
+ __cond_acquires(nonzero, &ctrl->subsys->lock)
+ __cond_acquires(nonzero, &ctrl->scan_lock);
+
int nvme_execute_rq(struct request *rq, bool at_head);
u32 nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects,
- struct nvme_command *cmd, int status);
+ struct nvme_command *cmd, int status)
+ __cond_releases(nonzero, &ctrl->scan_lock)
+ __cond_releases(nonzero, &ctrl->subsys->lock);
+
struct nvme_ctrl *nvme_ctrl_from_file(struct file *file);
struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid);
bool nvme_get_ns(struct nvme_ns *ns);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 03/18] nvme: add context annotations for nvme_ns_head::srcu
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 01/18] nvme: update nvme_passthru_end() signature Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 02/18] nvme: add context annotations for nvme_passthru_{start|stop} Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 04/18] nvme: add context annotations for nvme_ns_head::requeue_list Nilay Shroff
` (14 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
Add Clang lock context annotations for helpers that operate under
head->srcu read-side protection.
The path selection helpers invoked by nvme_find_path() access SRCU-
protected data through srcu_dereference() and therefore require the
caller to hold head->srcu. Annotate these helpers and nvme_find_path()
with __must_hold_shared(&head->srcu) so that Clang's lock context
analysis can verify the SRCU locking requirements across the call chain.
Also update nvme_ns_head_ctrl_ioctl() to use __releases_shared()
to match the shared SRCU read-side lock acquired through
srcu_read_lock().
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/ioctl.c | 2 +-
drivers/nvme/host/multipath.c | 4 ++++
drivers/nvme/host/nvme.h | 3 ++-
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index 664216eece4a..406e09a79c89 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -692,7 +692,7 @@ int nvme_ns_chr_uring_cmd_iopoll(struct io_uring_cmd *ioucmd,
static int nvme_ns_head_ctrl_ioctl(struct nvme_ns *ns, unsigned int cmd,
void __user *argp, struct nvme_ns_head *head, int srcu_idx,
bool open_for_write)
- __releases(&head->srcu)
+ __releases_shared(&head->srcu)
{
struct nvme_ctrl *ctrl = ns->ctrl;
int ret;
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 9b9a657fa330..e4ec5d5e2df1 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -306,6 +306,7 @@ static bool nvme_path_is_disabled(struct nvme_ns *ns)
}
static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head, int node)
+ __must_hold_shared(&head->srcu)
{
int found_distance = INT_MAX, fallback_distance = INT_MAX, distance;
struct nvme_ns *found = NULL, *fallback = NULL, *ns;
@@ -357,6 +358,7 @@ static struct nvme_ns *nvme_next_ns(struct nvme_ns_head *head,
}
static struct nvme_ns *nvme_round_robin_path(struct nvme_ns_head *head)
+ __must_hold_shared(&head->srcu)
{
struct nvme_ns *ns, *found = NULL;
int node = numa_node_id();
@@ -405,6 +407,7 @@ static struct nvme_ns *nvme_round_robin_path(struct nvme_ns_head *head)
}
static struct nvme_ns *nvme_queue_depth_path(struct nvme_ns_head *head)
+ __must_hold_shared(&head->srcu)
{
struct nvme_ns *best_opt = NULL, *best_nonopt = NULL, *ns;
unsigned int min_depth_opt = UINT_MAX, min_depth_nonopt = UINT_MAX;
@@ -448,6 +451,7 @@ static inline bool nvme_path_is_optimized(struct nvme_ns *ns)
}
static struct nvme_ns *nvme_numa_path(struct nvme_ns_head *head)
+ __must_hold_shared(&head->srcu)
{
int node = numa_node_id();
struct nvme_ns *ns;
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index fba2d7674623..b7c3ba9c0fc1 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -1032,7 +1032,8 @@ extern const struct attribute_group *nvme_dev_attr_groups[];
extern const struct block_device_operations nvme_bdev_ops;
void nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl);
-struct nvme_ns *nvme_find_path(struct nvme_ns_head *head);
+struct nvme_ns *nvme_find_path(struct nvme_ns_head *head)
+ __must_hold_shared(&head->srcu);
#ifdef CONFIG_NVME_MULTIPATH
static inline bool nvme_ctrl_use_ana(struct nvme_ctrl *ctrl)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 04/18] nvme: add context annotations for nvme_ns_head::requeue_list
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (2 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 03/18] nvme: add context annotations for nvme_ns_head::srcu Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 05/18] nvme: add context annotations for nvme_ns_head::current_path Nilay Shroff
` (13 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
nvme_ns_head::requeue_list is protected by
nvme_ns_head::requeue_lock. Annotate requeue_list with
__guarded_by(&requeue_lock) so that Clang's context analysis can
validate accesses to the list.
For zero-initialized objects, bio_list_init() is a no-op. Remove the
redundant initialization from nvme_mpath_alloc_disk(), which
initializes nvme_ns_head::requeue_list. Besides simplifying the code,
this also avoids a false positive from Clang's context analysis, which
would otherwise warn about accessing nvme_ns_head::requeue_list
without holding nvme_ns_head::requeue_lock.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/multipath.c | 1 -
drivers/nvme/host/nvme.h | 3 ++-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index e4ec5d5e2df1..67fd0752e894 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -732,7 +732,6 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
struct queue_limits lim;
mutex_init(&head->lock);
- bio_list_init(&head->requeue_list);
spin_lock_init(&head->requeue_lock);
INIT_WORK(&head->requeue_work, nvme_requeue_work);
INIT_WORK(&head->partition_scan_work, nvme_partition_scan_work);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index b7c3ba9c0fc1..5e746ae1c805 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -561,7 +561,8 @@ struct nvme_ns_head {
u16 nr_plids;
u16 *plids;
#ifdef CONFIG_NVME_MULTIPATH
- struct bio_list requeue_list;
+ struct bio_list requeue_list
+ __guarded_by(&requeue_lock);
spinlock_t requeue_lock;
struct work_struct requeue_work;
struct work_struct partition_scan_work;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 05/18] nvme: add context annotations for nvme_ns_head::current_path
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (3 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 04/18] nvme: add context annotations for nvme_ns_head::requeue_list Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 16:08 ` Paul E. McKenney
2026-07-06 14:14 ` [PATCH v3 06/18] nvme: add context annotations for nvme_dev::shutdown_lock Nilay Shroff
` (12 subsequent siblings)
17 siblings, 1 reply; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff,
Paul E. McKenney
Annotate nvme_ns_head::current_path[] with __rcu_guarded so that
Clang's context analysis can validate accesses to the SRCU/RCU
protected pointer.
Cc: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/nvme.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 5e746ae1c805..610c685e2263 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -575,7 +575,7 @@ struct nvme_ns_head {
#define NVME_NSHEAD_DISK_LIVE 0
#define NVME_NSHEAD_QUEUE_IF_NO_PATH 1
#define NVME_NSHEAD_CDEV_LIVE 2
- struct nvme_ns __rcu *current_path[];
+ struct nvme_ns __rcu_guarded *current_path[];
#endif
};
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 06/18] nvme: add context annotations for nvme_dev::shutdown_lock
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (4 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 05/18] nvme: add context annotations for nvme_ns_head::current_path Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 07/18] nvme: add context annotations for nvme_subsystem::lock Nilay Shroff
` (11 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
nvme_setup_io_queues_trylock() conditionally acquires dev->shutdown_lock
using mutex_trylock(). The function returns 0 when the lock is
successfully acquired and a negative error code otherwise.
Annotate the function with __cond_acquires(0, &dev->shutdown_lock) so
that Clang's lock context analysis can track the lock state based on
the return value and verify correct lock usage at call sites.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/pci.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 69932d640b53..7954417d1252 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2199,6 +2199,7 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid)
* Try getting shutdown_lock while setting up IO queues.
*/
static int nvme_setup_io_queues_trylock(struct nvme_dev *dev)
+ __cond_acquires(0, &dev->shutdown_lock)
{
/*
* Give up if the lock is being held by nvme_dev_disable.
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 07/18] nvme: add context annotations for nvme_subsystem::lock
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (5 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 06/18] nvme: add context annotations for nvme_dev::shutdown_lock Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 08/18] nvme: add context annotations for nvme_ctrl::ana_lock Nilay Shroff
` (10 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
Several helpers access or traverse data structures protected by
nvme_subsystem::lock and therefore require callers to hold the lock.
Annotate nvme_mpath_unfreeze(), nvme_mpath_wait_freeze(),
nvme_mpath_start_freeze(), nvme_find_ns_head(), nvme_alloc_ns_head()
and nvme_subsys_check_duplicate_ids() with __must_hold(&subsys->lock)
so that Clang's lock context analysis can validate the locking
requirements at compile time.
Also annotate nvme_subsystem::nsheads and
nvme_ns_head::delayed_removal_secs with __guarded_by(&subsys->lock),
as both are protected by the subsystem lock.
Wrap the initialization of nvme_subsystem::nsheads with
context_unsafe(...) to suppress the context analysis warning emitted
for INIT_LIST_HEAD() during object initialization.
nvme_ns_head is allocated with kzalloc(), so explicitly initializing
nvme_ns_head::delayed_removal_secs to 0 in nvme_mpath_alloc_disk() is
redundant. Remove the redundant initialization, which also avoids a
false positive from Clang's context analysis.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/core.c | 6 +++++-
drivers/nvme/host/multipath.c | 1 -
drivers/nvme/host/nvme.h | 15 ++++++++++-----
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index d6a095e1e44e..9cdde56c97bc 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3286,7 +3286,8 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
mutex_init(&subsys->lock);
kref_init(&subsys->ref);
INIT_LIST_HEAD(&subsys->ctrls);
- INIT_LIST_HEAD(&subsys->nsheads);
+ /* Initialize unpublished lock-guarded variable. */
+ context_unsafe(INIT_LIST_HEAD(&subsys->nsheads));
nvme_init_subnqn(subsys, ctrl, id);
memcpy(subsys->serial, id->sn, sizeof(subsys->serial));
memcpy(subsys->model, id->mn, sizeof(subsys->model));
@@ -3845,6 +3846,7 @@ static const struct file_operations nvme_dev_fops = {
static struct nvme_ns_head *nvme_find_ns_head(struct nvme_ctrl *ctrl,
unsigned nsid)
+ __must_hold(&ctrl->subsys->lock)
{
struct nvme_ns_head *h;
@@ -3867,6 +3869,7 @@ static struct nvme_ns_head *nvme_find_ns_head(struct nvme_ctrl *ctrl,
static int nvme_subsys_check_duplicate_ids(struct nvme_subsystem *subsys,
struct nvme_ns_ids *ids)
+ __must_hold(&subsys->lock)
{
bool has_uuid = !uuid_is_null(&ids->uuid);
bool has_nguid = memchr_inv(ids->nguid, 0, sizeof(ids->nguid));
@@ -3968,6 +3971,7 @@ static void nvme_add_ns_cdev(struct nvme_ns *ns)
static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
struct nvme_ns_info *info)
+ __must_hold(&ctrl->subsys->lock)
{
struct nvme_ns_head *head;
size_t size = sizeof(*head);
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 67fd0752e894..765c3fac2823 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -736,7 +736,6 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
INIT_WORK(&head->requeue_work, nvme_requeue_work);
INIT_WORK(&head->partition_scan_work, nvme_partition_scan_work);
INIT_DELAYED_WORK(&head->remove_work, nvme_remove_head_work);
- head->delayed_removal_secs = 0;
/*
* If "multipath_always_on" is enabled, a multipath node is added
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 610c685e2263..602d567f3def 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -496,7 +496,8 @@ struct nvme_subsystem {
struct list_head entry;
struct mutex lock;
struct list_head ctrls;
- struct list_head nsheads;
+ struct list_head nsheads
+ __guarded_by(&lock);
char subnqn[NVMF_NQN_SIZE];
char serial[20];
char model[40];
@@ -569,7 +570,8 @@ struct nvme_ns_head {
struct mutex lock;
unsigned long flags;
struct delayed_work remove_work;
- unsigned int delayed_removal_secs;
+ unsigned int delayed_removal_secs
+ __guarded_by(&subsys->lock);
atomic_long_t io_requeue_no_usable_path_count;
atomic_long_t io_fail_no_available_path_count;
#define NVME_NSHEAD_DISK_LIVE 0
@@ -1041,9 +1043,12 @@ static inline bool nvme_ctrl_use_ana(struct nvme_ctrl *ctrl)
return ctrl->ana_log_buf != NULL;
}
-void nvme_mpath_unfreeze(struct nvme_subsystem *subsys);
-void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys);
-void nvme_mpath_start_freeze(struct nvme_subsystem *subsys);
+void nvme_mpath_unfreeze(struct nvme_subsystem *subsys)
+ __must_hold(&subsys->lock);
+void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys)
+ __must_hold(&subsys->lock);
+void nvme_mpath_start_freeze(struct nvme_subsystem *subsys)
+ __must_hold(&subsys->lock);
void nvme_mpath_default_iopolicy(struct nvme_subsystem *subsys);
void nvme_failover_req(struct request *req);
void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 08/18] nvme: add context annotations for nvme_ctrl::ana_lock
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (6 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 07/18] nvme: add context annotations for nvme_subsystem::lock Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 09/18] list: introduce LIST_HEAD_GUARDED Nilay Shroff
` (9 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
nvme_parse_ana_log() accesses ANA state protected by ctrl->ana_lock and
therefore requires callers to hold the lock.
Annotate nvme_parse_ana_log() with __must_hold(&ctrl->ana_lock) so that
Clang's lock context analysis can verify the locking requirement at
compile time.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/multipath.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 765c3fac2823..47d3a3b30a1a 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -827,6 +827,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
static int nvme_parse_ana_log(struct nvme_ctrl *ctrl, void *data,
int (*cb)(struct nvme_ctrl *ctrl, struct nvme_ana_group_desc *,
void *))
+ __must_hold(&ctrl->ana_lock)
{
void *base = ctrl->ana_log_buf;
size_t offset = sizeof(struct nvme_ana_rsp_hdr);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 09/18] list: introduce LIST_HEAD_GUARDED
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (7 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 08/18] nvme: add context annotations for nvme_ctrl::ana_lock Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 10/18] nvme: add context annotations for nvme_subsystems_lock Nilay Shroff
` (8 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
Introduce LIST_HEAD_GUARDED(name, lock) to define a struct list_head
annotated with __guarded_by(lock). This provides a convenient shorthand
for defining lock-protected list heads and allows compiler context
analysis to validate accesses to the list against the associated lock.
The new helper also reduces boilerplate and improves consistency across
callers that annotate struct list_head objects with __guarded_by().
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
include/linux/list.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/include/linux/list.h b/include/linux/list.h
index 09d979976b3b..f6f22c8b06f7 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -33,6 +33,14 @@
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
+/**
+ * LIST_HEAD_GUARDED - define a &struct list_head annotated with __guarded_by()
+ * @name: name of the list_head
+ * @lock: lock protecting the list
+ */
+#define LIST_HEAD_GUARDED(name, lock) \
+ __guarded_by(&(lock)) LIST_HEAD(name)
+
/**
* INIT_LIST_HEAD - Initialize a list_head structure
* @list: list_head structure to be initialized.
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 10/18] nvme: add context annotations for nvme_subsystems_lock
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (8 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 09/18] list: introduce LIST_HEAD_GUARDED Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 11/18] nvme: add context annotations in fabric.c Nilay Shroff
` (7 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
The global nvme_subsystems list, nvme_subsystem::entry,
nvme_subsystem::ctrls, and nvme_ctrl::subsys_entry are protected by
nvme_subsystems_lock. Annotate these objects with
__guarded_by(&nvme_subsystems_lock) so that Clang's context analysis
can validate accesses to them.
__nvme_find_get_subsystem() and nvme_validate_cntlid() traverse the
global subsystem list and subsystem controller list and therefore
require callers to hold nvme_subsystems_lock. Annotate both helpers
with __must_hold(&nvme_subsystems_lock).
The initialization of nvme_subsystem::ctrls in nvme_init_subsystem()
occurs before the subsystem is published and therefore does not require
protection by nvme_subsystems_lock. Annotate the initialization with
context_unsafe() to suppress the corresponding context analysis
warning.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/core.c | 12 ++++++++----
drivers/nvme/host/nvme.h | 9 ++++++---
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 9cdde56c97bc..01346c46bfde 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -126,8 +126,8 @@ EXPORT_SYMBOL_GPL(nvme_reset_wq);
struct workqueue_struct *nvme_delete_wq;
EXPORT_SYMBOL_GPL(nvme_delete_wq);
-static LIST_HEAD(nvme_subsystems);
DEFINE_MUTEX(nvme_subsystems_lock);
+static LIST_HEAD_GUARDED(nvme_subsystems, nvme_subsystems_lock);
static DEFINE_IDA(nvme_instance_ida);
static dev_t nvme_ctrl_base_chr_devt;
@@ -3200,6 +3200,7 @@ static void nvme_put_subsystem(struct nvme_subsystem *subsys)
}
static struct nvme_subsystem *__nvme_find_get_subsystem(const char *subsysnqn)
+ __must_hold(&nvme_subsystems_lock)
{
struct nvme_subsystem *subsys;
@@ -3244,6 +3245,7 @@ static inline bool nvme_is_io_ctrl(struct nvme_ctrl *ctrl)
static bool nvme_validate_cntlid(struct nvme_subsystem *subsys,
struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
+ __must_hold(&nvme_subsystems_lock)
{
struct nvme_ctrl *tmp;
@@ -3285,9 +3287,11 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
subsys->instance = -1;
mutex_init(&subsys->lock);
kref_init(&subsys->ref);
- INIT_LIST_HEAD(&subsys->ctrls);
- /* Initialize unpublished lock-guarded variable. */
- context_unsafe(INIT_LIST_HEAD(&subsys->nsheads));
+ /* Initialize unpublished lock-guarded variables. */
+ context_unsafe(
+ INIT_LIST_HEAD(&subsys->ctrls);
+ INIT_LIST_HEAD(&subsys->nsheads);
+ );
nvme_init_subnqn(subsys, ctrl, id);
memcpy(subsys->serial, id->sn, sizeof(subsys->serial));
memcpy(subsys->model, id->mn, sizeof(subsys->model));
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 602d567f3def..607fa9664272 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -361,7 +361,8 @@ struct nvme_ctrl {
wait_queue_head_t state_wq;
struct nvme_subsystem *subsys;
- struct list_head subsys_entry;
+ struct list_head subsys_entry
+ __guarded_by(&nvme_subsystems_lock);
struct opal_dev *opal_dev;
@@ -493,9 +494,11 @@ struct nvme_subsystem {
* a separate refcount.
*/
struct kref ref;
- struct list_head entry;
+ struct list_head entry
+ __guarded_by(&nvme_subsystems_lock);
struct mutex lock;
- struct list_head ctrls;
+ struct list_head ctrls
+ __guarded_by(&nvme_subsystems_lock);
struct list_head nsheads
__guarded_by(&lock);
char subnqn[NVMF_NQN_SIZE];
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 11/18] nvme: add context annotations in fabric.c
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (9 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 10/18] nvme: add context annotations for nvme_subsystems_lock Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 12/18] nvme: add context annotations for nvme_queue::sq_lock Nilay Shroff
` (6 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
The global nvmf_transports list is protected by nvmf_transports_rwsem
and the global nvmf_hosts list is protected by nvmf_hosts_mutex.
Define both lists using INIT_LIST_GUARDED() so that Clang's context
analysis can validate accesses to the lists against the corresponding
locking requirements.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/fabrics.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index ac3d4f400601..fd5abd04e080 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -14,11 +14,11 @@
#include "fabrics.h"
#include <linux/nvme-keyring.h>
-static LIST_HEAD(nvmf_transports);
static DECLARE_RWSEM(nvmf_transports_rwsem);
+static LIST_HEAD_GUARDED(nvmf_transports, nvmf_transports_rwsem);
-static LIST_HEAD(nvmf_hosts);
static DEFINE_MUTEX(nvmf_hosts_mutex);
+static LIST_HEAD_GUARDED(nvmf_hosts, nvmf_hosts_mutex);
static struct nvmf_host *nvmf_default_host;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 12/18] nvme: add context annotations for nvme_queue::sq_lock
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (10 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 11/18] nvme: add context annotations in fabric.c Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 13/18] nvme: add context annotations in rdma.c Nilay Shroff
` (5 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
nvme_queue::sq_tail, nvme_queue::last_sq_tail and nvme_queue::sq_cmds
are protected by nvme_queue::sq_lock. Annotate each field with
__guarded_by(&sq_lock) and annotate helpers that access them with
__must_hold(&sq_lock) so that Clang's context analysis can validate
the locking requirements.
Access to nvme_queue::sq_tail used solely for tracing is annotated with
data_race(), as they only require a lockless snapshot of the value.
nvme_init_queue() initializes nvme_queue::sq_tail and
nvme_queue::last_sq_tail before the queue is published and thus do not
require nvme_queue::sq_lock protection. So wrap the corresponding
initializations with context_unsafe().
nvme_free_queue() operate on queues which are no longer reachable, and
therefore do not require nvme_queue::sq_lock protection. Similarly,
nvme_alloc_sq_cmds() allocates memory for nvme_queue::sq_cmds for the
queue which is not yet published or in use and hence it's safe to
annotate all these helpers using context_unsafe.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/pci.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 7954417d1252..11720342a6b7 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -366,7 +366,8 @@ struct nvme_queue {
struct nvme_dev *dev;
struct nvme_descriptor_pools descriptor_pools;
spinlock_t sq_lock;
- void *sq_cmds;
+ void *sq_cmds
+ __guarded_by(&sq_lock);
/* only used for poll queues: */
spinlock_t cq_poll_lock ____cacheline_aligned_in_smp;
struct nvme_completion *cqes;
@@ -375,9 +376,11 @@ struct nvme_queue {
u32 __iomem *q_db;
u32 q_depth;
u16 cq_vector;
- u16 sq_tail;
- u16 last_sq_tail;
u16 cq_head;
+ u16 sq_tail
+ __guarded_by(&sq_lock);
+ u16 last_sq_tail
+ __guarded_by(&sq_lock);
u16 qid;
u8 cq_phase;
u8 sqes;
@@ -716,6 +719,7 @@ static void nvme_pci_map_queues(struct blk_mq_tag_set *set)
* Write sq tail if we are asked to, or if the next command would wrap.
*/
static inline void nvme_write_sq_db(struct nvme_queue *nvmeq, bool write_sq)
+ __must_hold(&nvmeq->sq_lock)
{
if (!write_sq) {
u16 next_tail = nvmeq->sq_tail + 1;
@@ -734,6 +738,7 @@ static inline void nvme_write_sq_db(struct nvme_queue *nvmeq, bool write_sq)
static inline void nvme_sq_copy_cmd(struct nvme_queue *nvmeq,
struct nvme_command *cmd)
+ __must_hold(&nvmeq->sq_lock)
{
memcpy(nvmeq->sq_cmds + (nvmeq->sq_tail << nvmeq->sqes),
absolute_pointer(cmd), sizeof(*cmd));
@@ -1586,7 +1591,12 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq,
return;
}
- trace_nvme_sq(req, cqe->sq_head, nvmeq->sq_tail);
+ /*
+ * Tracing only; annotate a lockless snapshot of nvmeq->sq_tail using
+ * data_race(). This would also help suppress context analysis warning
+ * while accessing nvmeq->sq_tail without acquiring ->sq_lock.
+ */
+ trace_nvme_sq(req, cqe->sq_head, data_race(nvmeq->sq_tail));
if (!nvme_try_complete_req(req, cqe->status, cqe->result) &&
!blk_mq_add_to_batch(req, iob,
nvme_req(req)->status != NVME_SC_SUCCESS,
@@ -2013,6 +2023,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
}
static void nvme_free_queue(struct nvme_queue *nvmeq)
+ __context_unsafe(/* frees queue which is no longer in use */)
{
dma_free_coherent(nvmeq->dev->dev, CQ_SIZE(nvmeq),
(void *)nvmeq->cqes, nvmeq->cq_dma_addr);
@@ -2107,6 +2118,7 @@ static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues,
static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq,
int qid)
+ __context_unsafe(/* safe to allocate sq_cmds without any protection */)
{
struct pci_dev *pdev = to_pci_dev(dev->dev);
@@ -2184,8 +2196,11 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid)
{
struct nvme_dev *dev = nvmeq->dev;
- nvmeq->sq_tail = 0;
- nvmeq->last_sq_tail = 0;
+ /* Initialize unpublished lock-guarded variables. */
+ context_unsafe(
+ nvmeq->sq_tail = 0;
+ nvmeq->last_sq_tail = 0;
+ );
nvmeq->cq_head = 0;
nvmeq->cq_phase = 1;
nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride];
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 13/18] nvme: add context annotations in rdma.c
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (11 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 12/18] nvme: add context annotations for nvme_queue::sq_lock Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 14/18] list: Permit context-unguarded access with list_empty_careful() Nilay Shroff
` (4 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
device_list and nvme_rdma_device::entry are protected by
device_list_mutex. Define device_list using
LIST_HEAD_GUARDED(device_list, device_list_mutex) and annotate
nvme_rdma_device::entry with __guarded_by(&device_list_mutex) so that
Clang's context analysis can validate accesses against the corresponding
locking requirements.
Similarly, nvme_rdma_ctrl_list and nvme_rdma_ctrl::list are
protected by nvme_rdma_ctrl_mutex. Define nvme_rdma_ctrl_list using
LIST_HEAD_GUARDED(nvme_rdma_ctrl_list, nvme_rdma_ctrl_mutex) and
annotate nvme_rdma_ctrl::list with __guarded_by(&nvme_rdma_ctrl_mutex).
It is safe to initialize nvme_rdma_ctrl::list while allocating the
controller object because the list entry has not yet been added to
nvme_rdma_ctrl_list. Annotate the initialization with context_unsafe()
to suppress the corresponding Clang context analysis warning.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/rdma.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 6909e3542794..bf392035037a 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -39,11 +39,18 @@
#define NVME_RDMA_METADATA_SGL_SIZE \
(sizeof(struct scatterlist) * NVME_INLINE_METADATA_SG_CNT)
+static DEFINE_MUTEX(device_list_mutex);
+static LIST_HEAD_GUARDED(device_list, device_list_mutex);
+
+static DEFINE_MUTEX(nvme_rdma_ctrl_mutex);
+static LIST_HEAD_GUARDED(nvme_rdma_ctrl_list, nvme_rdma_ctrl_mutex);
+
struct nvme_rdma_device {
struct ib_device *dev;
struct ib_pd *pd;
struct kref ref;
- struct list_head entry;
+ struct list_head entry
+ __guarded_by(&device_list_mutex);
unsigned int num_inline_segments;
};
@@ -112,7 +119,8 @@ struct nvme_rdma_ctrl {
struct delayed_work reconnect_work;
- struct list_head list;
+ struct list_head list
+ __guarded_by(&nvme_rdma_ctrl_mutex);
struct blk_mq_tag_set admin_tag_set;
struct nvme_rdma_device *device;
@@ -132,12 +140,6 @@ static inline struct nvme_rdma_ctrl *to_rdma_ctrl(struct nvme_ctrl *ctrl)
return container_of(ctrl, struct nvme_rdma_ctrl, ctrl);
}
-static LIST_HEAD(device_list);
-static DEFINE_MUTEX(device_list_mutex);
-
-static LIST_HEAD(nvme_rdma_ctrl_list);
-static DEFINE_MUTEX(nvme_rdma_ctrl_mutex);
-
/*
* Disabling this option makes small I/O goes faster, but is fundamentally
* unsafe. With it turned off we will have to register a global rkey that
@@ -2254,7 +2256,10 @@ static struct nvme_rdma_ctrl *nvme_rdma_alloc_ctrl(struct device *dev,
if (!ctrl)
return ERR_PTR(-ENOMEM);
ctrl->ctrl.opts = opts;
- INIT_LIST_HEAD(&ctrl->list);
+ /*
+ * Safe to init list while allocating ctrl object.
+ */
+ context_unsafe(INIT_LIST_HEAD(&ctrl->list));
if (!(opts->mask & NVMF_OPT_TRSVCID)) {
opts->trsvcid =
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 14/18] list: Permit context-unguarded access with list_empty_careful()
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (12 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 13/18] nvme: add context annotations in rdma.c Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 15/18] nvme: fix context analysis warning in rdma.c Nilay Shroff
` (3 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
From: Marco Elver <elver@google.com>
With Context Analysis (viz. Clang's Thread Safety Analysis), list_heads
that are __guarded_by(..) require holding the appropriate context lock
when accessing and manipulating them via the list API. Because Clang's
warning diagnostics do not perform inter-procedural analysis, this is
enforced by Clang with -Wthread-safety-pointer in the caller at the call
boundary; a warning is produced when passing a pointer to a guarded
variable without holding the appropriate context locks:
warning: passing pointer to variable 'list' requires holding [...] [-Wthread-safety-pointer]
if (list_empty(&ctrl->list))
An exception is list_empty_careful(), which is like list_empty(), except
that it is permitted to use without holding any context lock (carefully).
Mark list_empty_careful() __context_unsafe, which disables context
analysis within list_empty_careful(), but also suppresses warnings
generated in callers related to its pointer arguments.
Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
include/linux/list.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/list.h b/include/linux/list.h
index f6f22c8b06f7..19212bfc3f6d 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -444,6 +444,7 @@ static inline void list_del_init_careful(struct list_head *entry)
* if another CPU could re-list_add() it.
*/
static inline int list_empty_careful(const struct list_head *head)
+ __context_unsafe(/* intentional lockless access to @head */)
{
struct list_head *next = smp_load_acquire(&head->next);
return list_is_head(next, head) && (next == READ_ONCE(head->prev));
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 15/18] nvme: fix context analysis warning in rdma.c
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (13 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 14/18] list: Permit context-unguarded access with list_empty_careful() Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 16/18] nvme: add context annotations in tcp.c Nilay Shroff
` (2 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
After adding Clang lock context annotations in rdma.c, Clang reports
the following warning when context analysis is enabled:
drivers/nvme/host/rdma.c:972:24: warning: passing pointer to variable 'list' requires holding mutex 'nvme_rdma_ctrl_mutex'
[-Wthread-safety-pointer]
972 | if (list_empty(&ctrl->list))
| ^
The warning is triggered because ctrl->list is annotated as being
protected by nvme_rdma_ctrl_mutex, but list_empty(&ctrl->list) is
invoked without holding that mutex.
Replace list_empty() with list_empty_careful(), which is intended
for lockless inspection of list heads during teardown when no concurrent
list modifications are expected. This suppresses the corresponding
context analysis warning while preserving the existing behavior.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/rdma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index bf392035037a..cdd8837da03a 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -971,7 +971,7 @@ static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl)
{
struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl);
- if (list_empty(&ctrl->list))
+ if (list_empty_careful(&ctrl->list))
goto free_ctrl;
mutex_lock(&nvme_rdma_ctrl_mutex);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 16/18] nvme: add context annotations in tcp.c
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (14 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 15/18] nvme: fix context analysis warning in rdma.c Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 17/18] nvme: fix context analysis warning " Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 18/18] nvme: enable context analysis support for nvme host driver Nilay Shroff
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
The nvme_tcp_ctrl_list and nvme_tcp_ctrl::list are protected by
nvme_tcp_ctrl_mutex. Define nvme_tcp_ctrl_list using
LIST_HEAD_GUARDED(nvme_tcp_ctrl_list, nvme_tcp_ctrl_mutex) and
annotate nvme_tcp_ctrl::list using
__guarded_by(&nvme_tcp_ctrl_mutex) so that Clang's context analysis
can validate accesses against the corresponding locking requirements.
It is safe to initialize nvme_tcp_ctrl::list while allocating the
controller object because the list entry has not yet been added to
nvme_tcp_ctrl_list. Annotate the initialization with context_unsafe()
to suppress the corresponding Clang warning.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/tcp.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index ba5c7b3e2a7c..8d2fbfc7cd8d 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -149,13 +149,17 @@ struct nvme_tcp_queue {
#endif
};
+static DEFINE_MUTEX(nvme_tcp_ctrl_mutex);
+static LIST_HEAD_GUARDED(nvme_tcp_ctrl_list, nvme_tcp_ctrl_mutex);
+
struct nvme_tcp_ctrl {
/* read only in the hot path */
struct nvme_tcp_queue *queues;
struct blk_mq_tag_set tag_set;
/* other member variables */
- struct list_head list;
+ struct list_head list
+ __guarded_by(&nvme_tcp_ctrl_mutex);
struct blk_mq_tag_set admin_tag_set;
struct sockaddr_storage addr;
struct sockaddr_storage src_addr;
@@ -167,8 +171,6 @@ struct nvme_tcp_ctrl {
u32 io_queues[HCTX_MAX_TYPES];
};
-static LIST_HEAD(nvme_tcp_ctrl_list);
-static DEFINE_MUTEX(nvme_tcp_ctrl_mutex);
static struct workqueue_struct *nvme_tcp_wq;
static const struct blk_mq_ops nvme_tcp_mq_ops;
static const struct blk_mq_ops nvme_tcp_admin_mq_ops;
@@ -2919,7 +2921,10 @@ static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(struct device *dev,
if (!ctrl)
return ERR_PTR(-ENOMEM);
- INIT_LIST_HEAD(&ctrl->list);
+ /*
+ * Safe to init list while allocating ctrl object.
+ */
+ context_unsafe(INIT_LIST_HEAD(&ctrl->list));
ctrl->ctrl.opts = opts;
ctrl->ctrl.queue_count = opts->nr_io_queues + opts->nr_write_queues +
opts->nr_poll_queues + 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 17/18] nvme: fix context analysis warning in tcp.c
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (15 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 16/18] nvme: add context annotations in tcp.c Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 18/18] nvme: enable context analysis support for nvme host driver Nilay Shroff
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
After adding Clang context annotations, compiling tcp.c reports the
following warning while context analysis is enabled:
drivers/nvme/host/tcp.c:2572:24: warning: passing pointer to variable 'list' requires holding mutex 'nvme_tcp_ctrl_mutex'
[-Wthread-safety-pointer]
2572 | if (list_empty(&ctrl->list))
| ^
The above warning is triggered because ctrl->list is guarded with mutex
nvme_tcp_ctrl_mutex but when list_empty(&ctrl->list) is invoked it
doesn't acquire nvme_tcp_ctrl_mutex.
Replace list_empty() with list_empty_careful(), which is intended
for lockless inspection of list heads during teardown when no concurrent
list modifications are expected. This suppresses the corresponding
Clang context analysis warning while preserving the existing behavior.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/tcp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 8d2fbfc7cd8d..87d8067f3283 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -2579,7 +2579,7 @@ static void nvme_tcp_free_ctrl(struct nvme_ctrl *nctrl)
{
struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
- if (list_empty(&ctrl->list))
+ if (list_empty_careful(&ctrl->list))
goto free_ctrl;
mutex_lock(&nvme_tcp_ctrl_mutex);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 18/18] nvme: enable context analysis support for nvme host driver
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
` (16 preceding siblings ...)
2026-07-06 14:14 ` [PATCH v3 17/18] nvme: fix context analysis warning " Nilay Shroff
@ 2026-07-06 14:14 ` Nilay Shroff
17 siblings, 0 replies; 20+ messages in thread
From: Nilay Shroff @ 2026-07-06 14:14 UTC (permalink / raw)
To: linux-nvme, linux-kernel
Cc: hch, elver, kbusch, sagi, axboe, bvanassche, gjoyce, Nilay Shroff
Update nvme host driver makefile to enable support for the Clang's
context anaysis.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
drivers/nvme/host/Makefile | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/nvme/host/Makefile b/drivers/nvme/host/Makefile
index 6414ec968f99..67563a69f7dc 100644
--- a/drivers/nvme/host/Makefile
+++ b/drivers/nvme/host/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
+CONTEXT_ANALYSIS := y
ccflags-y += -I$(src)
obj-$(CONFIG_NVME_CORE) += nvme-core.o
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 05/18] nvme: add context annotations for nvme_ns_head::current_path
2026-07-06 14:14 ` [PATCH v3 05/18] nvme: add context annotations for nvme_ns_head::current_path Nilay Shroff
@ 2026-07-06 16:08 ` Paul E. McKenney
0 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2026-07-06 16:08 UTC (permalink / raw)
To: Nilay Shroff
Cc: linux-nvme, linux-kernel, hch, elver, kbusch, sagi, axboe,
bvanassche, gjoyce
On Mon, Jul 06, 2026 at 07:44:07PM +0530, Nilay Shroff wrote:
> Annotate nvme_ns_head::current_path[] with __rcu_guarded so that
> Clang's context analysis can validate accesses to the SRCU/RCU
> protected pointer.
>
> Cc: Paul E. McKenney <paulmck@kernel.org>
> Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
From an RCU perspective:
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
> ---
> drivers/nvme/host/nvme.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
> index 5e746ae1c805..610c685e2263 100644
> --- a/drivers/nvme/host/nvme.h
> +++ b/drivers/nvme/host/nvme.h
> @@ -575,7 +575,7 @@ struct nvme_ns_head {
> #define NVME_NSHEAD_DISK_LIVE 0
> #define NVME_NSHEAD_QUEUE_IF_NO_PATH 1
> #define NVME_NSHEAD_CDEV_LIVE 2
> - struct nvme_ns __rcu *current_path[];
> + struct nvme_ns __rcu_guarded *current_path[];
> #endif
> };
>
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2026-07-06 16:08 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-06 14:14 [PATCH v3 00/18] Support Clang context analysis for NVMe host drivers Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 01/18] nvme: update nvme_passthru_end() signature Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 02/18] nvme: add context annotations for nvme_passthru_{start|stop} Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 03/18] nvme: add context annotations for nvme_ns_head::srcu Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 04/18] nvme: add context annotations for nvme_ns_head::requeue_list Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 05/18] nvme: add context annotations for nvme_ns_head::current_path Nilay Shroff
2026-07-06 16:08 ` Paul E. McKenney
2026-07-06 14:14 ` [PATCH v3 06/18] nvme: add context annotations for nvme_dev::shutdown_lock Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 07/18] nvme: add context annotations for nvme_subsystem::lock Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 08/18] nvme: add context annotations for nvme_ctrl::ana_lock Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 09/18] list: introduce LIST_HEAD_GUARDED Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 10/18] nvme: add context annotations for nvme_subsystems_lock Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 11/18] nvme: add context annotations in fabric.c Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 12/18] nvme: add context annotations for nvme_queue::sq_lock Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 13/18] nvme: add context annotations in rdma.c Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 14/18] list: Permit context-unguarded access with list_empty_careful() Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 15/18] nvme: fix context analysis warning in rdma.c Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 16/18] nvme: add context annotations in tcp.c Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 17/18] nvme: fix context analysis warning " Nilay Shroff
2026-07-06 14:14 ` [PATCH v3 18/18] nvme: enable context analysis support for nvme host driver Nilay Shroff
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox