Commit 7601de45 authored by Mark Rutland's avatar Mark Rutland Committed by Zheng Zengkai
Browse files

thread_info: Add helpers to snapshot thread flags

mainline inclusion
from mainline-v5.17-rc1
commit 7ad63984
category: performance
bugzilla: https://gitee.com/openeuler/kernel/issues/IA5WFA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7ad639840acf2800b5f387c495795f995a67a329



----------------------------------------------------------------------

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: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Reviewed-by: default avatarThomas Gleixner <tglx@linutronix.de>
Acked-by: default avatarMarco Elver <elver@google.com>
Acked-by: default avatarPaul E. McKenney <paulmck@kernel.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20211129130653.2037928-2-mark.rutland@arm.com



Conflict:
	include/linux/thread_info.h

Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 0989f895
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -36,6 +36,21 @@ static inline long set_restart_fn(struct restart_block *restart,

#define THREADINFO_GFP		(GFP_KERNEL_ACCOUNT | __GFP_ZERO)

/*
 * This may be used in noinstr code, and needs to be __always_inline to prevent
 * inadvertent instrumentation.
 */
static __always_inline unsigned long read_ti_thread_flags(struct thread_info *ti)
{
	return READ_ONCE(ti->flags);
}

#define read_thread_flags() \
	read_ti_thread_flags(current_thread_info())

#define read_task_thread_flags(t) \
	read_ti_thread_flags(task_thread_info(t))

#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED)

#ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES