Commit 8b96f011 authored by Frederic Weisbecker's avatar Frederic Weisbecker Committed by Ingo Molnar

tracing/function-graph-tracer: introduce __notrace_funcgraph to filter special functions

Impact: trace more functions

When the function graph tracer is configured, three more files are not
traced to prevent only four functions to be traced. And this impacts the
normal function tracer too.

arch/x86/kernel/process_64/32.c:

I had crashes when I let this file traced. After some debugging, I saw
that the "current" task point was changed inside__swtich_to(), ie:
"write_pda(pcurrent, next_p);" inside process_64.c Since the tracer store
the original return address of the function inside current, we had
crashes. Only __switch_to() has to be excluded from tracing.

kernel/module.c and kernel/extable.c:

Because of a function used internally by the function graph tracer:
__kernel_text_address()

To let the other functions inside these files to be traced, this patch
introduces the __notrace_funcgraph function prefix which is __notrace if
function graph tracer is configured and nothing if not.
Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent decbec38
...@@ -14,12 +14,6 @@ CFLAGS_REMOVE_paravirt-spinlocks.o = -pg ...@@ -14,12 +14,6 @@ CFLAGS_REMOVE_paravirt-spinlocks.o = -pg
CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_ftrace.o = -pg
endif endif
ifdef CONFIG_FUNCTION_GRAPH_TRACER
# Don't trace __switch_to() but let it for function tracer
CFLAGS_REMOVE_process_32.o = -pg
CFLAGS_REMOVE_process_64.o = -pg
endif
# #
# vsyscalls (which work on the user stack) should have # vsyscalls (which work on the user stack) should have
# no stack-protector checks: # no stack-protector checks:
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/prctl.h> #include <linux/prctl.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/ftrace.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
...@@ -548,7 +549,8 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, ...@@ -548,7 +549,8 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
* the task-switch, and shows up in ret_from_fork in entry.S, * the task-switch, and shows up in ret_from_fork in entry.S,
* for example. * for example.
*/ */
struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct *next_p) __notrace_funcgraph struct task_struct *
__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{ {
struct thread_struct *prev = &prev_p->thread, struct thread_struct *prev = &prev_p->thread,
*next = &next_p->thread; *next = &next_p->thread;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/prctl.h> #include <linux/prctl.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/ftrace.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -551,8 +552,9 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, ...@@ -551,8 +552,9 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
* - could test fs/gs bitsliced * - could test fs/gs bitsliced
* *
* Kprobes not supported here. Set the probe on schedule instead. * Kprobes not supported here. Set the probe on schedule instead.
* Function graph tracer not supported too.
*/ */
struct task_struct * __notrace_funcgraph struct task_struct *
__switch_to(struct task_struct *prev_p, struct task_struct *next_p) __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{ {
struct thread_struct *prev = &prev_p->thread; struct thread_struct *prev = &prev_p->thread;
......
...@@ -369,6 +369,14 @@ struct ftrace_graph_ret { ...@@ -369,6 +369,14 @@ struct ftrace_graph_ret {
}; };
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
/*
* Sometimes we don't want to trace a function with the function
* graph tracer but we want them to keep traced by the usual function
* tracer if the function graph tracer is not configured.
*/
#define __notrace_funcgraph notrace
#define FTRACE_RETFUNC_DEPTH 50 #define FTRACE_RETFUNC_DEPTH 50
#define FTRACE_RETSTACK_ALLOC_SIZE 32 #define FTRACE_RETSTACK_ALLOC_SIZE 32
/* Type of the callback handlers for tracing function graph*/ /* Type of the callback handlers for tracing function graph*/
...@@ -394,6 +402,9 @@ static inline int task_curr_ret_stack(struct task_struct *t) ...@@ -394,6 +402,9 @@ static inline int task_curr_ret_stack(struct task_struct *t)
return t->curr_ret_stack; return t->curr_ret_stack;
} }
#else #else
#define __notrace_funcgraph
static inline void ftrace_graph_init_task(struct task_struct *t) { } static inline void ftrace_graph_init_task(struct task_struct *t) { }
static inline void ftrace_graph_exit_task(struct task_struct *t) { } static inline void ftrace_graph_exit_task(struct task_struct *t) { }
......
...@@ -21,10 +21,6 @@ CFLAGS_REMOVE_cgroup-debug.o = -pg ...@@ -21,10 +21,6 @@ CFLAGS_REMOVE_cgroup-debug.o = -pg
CFLAGS_REMOVE_sched_clock.o = -pg CFLAGS_REMOVE_sched_clock.o = -pg
CFLAGS_REMOVE_sched.o = -pg CFLAGS_REMOVE_sched.o = -pg
endif endif
ifdef CONFIG_FUNCTION_GRAPH_TRACER
CFLAGS_REMOVE_extable.o = -pg # For __kernel_text_address()
CFLAGS_REMOVE_module.o = -pg # For __module_text_address()
endif
obj-$(CONFIG_FREEZER) += freezer.o obj-$(CONFIG_FREEZER) += freezer.o
obj-$(CONFIG_PROFILING) += profile.o obj-$(CONFIG_PROFILING) += profile.o
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/ftrace.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/sections.h> #include <asm/sections.h>
...@@ -40,7 +41,7 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr) ...@@ -40,7 +41,7 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr)
return e; return e;
} }
int core_kernel_text(unsigned long addr) __notrace_funcgraph int core_kernel_text(unsigned long addr)
{ {
if (addr >= (unsigned long)_stext && if (addr >= (unsigned long)_stext &&
addr <= (unsigned long)_etext) addr <= (unsigned long)_etext)
...@@ -53,7 +54,7 @@ int core_kernel_text(unsigned long addr) ...@@ -53,7 +54,7 @@ int core_kernel_text(unsigned long addr)
return 0; return 0;
} }
int __kernel_text_address(unsigned long addr) __notrace_funcgraph int __kernel_text_address(unsigned long addr)
{ {
if (core_kernel_text(addr)) if (core_kernel_text(addr))
return 1; return 1;
......
...@@ -2704,7 +2704,7 @@ int is_module_address(unsigned long addr) ...@@ -2704,7 +2704,7 @@ int is_module_address(unsigned long addr)
/* Is this a valid kernel address? */ /* Is this a valid kernel address? */
struct module *__module_text_address(unsigned long addr) __notrace_funcgraph struct module *__module_text_address(unsigned long addr)
{ {
struct module *mod; struct module *mod;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment