mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] once_lite: Simplify condition handling and fix context analysis
@ 2026-09-03 10:16 Marco Elver
  2026-09-07 22:13 ` Nathan Chancellor
  0 siblings, 1 reply; 6+ messages in thread
From: Marco Elver @ 2026-09-03 10:16 UTC (permalink / raw)
  To: elver, Nathan Chancellor
  Cc: linux-kernel, kasan-dev, Jan Kara, Timothy Day, linux-ext4,
	Theodore Tso, linux-fsdevel

When WARN_ON_ONCE() wraps a conditional lock acquisition (such as
down_write_trylock()) on architectures relying on DO_ONCE_LITE_IF()
(e.g. arm), Clang's context analysis (Thread Safety Analysis) failed
with a false positive:

  fs/ext2/xattr.c:825:6: error: rw_semaphore 'EXT2_I().xattr_sem' is not held on every path through here [-Werror,-Wthread-safety-analysis]
    825 |         if (WARN_ON_ONCE(!down_write_trylock(&EXT2_I(inode)->xattr_sem)))
        |             ^

This happens because DO_ONCE_LITE_IF() branches on __ONCE_LITE_IF()'s
return value (__ret_once), creating an intermediate branch merge point
where the lock may or may not be held depending on whether the once-flag
(__already_done) was already set. Because the merge branch condition is
__ret_once rather than the trylock predicate (__ret_do_once), Clang
cannot reconcile the lockset at the branch merge points.

Fix it by refactoring __ONCE_LITE_IF() into an unconditional
__ONCE_LITE() primitive and redefining __ONCE_LITE_IF(condition) as:

  (unlikely(condition) && __ONCE_LITE())

This simplifies the implementation, short-circuits evaluation so that
__ONCE_LITE() is not called when the condition is false, and ensures
that DO_ONCE_LITE_IF() only enters __ONCE_LITE() when __ret_do_once is
true.

Reported-by: Nathan Chancellor <nathan@kernel.org>
Link: https://lore.kernel.org/all/20260903072759.GA1750084@ax162/
Signed-off-by: Marco Elver <elver@google.com>
---
 include/linux/once_lite.h | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/linux/once_lite.h b/include/linux/once_lite.h
index 236592c4eeb1..5e2b67039aaf 100644
--- a/include/linux/once_lite.h
+++ b/include/linux/once_lite.h
@@ -10,19 +10,21 @@
 #define DO_ONCE_LITE(func, ...)						\
 	DO_ONCE_LITE_IF(true, func, ##__VA_ARGS__)
 
-#define __ONCE_LITE_IF(condition)					\
+#define __ONCE_LITE()							\
 	({								\
 		static bool __section(".data..once") __already_done;	\
-		bool __ret_cond = !!(condition);			\
 		bool __ret_once = false;				\
 									\
-		if (unlikely(__ret_cond) && unlikely(!__already_done)) {\
+		if (unlikely(!__already_done)) {			\
 			__already_done = true;				\
 			__ret_once = true;				\
 		}							\
 		unlikely(__ret_once);					\
 	})
 
+#define __ONCE_LITE_IF(condition)					\
+	(unlikely(condition) && __ONCE_LITE())
+
 #define DO_ONCE_LITE_IF(condition, func, ...)				\
 	({								\
 		bool __ret_do_once = !!(condition);			\
-- 
2.55.0.970.g62bdec98f9-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] once_lite: Simplify condition handling and fix context analysis
  2026-09-03 10:16 [PATCH] once_lite: Simplify condition handling and fix context analysis Marco Elver
@ 2026-09-07 22:13 ` Nathan Chancellor
  2026-09-07 22:17   ` Marco Elver
  0 siblings, 1 reply; 6+ messages in thread
From: Nathan Chancellor @ 2026-09-07 22:13 UTC (permalink / raw)
  To: Marco Elver
  Cc: linux-kernel, kasan-dev, Jan Kara, Timothy Day, linux-ext4,
	Theodore Tso, linux-fsdevel

On Thu, Sep 03, 2026 at 10:16:38AM +0000, Marco Elver wrote:
> When WARN_ON_ONCE() wraps a conditional lock acquisition (such as
> down_write_trylock()) on architectures relying on DO_ONCE_LITE_IF()
> (e.g. arm), Clang's context analysis (Thread Safety Analysis) failed
> with a false positive:
> 
>   fs/ext2/xattr.c:825:6: error: rw_semaphore 'EXT2_I().xattr_sem' is not held on every path through here [-Werror,-Wthread-safety-analysis]
>     825 |         if (WARN_ON_ONCE(!down_write_trylock(&EXT2_I(inode)->xattr_sem)))
>         |             ^
> 
> This happens because DO_ONCE_LITE_IF() branches on __ONCE_LITE_IF()'s
> return value (__ret_once), creating an intermediate branch merge point
> where the lock may or may not be held depending on whether the once-flag
> (__already_done) was already set. Because the merge branch condition is
> __ret_once rather than the trylock predicate (__ret_do_once), Clang
> cannot reconcile the lockset at the branch merge points.
> 
> Fix it by refactoring __ONCE_LITE_IF() into an unconditional
> __ONCE_LITE() primitive and redefining __ONCE_LITE_IF(condition) as:
> 
>   (unlikely(condition) && __ONCE_LITE())
> 
> This simplifies the implementation, short-circuits evaluation so that
> __ONCE_LITE() is not called when the condition is false, and ensures
> that DO_ONCE_LITE_IF() only enters __ONCE_LITE() when __ret_do_once is
> true.
> 
> Reported-by: Nathan Chancellor <nathan@kernel.org>
> Link: https://lore.kernel.org/all/20260903072759.GA1750084@ax162/
> Signed-off-by: Marco Elver <elver@google.com>

Thanks, this fixes that warning for me across all my builds.

Tested-by: Nathan Chancellor <nathan@kernel.org> # build

-- 
Cheers,
Nathan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] once_lite: Simplify condition handling and fix context analysis
  2026-09-07 22:13 ` Nathan Chancellor
