Skip to content

Commit

Permalink
tracing: Add stack_tracer_disable/enable() functions
Browse files Browse the repository at this point in the history
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) <rostedt@goodmis.org>
  • Loading branch information
Steven Rostedt (VMware) committed Apr 10, 2017
1 parent 252babc commit 5367278
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,12 @@ int
stack_trace_sysctl(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos);

void stack_tracer_disable(void);
void stack_tracer_enable(void);
#else
static inline void stack_tracer_disable(void) { }
static inline void stack_tracer_enable(void) { }
#endif

struct ftrace_func_command {
Expand Down
32 changes: 32 additions & 0 deletions kernel/trace/trace_stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,38 @@ static DEFINE_MUTEX(stack_sysctl_mutex);
int stack_tracer_enabled;
static int last_stack_tracer_enabled;

/**
* stack_tracer_disable - temporarily disable the stack tracer
*
* There's a few locations (namely in RCU) where stack tracing
* cannot be executed. This function is used to disable stack
* tracing during those critical sections.
*
* This function must be called with preemption or interrupts
* disabled and stack_tracer_enable() must be called shortly after
* while preemption or interrupts are still disabled.
*/
void stack_tracer_disable(void)
{
/* Preemption or interupts must be disabled */
if (IS_ENABLED(CONFIG_PREEMPT_DEBUG))
WARN_ON_ONCE(!preempt_count() || !irqs_disabled());
this_cpu_inc(trace_active);
}

/**
* stack_tracer_enable - re-enable the stack tracer
*
* After stack_tracer_disable() is called, stack_tracer_enable()
* must be called shortly afterward.
*/
void stack_tracer_enable(void)
{
if (IS_ENABLED(CONFIG_PREEMPT_DEBUG))
WARN_ON_ONCE(!preempt_count() || !irqs_disabled());
this_cpu_dec(trace_active);
}

void stack_trace_print(void)
{
long i;
Expand Down

0 comments on commit 5367278

Please sign in to comment.