Commit e919a3f7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'trace-v6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull more tracing updates from Steven Rostedt:

 - Make buffer_percent read/write.

   The buffer_percent file is how users can state how long to block on
   the tracing buffer depending on how much is in the buffer. When it
   hits the "buffer_percent" it will wake the task waiting on the
   buffer. For some reason it was set to read-only.

   This was not noticed because testing was done as root without
   SELinux, but with SELinux it will prevent even root to write to it
   without having CAP_DAC_OVERRIDE.

 - The "touched_functions" was added this merge window, but one of the
   reasons for adding it was not implemented.

   That was to show what functions were not only touched, but had either
   a direct trampoline attached to it, or a kprobe or live kernel
   patching that can "hijack" the function to run a different function.
   The point is to know if there's functions in the kernel that may not
   be behaving as the kernel code shows. This can be used for debugging.

   TODO: Add this information to kernel oops too.

* tag 'trace-v6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  ftrace: Add MODIFIED flag to show if IPMODIFY or direct was attached
  tracing: Fix permissions for the buffer_percent file
parents b115d85a 6ce2c04f
...@@ -350,6 +350,19 @@ of ftrace. Here is a list of some of the key files: ...@@ -350,6 +350,19 @@ of ftrace. Here is a list of some of the key files:
an 'I' will be displayed on the same line as the function that an 'I' will be displayed on the same line as the function that
can be overridden. can be overridden.
If a non ftrace trampoline is attached (BPF) a 'D' will be displayed.
Note, normal ftrace trampolines can also be attached, but only one
"direct" trampoline can be attached to a given function at a time.
Some architectures can not call direct trampolines, but instead have
the ftrace ops function located above the function entry point. In
such cases an 'O' will be displayed.
If a function had either the "ip modify" or a "direct" call attached to
it in the past, a 'M' will be shown. This flag is never cleared. It is
used to know if a function was every modified by the ftrace infrastructure,
and can be used for debugging.
If the architecture supports it, it will also show what callback If the architecture supports it, it will also show what callback
is being directly called by the function. If the count is greater is being directly called by the function. If the count is greater
than 1 it most likely will be ftrace_ops_list_func(). than 1 it most likely will be ftrace_ops_list_func().
...@@ -359,6 +372,18 @@ of ftrace. Here is a list of some of the key files: ...@@ -359,6 +372,18 @@ of ftrace. Here is a list of some of the key files:
its address will be printed as well as the function that the its address will be printed as well as the function that the
trampoline calls. trampoline calls.
touched_functions:
This file contains all the functions that ever had a function callback
to it via the ftrace infrastructure. It has the same format as
enabled_functions but shows all functions that have every been
traced.
To see any function that has every been modified by "ip modify" or a
direct trampoline, one can perform the following command:
grep ' M ' /sys/kernel/tracing/touched_functions
function_profile_enabled: function_profile_enabled:
When set it will enable all functions with either the function When set it will enable all functions with either the function
......
...@@ -549,6 +549,7 @@ bool is_ftrace_trampoline(unsigned long addr); ...@@ -549,6 +549,7 @@ bool is_ftrace_trampoline(unsigned long addr);
* CALL_OPS - the record can use callsite-specific ops * CALL_OPS - the record can use callsite-specific ops
* CALL_OPS_EN - the function is set up to use callsite-specific ops * CALL_OPS_EN - the function is set up to use callsite-specific ops
* TOUCHED - A callback was added since boot up * TOUCHED - A callback was added since boot up
* MODIFIED - The function had IPMODIFY or DIRECT attached to it
* *
* When a new ftrace_ops is registered and wants a function to save * When a new ftrace_ops is registered and wants a function to save
* pt_regs, the rec->flags REGS is set. When the function has been * pt_regs, the rec->flags REGS is set. When the function has been
...@@ -569,9 +570,10 @@ enum { ...@@ -569,9 +570,10 @@ enum {
FTRACE_FL_CALL_OPS = (1UL << 22), FTRACE_FL_CALL_OPS = (1UL << 22),
FTRACE_FL_CALL_OPS_EN = (1UL << 21), FTRACE_FL_CALL_OPS_EN = (1UL << 21),
FTRACE_FL_TOUCHED = (1UL << 20), FTRACE_FL_TOUCHED = (1UL << 20),
FTRACE_FL_MODIFIED = (1UL << 19),
}; };
#define FTRACE_REF_MAX_SHIFT 20 #define FTRACE_REF_MAX_SHIFT 19
#define FTRACE_REF_MAX ((1UL << FTRACE_REF_MAX_SHIFT) - 1) #define FTRACE_REF_MAX ((1UL << FTRACE_REF_MAX_SHIFT) - 1)
#define ftrace_rec_count(rec) ((rec)->flags & FTRACE_REF_MAX) #define ftrace_rec_count(rec) ((rec)->flags & FTRACE_REF_MAX)
......
...@@ -46,7 +46,8 @@ ...@@ -46,7 +46,8 @@
#include "trace_stat.h" #include "trace_stat.h"
/* Flags that do not get reset */ /* Flags that do not get reset */
#define FTRACE_NOCLEAR_FLAGS (FTRACE_FL_DISABLED | FTRACE_FL_TOUCHED) #define FTRACE_NOCLEAR_FLAGS (FTRACE_FL_DISABLED | FTRACE_FL_TOUCHED | \
FTRACE_FL_MODIFIED)
#define FTRACE_INVALID_FUNCTION "__ftrace_invalid_address__" #define FTRACE_INVALID_FUNCTION "__ftrace_invalid_address__"
...@@ -2273,6 +2274,10 @@ static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update) ...@@ -2273,6 +2274,10 @@ static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update)
rec->flags &= ~FTRACE_FL_TRAMP_EN; rec->flags &= ~FTRACE_FL_TRAMP_EN;
} }
/* Keep track of anything that modifies the function */
if (rec->flags & (FTRACE_FL_DIRECT | FTRACE_FL_IPMODIFY))
rec->flags |= FTRACE_FL_MODIFIED;
if (flag & FTRACE_FL_DIRECT) { if (flag & FTRACE_FL_DIRECT) {
/* /*
* If there's only one user (direct_ops helper) * If there's only one user (direct_ops helper)
...@@ -3866,12 +3871,13 @@ static int t_show(struct seq_file *m, void *v) ...@@ -3866,12 +3871,13 @@ static int t_show(struct seq_file *m, void *v)
if (iter->flags & (FTRACE_ITER_ENABLED | FTRACE_ITER_TOUCHED)) { if (iter->flags & (FTRACE_ITER_ENABLED | FTRACE_ITER_TOUCHED)) {
struct ftrace_ops *ops; struct ftrace_ops *ops;
seq_printf(m, " (%ld)%s%s%s%s", seq_printf(m, " (%ld)%s%s%s%s%s",
ftrace_rec_count(rec), ftrace_rec_count(rec),
rec->flags & FTRACE_FL_REGS ? " R" : " ", rec->flags & FTRACE_FL_REGS ? " R" : " ",
rec->flags & FTRACE_FL_IPMODIFY ? " I" : " ", rec->flags & FTRACE_FL_IPMODIFY ? " I" : " ",
rec->flags & FTRACE_FL_DIRECT ? " D" : " ", rec->flags & FTRACE_FL_DIRECT ? " D" : " ",
rec->flags & FTRACE_FL_CALL_OPS ? " O" : " "); rec->flags & FTRACE_FL_CALL_OPS ? " O" : " ",
rec->flags & FTRACE_FL_MODIFIED ? " M " : " ");
if (rec->flags & FTRACE_FL_TRAMP_EN) { if (rec->flags & FTRACE_FL_TRAMP_EN) {
ops = ftrace_find_tramp_ops_any(rec); ops = ftrace_find_tramp_ops_any(rec);
if (ops) { if (ops) {
......
...@@ -9661,7 +9661,7 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) ...@@ -9661,7 +9661,7 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
tr->buffer_percent = 50; tr->buffer_percent = 50;
trace_create_file("buffer_percent", TRACE_MODE_READ, d_tracer, trace_create_file("buffer_percent", TRACE_MODE_WRITE, d_tracer,
tr, &buffer_percent_fops); tr, &buffer_percent_fops);
create_trace_options_dir(tr); create_trace_options_dir(tr);
......
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