From 4617721c502b2ddaa4e324e86da4997edf738fa5 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 2 Sep 2026 09:55:01 -0400 Subject: ftrace: Synchronize the initialization of ftrace_ops There's some internal state that ftrace_ops needs to have set, but since it can be declared outside of the ftrace.c code, it calls ftrace_ops_init() on the ops in every global function. The issue is that if two tasks call it on the same ops at the same time it is possible to have the initialization of one corrupt the initialization of the other call. Create a ops_mutex to use to synchronize every initialization of the ftrace_ops. The mutex is taken within checking the ftrace_ops flag that states it was initializied but the flag is checked again after the mutex has been taken. Checking first outside the mutex allows it to shortcut having to take the mutex. But then the check needs to be done again after the mute is taken in case of races. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260902095501.6b59af20@gandalf.local.home Fixes: f04f24fb7e48d ("ftrace, kprobes: Fix a deadlock on ftrace_regex_lock") Reported-by: sashiko-bot@kernel.org Close: https://lore.kernel.org/all/20260829025528.49A831F000E9@smtp.kernel.org/ Signed-off-by: Steven Rostedt --- tools/perf/util/c2c.h | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 tools/perf/util/c2c.h (limited to 'tools/perf/util/c2c.h') diff --git a/tools/perf/util/c2c.h b/tools/perf/util/c2c.h new file mode 100644 index 000000000..53f024e25 --- /dev/null +++ b/tools/perf/util/c2c.h @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_UTIL_C2C_H +#define __PERF_UTIL_C2C_H + +#include +#include +#include +#include "hist.h" +#include "mem-events.h" +#include "stat.h" + +struct sort_entry; + +struct c2c_hists { + struct hists hists; + struct perf_hpp_list list; + struct c2c_stats stats; +}; + +struct compute_stats { + struct stats lcl_hitm; + struct stats rmt_hitm; + struct stats lcl_peer; + struct stats rmt_peer; + struct stats load; +}; + +struct c2c_hist_entry { + struct c2c_hists *hists; + struct evsel *evsel; + struct c2c_stats stats; + unsigned long *cpuset; + unsigned long *nodeset; + struct c2c_stats *node_stats; + unsigned int cacheline_idx; + + struct compute_stats cstats; + + unsigned long paddr; + unsigned long paddr_cnt; + bool paddr_zero; + char *nodestr; + + /* + * must be at the end, + * because of its callchain dynamic entry + */ + struct hist_entry he; +}; + +#define C2C_HEADER_MAX 2 + +struct c2c_header { + struct { + const char *text; + int span; + } line[C2C_HEADER_MAX]; +}; + +struct c2c_dimension { + struct c2c_header header; + const char *name; + int width; + struct sort_entry *se; + + int64_t (*cmp)(struct perf_hpp_fmt *fmt, + struct hist_entry *left, struct hist_entry *right); + int (*entry)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, + struct hist_entry *he); + int (*color)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, + struct hist_entry *he); +}; + +struct c2c_fmt { + struct perf_hpp_fmt fmt; + struct c2c_dimension *dim; +}; + +#define SYMBOL_WIDTH 30 + +#define HEADER_LOW(__h) \ + { \ + .line[1] = { \ + .text = __h, \ + }, \ + } + +#define HEADER_BOTH(__h0, __h1) \ + { \ + .line[0] = { \ + .text = __h0, \ + }, \ + .line[1] = { \ + .text = __h1, \ + }, \ + } + +void c2c_fmt_free(struct perf_hpp_fmt *fmt); +bool c2c_fmt_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b); + +/* + * Build the function-view hierarchy. Returns -EOPNOTSUPP when @cl_sort lacks + * iaddr. On success, *@hists remains valid until the next + * c2c_function__build() or c2c_function__reset(). On failure, *@hists is + * NULL. + */ +int c2c_function__build(struct c2c_hists *cl_hists, const char *cl_sort, + bool symbol_full, struct hists **hists); +void c2c_function__reset(void); +/* Valid only between a successful build and c2c_function__reset(). */ +struct hist_entry *c2c_function__find_cacheline(struct hist_entry *he); + +/* Inputs and TUI callback supplied by the c2c command. */ +struct c2c_function_view_args { + /* Source cacheline histograms used by the common model. */ + struct c2c_hists *cl_hists; + /* --coalesce field list, used to require iaddr. */ + const char *cl_sort; + /* Do not cap long symbol names. */ + bool symbol_full; + /* Open the cacheline detail view for @he. */ + int (*browse_cacheline)(struct hist_entry *he); +}; + +#ifdef HAVE_SLANG_SUPPORT +int perf_c2c__browse_function_view(struct c2c_function_view_args *args); +#else +static inline int +perf_c2c__browse_function_view(struct c2c_function_view_args *args __maybe_unused) +{ + return 0; +} +#endif + +#endif /* __PERF_UTIL_C2C_H */ -- cgit v1.3.1