Re: [PATCHv2 14/17] nvme: fix Clang context analysis warning in rdma.c

From: Nilay Shroff

Date: Wed Jul 01 2026 - 03:51:09 EST



See patch below; to avoid more dependency issues for you, I suggest you
pick it up and carry it as part of this series unless someone else wants
it before for other reasons.

Only lightly tested, please test.


Thanks! this is useful and it's working as expected. So, yes I will pick it
up and send out while I spin the next version of this series.

------ >8 ------

From: Marco Elver <elver@xxxxxxxxxx>
Date: Tue, 30 Jun 2026 12:01:26 +0200
Subject: [PATCH] list: Permit context-unguarded access with
list_empty_careful()

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@xxxxxxxxxx>
---
include/linux/list.h | 1 +
1 file changed, 1 insertion(+)

diff --git a/include/linux/list.h b/include/linux/list.h
index 09d979976b3b..ba3c255f6112 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -436,6 +436,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));

Thanks,
--Nilay