@ 2026-09-07 22:17   ` Marco Elver
  2026-09-08 10:15     ` Jan Kara
  0 siblings, 1 reply; 6+ messages in thread
From: Marco Elver @ 2026-09-07 22:17 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: linux-kernel, kasan-dev, Jan Kara, Timothy Day, linux-ext4,
	Theodore Tso, linux-fsdevel

On Tue, 8 Sept 2026 at 00:13, Nathan Chancellor <nathan@kernel.org> wrote:
>
> On Thu, Sep 03, 2026 at 10:16:38AM +0000, Marco Elver wrote:
> > When WARN_ON_ONCE() wraps a conditional lock acquisition (such as
> > down_write_trylock()) on architectures relying on DO_ONCE_LITE_IF()
> > (e.g. arm), Clang's context analysis (Thread Safety Analysis) failed
> > with a false positive:
> >
> >   fs/ext2/xattr.c:825:6: error: rw_semaphore 'EXT2_I().xattr_sem' is not held on every path through here [-Werror,-Wthread-safety-analysis]
> >     825 |         if (WARN_ON_ONCE(!down_write_trylock(&EXT2_I(inode)->xattr_sem)))
> >         |             ^
> >
> > This happens because DO_ONCE_LITE_IF() branches on __ONCE_LITE_IF()'s
> > return value (__ret_once), creating an intermediate branch merge point
> > where the lock may or may not be held depending on whether the once-flag
> > (__already_done) was already set. Because the merge branch condition is
> > __ret_once rather than the trylock predicate (__ret_do_once), Clang
> > cannot reconcile the lockset at the branch merge points.
> >
> > Fix it by refactoring __ONCE_LITE_IF() into an unconditional
> > __ONCE_LITE() primitive and redefining __ONCE_LITE_IF(condition) as:
> >
> >   (unlikely(condition) && __ONCE_LITE())
> >
> > This simplifies the implementation, short-circuits evaluation so that
> > __ONCE_LITE() is not called when the condition is false, and ensures
> > that DO_ONCE_LITE_IF() only enters __ONCE_LITE() when __ret_do_once is
> > true.
> >
> > Reported-by: Nathan Chancellor <nathan@kernel.org>
> > Link: https://lore.kernel.org/all/20260903072759.GA1750084@ax162/
> > Signed-off-by: Marco Elver <elver@google.com>
>
> Thanks, this fixes that warning for me across all my builds.
>
> Tested-by: Nathan Chancellor <nathan@kernel.org> # build

