Skip to content

Commit 7ad6398

Browse files
mrutland-armKAGA-KOKO
authored andcommitted
thread_info: Add helpers to snapshot thread flags
In <linux/thread_info.h> there are helpers to manipulate individual thread flags, but where code wants to check several flags at once, it must open code reading current_thread_info()->flags and operating on a snapshot. As some flags can be set remotely it's necessary to use READ_ONCE() to get a consistent snapshot even when IRQs are disabled, but some code forgets to do this. Generally this is unlike to cause a problem in practice, but it is somewhat unsound, and KCSAN will legitimately warn that there is a data race. To make it easier to do the right thing, and to highlight that concurrent modification is possible, add new helpers to snapshot the flags, which should be used in preference to plain reads. Subsequent patches will move existing code to use the new helpers. Signed-off-by: Mark Rutland <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]> Acked-by: Marco Elver <[email protected]> Acked-by: Paul E. McKenney <[email protected]> Cc: Boqun Feng <[email protected]> Cc: Dmitry Vyukov <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Will Deacon <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent d58071a commit 7ad6398

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

include/linux/thread_info.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
118118
return test_bit(flag, (unsigned long *)&ti->flags);
119119
}
120120

121+
/*
122+
* This may be used in noinstr code, and needs to be __always_inline to prevent
123+
* inadvertent instrumentation.
124+
*/
125+
static __always_inline unsigned long read_ti_thread_flags(struct thread_info *ti)
126+
{
127+
return READ_ONCE(ti->flags);
128+
}
129+
121130
#define set_thread_flag(flag) \
122131
set_ti_thread_flag(current_thread_info(), flag)
123132
#define clear_thread_flag(flag) \
@@ -130,6 +139,11 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
130139
test_and_clear_ti_thread_flag(current_thread_info(), flag)
131140
#define test_thread_flag(flag) \
132141
test_ti_thread_flag(current_thread_info(), flag)
142+
#define read_thread_flags() \
143+
read_ti_thread_flags(current_thread_info())
144+
145+
#define read_task_thread_flags(t) \
146+
read_ti_thread_flags(task_thread_info(t))
133147

134148
#ifdef CONFIG_GENERIC_ENTRY
135149
#define set_syscall_work(fl) \

0 commit comments

Comments
 (0)