Skip to content

Commit 5367278

Browse files
committed
tracing: Add stack_tracer_disable/enable() functions
There are certain parts of the kernel that cannot let stack tracing proceed (namely in RCU), because the stack tracer uses RCU, and parts of RCU internals cannot handle having RCU read side locks taken. Add stack_tracer_disable() and stack_tracer_enable() functions to let RCU stop stack tracing on the current CPU when it is in those critical sections. Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 252babc commit 5367278

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

include/linux/ftrace.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,12 @@ int
286286
stack_trace_sysctl(struct ctl_table *table, int write,
287287
void __user *buffer, size_t *lenp,
288288
loff_t *ppos);
289+
290+
void stack_tracer_disable(void);
291+
void stack_tracer_enable(void);
292+
#else
293+
static inline void stack_tracer_disable(void) { }
294+
static inline void stack_tracer_enable(void) { }
289295
#endif
290296

291297
struct ftrace_func_command {

kernel/trace/trace_stack.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,38 @@ static DEFINE_MUTEX(stack_sysctl_mutex);
4141
int stack_tracer_enabled;
4242
static int last_stack_tracer_enabled;
4343

44+
/**
45+
* stack_tracer_disable - temporarily disable the stack tracer
46+
*
47+
* There's a few locations (namely in RCU) where stack tracing
48+
* cannot be executed. This function is used to disable stack
49+
* tracing during those critical sections.
50+
*
51+
* This function must be called with preemption or interrupts
52+
* disabled and stack_tracer_enable() must be called shortly after
53+
* while preemption or interrupts are still disabled.
54+
*/
55+
void stack_tracer_disable(void)
56+
{
57+
/* Preemption or interupts must be disabled */
58+
if (IS_ENABLED(CONFIG_PREEMPT_DEBUG))
59+
WARN_ON_ONCE(!preempt_count() || !irqs_disabled());
60+
this_cpu_inc(trace_active);
61+
}
62+
63+
/**
64+
* stack_tracer_enable - re-enable the stack tracer
65+
*
66+
* After stack_tracer_disable() is called, stack_tracer_enable()
67+
* must be called shortly afterward.
68+
*/
69+
void stack_tracer_enable(void)
70+
{
71+
if (IS_ENABLED(CONFIG_PREEMPT_DEBUG))
72+
WARN_ON_ONCE(!preempt_count() || !irqs_disabled());
73+
this_cpu_dec(trace_active);
74+
}
75+
4476
void stack_trace_print(void)
4577
{
4678
long i;

0 commit comments

Comments
 (0)