Skip to content

Commit 858fa8a

Browse files
committed
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 <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Andrii Nakryiko <[email protected]> Cc: Indu Bhagat <[email protected]> Cc: "Jose E. Marchesi" <[email protected]> Cc: Beau Belgrave <[email protected]> Cc: Jens Remus <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Florian Weimer <[email protected]> Cc: Sam James <[email protected]> Link: https://lore.kernel.org/[email protected] Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 4c75133 commit 858fa8a

File tree

2 files changed

+13
-10
lines changed

2 files changed

+13
-10
lines changed

include/linux/unwind_deferred.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ struct unwind_work {
2020

2121
enum {
2222
UNWIND_PENDING_BIT = 0,
23+
UNWIND_USED_BIT,
2324
};
2425

2526
enum {
2627
UNWIND_PENDING = BIT(UNWIND_PENDING_BIT),
28+
29+
/* Set if the unwinding was used (directly or deferred) */
30+
UNWIND_USED = BIT(UNWIND_USED_BIT)
2731
};
2832

2933
void unwind_task_init(struct task_struct *task);
@@ -49,15 +53,11 @@ static __always_inline void unwind_reset_info(void)
4953
return;
5054
} while (!try_cmpxchg(&info->unwind_mask, &bits, 0UL));
5155
current->unwind_info.id.id = 0;
52-
}
53-
/*
54-
* As unwind_user_faultable() can be called directly and
55-
* depends on nr_entries being cleared on exit to user,
56-
* this needs to be a separate conditional.
57-
*/
58-
if (unlikely(info->cache)) {
59-
info->cache->nr_entries = 0;
60-
info->cache->unwind_completed = 0;
56+
57+
if (unlikely(info->cache)) {
58+
info->cache->nr_entries = 0;
59+
info->cache->unwind_completed = 0;
60+
}
6161
}
6262
}
6363

kernel/unwind/deferred.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static inline bool try_assign_cnt(struct unwind_task_info *info, u32 cnt)
4545
static DEFINE_MUTEX(callback_mutex);
4646
static LIST_HEAD(callbacks);
4747

48-
#define RESERVED_BITS (UNWIND_PENDING)
48+
#define RESERVED_BITS (UNWIND_PENDING | UNWIND_USED)
4949

5050
/* Zero'd bits are available for assigning callback users */
5151
static unsigned long unwind_mask = RESERVED_BITS;
@@ -140,6 +140,9 @@ int unwind_user_faultable(struct unwind_stacktrace *trace)
140140

141141
cache->nr_entries = trace->nr;
142142

143+
/* Clear nr_entries on way back to user space */
144+
set_bit(UNWIND_USED_BIT, &info->unwind_mask);
145+
143146
return 0;
144147
}
145148

0 commit comments

Comments
 (0)