Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

unwind: Add USED bit to only have one conditional on way back to user space

On the way back to user space, the function unwind_reset_info() is called
unconditionally (but always inlined). It currently has two conditionals.
One that checks the unwind_mask which is set whenever a deferred trace is
called and is used to know that the mask needs to be cleared. The other
checks if the cache has been allocated, and if so, it resets the
nr_entries so that the unwinder knows it needs to do the work to get a new
user space stack trace again (it only does it once per entering the
kernel).

Use one of the bits in the unwind mask as a "USED" bit that gets set
whenever a trace is created. This will make it possible to only check the
unwind_mask in the unwind_reset_info() to know if it needs to do work or
not and eliminates a conditional that happens every time the task goes
back to user space.

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Indu Bhagat <indu.bhagat@oracle.com>
Cc: "Jose E. Marchesi" <jemarch@gnu.org>
Cc: Beau Belgrave <beaub@linux.microsoft.com>
Cc: Jens Remus <jremus@linux.ibm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Florian Weimer <fweimer@redhat.com>
Cc: Sam James <sam@gentoo.org>
Link: https://lore.kernel.org/20250729182406.155422551@kernel.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

+13 -10
+9 -9
include/linux/unwind_deferred.h
··· 20 20 21 21 enum { 22 22 UNWIND_PENDING_BIT = 0, 23 + UNWIND_USED_BIT, 23 24 }; 24 25 25 26 enum { 26 27 UNWIND_PENDING = BIT(UNWIND_PENDING_BIT), 28 + 29 + /* Set if the unwinding was used (directly or deferred) */ 30 + UNWIND_USED = BIT(UNWIND_USED_BIT) 27 31 }; 28 32 29 33 void unwind_task_init(struct task_struct *task); ··· 53 49 return; 54 50 } while (!try_cmpxchg(&info->unwind_mask, &bits, 0UL)); 55 51 current->unwind_info.id.id = 0; 56 - } 57 - /* 58 - * As unwind_user_faultable() can be called directly and 59 - * depends on nr_entries being cleared on exit to user, 60 - * this needs to be a separate conditional. 61 - */ 62 - if (unlikely(info->cache)) { 63 - info->cache->nr_entries = 0; 64 - info->cache->unwind_completed = 0; 52 + 53 + if (unlikely(info->cache)) { 54 + info->cache->nr_entries = 0; 55 + info->cache->unwind_completed = 0; 56 + } 65 57 } 66 58 } 67 59
+4 -1
kernel/unwind/deferred.c
··· 45 45 static DEFINE_MUTEX(callback_mutex); 46 46 static LIST_HEAD(callbacks); 47 47 48 - #define RESERVED_BITS (UNWIND_PENDING) 48 + #define RESERVED_BITS (UNWIND_PENDING | UNWIND_USED) 49 49 50 50 /* Zero'd bits are available for assigning callback users */ 51 51 static unsigned long unwind_mask = RESERVED_BITS; ··· 139 139 unwind_user(trace, UNWIND_MAX_ENTRIES); 140 140 141 141 cache->nr_entries = trace->nr; 142 + 143 + /* Clear nr_entries on way back to user space */ 144 + set_bit(UNWIND_USED_BIT, &info->unwind_mask); 142 145 143 146 return 0; 144 147 }