Thanks! I think this is one of those orphaned files - which tree can
this go through? Can it go through your tree, unless Jan already
picked it up with the other fix?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] once_lite: Simplify condition handling and fix context analysis
  2026-09-07 22:17   ` Marco Elver
@ 2026-09-08 10:15     ` Jan Kara
  2026-09-09  0:20       ` Nathan Chancellor
  0 siblings, 1 reply; 6+ messages in thread
From: Jan Kara @ 2026-09-08 10:15 UTC (permalink / raw)
  To: Marco Elver
  Cc: Nathan Chancellor, linux-kernel, kasan-dev, Jan Kara,
	Timothy Day, linux-ext4, Theodore Tso, linux-fsdevel

On Tue 08-09-26 00:17:34, Marco Elver wrote:
> On Tue, 8 Sept 2026 at 00:13, Nathan Chancellor <nathan@kernel.org> wrote:
> >
> > On Thu, Sep 03, 2026 at 10:16:38AM +0000, Marco Elver wrote:
> > > When WARN_ON_ONCE() wraps a conditional lock acquisition (such as
> > > down_write_trylock()) on architectures relying on DO_ONCE_LITE_IF()
> > > (e.g. arm), Clang's context analysis (Thread Safety Analysis) failed
> > > with a false positive:
> > >
> > >   fs/ext2/xattr.c:825:6: error: rw_semaphore 'EXT2_I().xattr_sem' is not held on every path through here [-Werror,-Wthread-safety-analysis]
> > >     825 |         if (WARN_ON_ONCE(!down_write_trylock(&EXT2_I(inode)->xattr_sem)))
> > >         |             ^
> > >
> > > This happens because DO_ONCE_LITE_IF() branches on __ONCE_LITE_IF()'s
> > > return value (__ret_once), creating an intermediate branch merge point
> > > where the lock may or may not be held depending on whether the once-flag
> > > (__already_done) was already set. Because the merge branch condition is
> > > __ret_once rather than the trylock predicate (__ret_do_once), Clang
> > > cannot reconcile the lockset at the branch merge points.
> > >
> > > Fix it by refactoring __ONCE_LITE_IF() into an unconditional
> > > __ONCE_LITE() primitive and redefining __ONCE_LITE_IF(condition) as:
> > >
> > >   (unlikely(condition) && __ONCE_LITE())
> > >
> > > This simplifies the implementation, short-circuits evaluation so that
> > > __ONCE_LITE() is not called when the condition is false, and ensures
> > > that DO_ONCE_LITE_IF() only enters __ONCE_LITE() when __ret_do_once is
> > > true.
> > >
> > > Reported-by: Nathan Chancellor <nathan@kernel.org>
> > > Link: https://lore.kernel.org/all/20260903072759.GA1750084@ax162/
> > > Signed-off-by: Marco Elver <elver@google.com>
> >
> > Thanks, this fixes that warning for me across all my builds.
> >
> > Tested-by: Nathan Chancellor <nathan@kernel.org> # build
> 
> Thanks! I think this is one of those orphaned files - which tree can
> this go through? Can it go through your tree, unless Jan already
> picked it up with the other fix?

If Nathan can take it through his tree, that would be great, otherwise I
can take it through mine. Just let me know.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] once_lite: Simplify condition handling and fix context analysis
  2026-09-08 10:15     ` Jan Kara
@ 2026-09-09  0:20       ` Nathan Chancellor
  2026-09-09  9:46         ` Jan Kara
  0 siblings, 1 reply; 6+ messages in thread
From: Nathan Chancellor @ 2026-09-09  0:20 UTC (permalink / raw)
  To: Jan Kara
  Cc: Marco Elver, linux-kernel, kasan-dev, Timothy Day, linux-ext4,
	Theodore Tso, linux-fsdevel

