Skip to content

Commit

Permalink
Merge tag 'trace-v6.4-rc1' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/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
  • Loading branch information
torvalds committed May 5, 2023
2 parents b115d85 + 6ce2c04 commit e919a3f
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 5 deletions.
25 changes: 25 additions & 0 deletions Documentation/trace/ftrace.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
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
is being directly called by the function. If the count is greater
than 1 it most likely will be ftrace_ops_list_func().
Expand All @@ -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
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:

When set it will enable all functions with either the function
Expand Down
4 changes: 3 additions & 1 deletion include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ bool is_ftrace_trampoline(unsigned long addr);
* CALL_OPS - the record can 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
* MODIFIED - The function had IPMODIFY or DIRECT attached to it
*
* 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
Expand All @@ -569,9 +570,10 @@ enum {
FTRACE_FL_CALL_OPS = (1UL << 22),
FTRACE_FL_CALL_OPS_EN = (1UL << 21),
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_rec_count(rec) ((rec)->flags & FTRACE_REF_MAX)
Expand Down
12 changes: 9 additions & 3 deletions kernel/trace/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
#include "trace_stat.h"

/* 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__"

Expand Down Expand Up @@ -2273,6 +2274,10 @@ static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update)
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 there's only one user (direct_ops helper)
Expand Down Expand Up @@ -3866,12 +3871,13 @@ static int t_show(struct seq_file *m, void *v)
if (iter->flags & (FTRACE_ITER_ENABLED | FTRACE_ITER_TOUCHED)) {
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),
rec->flags & FTRACE_FL_REGS ? " R" : " ",
rec->flags & FTRACE_FL_IPMODIFY ? " I" : " ",
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) {
ops = ftrace_find_tramp_ops_any(rec);
if (ops) {
Expand Down
2 changes: 1 addition & 1 deletion kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -9661,7 +9661,7 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)

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);

create_trace_options_dir(tr);
Expand Down

0 comments on commit e919a3f

Please sign in to comment.