3d0833953e
This patch adds a feature to dynamically replace the ftrace code with the jmps to allow a kernel with ftrace configured to run as fast as it can without it configured. The way this works, is on bootup (if ftrace is enabled), a ftrace function is registered to record the instruction pointer of all places that call the function. Later, if there's still any code to patch, a kthread is awoken (rate limited to at most once a second) that performs a stop_machine, and replaces all the code that was called with a jmp over the call to ftrace. It only replaces what was found the previous time. Typically the system reaches equilibrium quickly after bootup and there's no code patching needed at all. e.g. call ftrace /* 5 bytes */ is replaced with jmp 3f /* jmp is 2 bytes and we jump 3 forward */ 3: When we want to enable ftrace for function tracing, the IP recording is removed, and stop_machine is called again to replace all the locations of that were recorded back to the call of ftrace. When it is disabled, we replace the code back to the jmp. Allocation is done by the kthread. If the ftrace recording function is called, and we don't have any record slots available, then we simply skip that call. Once a second a new page (if needed) is allocated for recording new ftrace function calls. A large batch is allocated at boot up to get most of the calls there. Because we do this via stop_machine, we don't have to worry about another CPU executing a ftrace call as we modify it. But we do need to worry about NMI's so all functions that might be called via nmi must be annotated with notrace_nmi. When this code is configured in, the NMI code will not call notrace. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
107 lines
3.2 KiB
Text
107 lines
3.2 KiB
Text
#
|
|
# Architectures that offer an FTRACE implementation should select HAVE_FTRACE:
|
|
#
|
|
config HAVE_FTRACE
|
|
bool
|
|
|
|
config TRACER_MAX_TRACE
|
|
bool
|
|
|
|
config TRACING
|
|
bool
|
|
select DEBUG_FS
|
|
|
|
config FTRACE
|
|
bool "Kernel Function Tracer"
|
|
depends on DEBUG_KERNEL && HAVE_FTRACE
|
|
select FRAME_POINTER
|
|
select TRACING
|
|
select CONTEXT_SWITCH_TRACER
|
|
help
|
|
Enable the kernel to trace every kernel function. This is done
|
|
by using a compiler feature to insert a small, 5-byte No-Operation
|
|
instruction to the beginning of every kernel function, which NOP
|
|
sequence is then dynamically patched into a tracer call when
|
|
tracing is enabled by the administrator. If it's runtime disabled
|
|
(the bootup default), then the overhead of the instructions is very
|
|
small and not measurable even in micro-benchmarks.
|
|
|
|
config IRQSOFF_TRACER
|
|
bool "Interrupts-off Latency Tracer"
|
|
default n
|
|
depends on TRACE_IRQFLAGS_SUPPORT
|
|
depends on GENERIC_TIME
|
|
select TRACE_IRQFLAGS
|
|
select TRACING
|
|
select TRACER_MAX_TRACE
|
|
help
|
|
This option measures the time spent in irqs-off critical
|
|
sections, with microsecond accuracy.
|
|
|
|
The default measurement method is a maximum search, which is
|
|
disabled by default and can be runtime (re-)started
|
|
via:
|
|
|
|
echo 0 > /debugfs/tracing/tracing_max_latency
|
|
|
|
(Note that kernel size and overhead increases with this option
|
|
enabled. This option and the preempt-off timing option can be
|
|
used together or separately.)
|
|
|
|
config PREEMPT_TRACER
|
|
bool "Preemption-off Latency Tracer"
|
|
default n
|
|
depends on GENERIC_TIME
|
|
depends on PREEMPT
|
|
select TRACING
|
|
select TRACER_MAX_TRACE
|
|
help
|
|
This option measures the time spent in preemption off critical
|
|
sections, with microsecond accuracy.
|
|
|
|
The default measurement method is a maximum search, which is
|
|
disabled by default and can be runtime (re-)started
|
|
via:
|
|
|
|
echo 0 > /debugfs/tracing/tracing_max_latency
|
|
|
|
(Note that kernel size and overhead increases with this option
|
|
enabled. This option and the irqs-off timing option can be
|
|
used together or separately.)
|
|
|
|
config SCHED_TRACER
|
|
bool "Scheduling Latency Tracer"
|
|
depends on DEBUG_KERNEL
|
|
select TRACING
|
|
select CONTEXT_SWITCH_TRACER
|
|
select TRACER_MAX_TRACE
|
|
help
|
|
This tracer tracks the latency of the highest priority task
|
|
to be scheduled in, starting from the point it has woken up.
|
|
|
|
config CONTEXT_SWITCH_TRACER
|
|
bool "Trace process context switches"
|
|
depends on DEBUG_KERNEL
|
|
select TRACING
|
|
select MARKERS
|
|
help
|
|
This tracer gets called from the context switch and records
|
|
all switching of tasks.
|
|
|
|
config DYNAMIC_FTRACE
|
|
bool "enable/disable ftrace tracepoints dynamically"
|
|
depends on FTRACE
|
|
default y
|
|
help
|
|
This option will modify all the calls to ftrace dynamically
|
|
(will patch them out of the binary image and replaces them
|
|
with a No-Op instruction) as they are called. A table is
|
|
created to dynamically enable them again.
|
|
|
|
This way a CONFIG_FTRACE kernel is slightly larger, but otherwise
|
|
has native performance as long as no tracing is active.
|
|
|
|
The changes to the code are done by a kernel thread that
|
|
wakes up once a second and checks to see if any ftrace calls
|
|
were made. If so, it runs stop_machine (stops all CPUS)
|
|
and modifies the code to jump over the call to ftrace.
|