On Tue, Sep 08, 2026 at 12:15:13PM +0200, Jan Kara wrote:
> On Tue 08-09-26 00:17:34, Marco Elver wrote:
> > Thanks! I think this is one of those orphaned files - which tree can
> > this go through? Can it go through your tree, unless Jan already
> > picked it up with the other fix?
> 
> If Nathan can take it through his tree, that would be great, otherwise I
> can take it through mine. Just let me know.

I applied this to my clang-fixes tree and created an immutable tag for
you to pull from, as you should have it in your tree since you are
enabling context analysis there. If nobody else needs it and I do not
have any other material for 7.4 in that tree, I won't send a pull
request if the ext2 tree is merged with this included.

The following changes since commit cee9395acd8043be0644b25c34bfa86623f2b935:

  Linux 7.3-rc1 (2026-08-30 13:34:40 -0700)

are available in the Git repository at:

  git@gitolite.kernel.org:pub/scm/linux/kernel/git/nathan/linux.git tags/clang-fixes-once_lite-for-7.4

for you to fetch changes up to 0bb666d5f5a2339a5692afb312c2161df9620503:

  once_lite: Simplify condition handling and fix context analysis (2026-09-08 16:54:02 -0700)

----------------------------------------------------------------
Immutable branch for once_lite.h context analysis fix

Signed-off-by: Nathan Chancellor <nathan@kernel.org>

----------------------------------------------------------------
Marco Elver (1):
      once_lite: Simplify condition handling and fix context analysis

 include/linux/once_lite.h | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

-- 
Cheers,
Nathan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] once_lite: Simplify condition handling and fix context analysis
  2026-09-09  0:20       ` Nathan Chancellor
@ 2026-09-09  9:46         ` Jan Kara
  0 siblings, 0 replies; 6+ messages in thread
From: Jan Kara @ 2026-09-09  9:46 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Jan Kara, Marco Elver, linux-kernel, kasan-dev, Timothy Day,
	linux-ext4, Theodore Tso, linux-fsdevel

On Tue 08-09-26 17:20:05, Nathan Chancellor wrote:
> On Tue, Sep 08, 2026 at 12:15:13PM +0200, Jan Kara wrote:
> > On Tue 08-09-26 00:17:34, Marco Elver wrote:
> > > Thanks! I think this is one of those orphaned files - which tree can
> > > this go through? Can it go through your tree, unless Jan already
> > > picked it up with the other fix?
> > 
> > If Nathan can take it through his tree, that would be great, otherwise I
> > can take it through mine. Just let me know.
> 
> I applied this to my clang-fixes tree and created an immutable tag for
> you to pull from, as you should have it in your tree since you are
> enabling context analysis there. If nobody else needs it and I do not
> have any other material for 7.4 in that tree, I won't send a pull
> request if the ext2 tree is merged with this included.
> 
> The following changes since commit cee9395acd8043be0644b25c34bfa86623f2b935:
> 
>   Linux 7.3-rc1 (2026-08-30 13:34:40 -0700)
> 
> are available in the Git repository at:
> 
>   git@gitolite.kernel.org:pub/scm/linux/kernel/git/nathan/linux.git tags/clang-fixes-once_lite-for-7.4
> 
> for you to fetch changes up to 0bb666d5f5a2339a5692afb312c2161df9620503:
> 
>   once_lite: Simplify condition handling and fix context analysis (2026-09-08 16:54:02 -0700)
> 
> ----------------------------------------------------------------
> Immutable branch for once_lite.h context analysis fix
> 
> Signed-off-by: Nathan Chancellor <nathan@kernel.org>

OK, thanks. I've pulled this branch into my tree.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-09  9:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-03 10:16 [PATCH] once_lite: Simplify condition handling and fix context analysis Marco Elver
2026-09-07 22:13 ` Nathan Chancellor
2026-09-07 22:17   ` Marco Elver
2026-09-08 10:15     ` Jan Kara
2026-09-09  0:20       ` Nathan Chancellor
2026-09-09  9:46         ` Jan Kara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®