Re: [PATCH v9 1/9] perf c2c: extract shared data structures into util/c2c.h
Ian Rogers <[email protected]>
| Newsgroups | org.kernel.vger.linux-perf-users,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAP-5=fVCRBrjPXxWSmqf+vFbhhiFsWNp8TrDLCMT-XiSYHcZ=g@mail.gmail.com> |
On Mon, Aug 17, 2026 at 2:40 AM Jiebin Sun <[email protected]> wrote: > > The function browser belongs in libperf-ui.a, but that archive is also > linked into python/perf.so, where builtin command objects are unavailable. > The browser therefore cannot depend on types or callbacks owned by > builtin-c2c.c. > > Move c2c_hists, compute_stats, c2c_hist_entry, and the shared column > formatting definitions from builtin-c2c.c to a new util/c2c.h. Move > c2c_fmt_free() and c2c_fmt_equal() to a new util/c2c.c. > > Keep struct perf_c2c, the command instance, and > perf_c2c__browse_cacheline() private to builtin-c2c.c. > > No functional change. > > Signed-off-by: Jiebin Sun <[email protected]> > Cc: Adrian Hunter <[email protected]> > Cc: Alexander Shishkin <[email protected]> > Cc: Arnaldo Carvalho de Melo <[email protected]> > Cc: Dapeng Mi <[email protected]> > Cc: Ian Rogers <[email protected]> > Cc: Ingo Molnar <[email protected]> > Cc: James Clark <[email protected]> > Cc: Jiri Olsa <[email protected]> > Cc: Mark Rutland <[email protected]> > Cc: Namhyung Kim <[email protected]> > Cc: Peter Zijlstra <[email protected]> > Cc: Thomas Falcon <[email protected]> > Reviewed-by: Tianyou Li <[email protected]> > Reviewed-by: Wangyang Guo <[email protected]> Reviewed-by: Ian Rogers <[email protected]> Thanks, Ian > --- > tools/perf/builtin-c2c.c | 105 ++------------------------------------- > tools/perf/util/Build | 1 + > tools/perf/util/c2c.c | 21 ++++++++ > tools/perf/util/c2c.h | 101 +++++++++++++++++++++++++++++++++++++ > 4 files changed, 126 insertions(+), 102 deletions(-) > create mode 100644 tools/perf/util/c2c.c > create mode 100644 tools/perf/util/c2c.h > > diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c > index bc16a57e0927..16b00a36fdfc 100644 > --- a/tools/perf/builtin-c2c.c > +++ b/tools/perf/builtin-c2c.c > @@ -52,46 +52,10 @@ > #include "ui/progress.h" > #include "ui/ui.h" > #include "util/annotate.h" > +#include "util/c2c.h" > #include "util/symbol.h" > #include "util/util.h" > > -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; > -}; > - > static char const *coalesce_default = "iaddr"; > > struct perf_c2c { > @@ -460,36 +424,6 @@ static const char * const __usage_report[] = { > > static const char * const *report_c2c_usage = __usage_report; > > -#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 *, struct hist_entry *); > - 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 > - > static struct c2c_dimension dim_symbol; > static struct c2c_dimension dim_srcline; > > @@ -1391,23 +1325,6 @@ cl_idx_empty_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, > return scnprintf(hpp->buf, hpp->size, "%*s", width, ""); > } > > -#define HEADER_LOW(__h) \ > - { \ > - .line[1] = { \ > - .text = __h, \ > - }, \ > - } > - > -#define HEADER_BOTH(__h0, __h1) \ > - { \ > - .line[0] = { \ > - .text = __h0, \ > - }, \ > - .line[1] = { \ > - .text = __h1, \ > - }, \ > - } > - > #define HEADER_SPAN(__h0, __h1, __s) \ > { \ > .line[0] = { \ > @@ -1930,22 +1847,6 @@ static struct c2c_dimension *dimensions[] = { > NULL, > }; > > -static void fmt_free(struct perf_hpp_fmt *fmt) > -{ > - struct c2c_fmt *c2c_fmt; > - > - c2c_fmt = container_of(fmt, struct c2c_fmt, fmt); > - free(c2c_fmt); > -} > - > -static bool fmt_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b) > -{ > - struct c2c_fmt *c2c_a = container_of(a, struct c2c_fmt, fmt); > - struct c2c_fmt *c2c_b = container_of(b, struct c2c_fmt, fmt); > - > - return c2c_a->dim == c2c_b->dim; > -} > - > static struct c2c_dimension *get_dimension(const char *name) > { > unsigned int i; > @@ -2023,8 +1924,8 @@ static struct c2c_fmt *get_format(const char *name) > fmt->header = c2c_header; > fmt->width = c2c_width; > fmt->collapse = dim->se ? c2c_se_collapse : dim->cmp; > - fmt->equal = fmt_equal; > - fmt->free = fmt_free; > + fmt->equal = c2c_fmt_equal; > + fmt->free = c2c_fmt_free; > > return c2c_fmt; > } > diff --git a/tools/perf/util/Build b/tools/perf/util/Build > index 330311cac550..1dfd92cbe3b7 100644 > --- a/tools/perf/util/Build > +++ b/tools/perf/util/Build > @@ -11,6 +11,7 @@ perf-util-y += blake2s.o > perf-util-y += block-info.o > perf-util-y += block-range.o > perf-util-y += build-id.o > +perf-util-y += c2c.o > perf-util-y += cacheline.o > perf-util-$(CONFIG_LIBCAPSTONE) += capstone.o > perf-util-y += config.o > diff --git a/tools/perf/util/c2c.c b/tools/perf/util/c2c.c > new file mode 100644 > index 000000000000..58c7342dff46 > --- /dev/null > +++ b/tools/perf/util/c2c.c > @@ -0,0 +1,21 @@ > +// SPDX-License-Identifier: GPL-2.0 > +#include <stdlib.h> > +#include <linux/kernel.h> > +#include "hist.h" > +#include "c2c.h" > + > +void c2c_fmt_free(struct perf_hpp_fmt *fmt) > +{ > + struct c2c_fmt *c2c_fmt; > + > + c2c_fmt = container_of(fmt, struct c2c_fmt, fmt); > + free(c2c_fmt); > +} > + > +bool c2c_fmt_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b) > +{ > + struct c2c_fmt *c2c_a = container_of(a, struct c2c_fmt, fmt); > + struct c2c_fmt *c2c_b = container_of(b, struct c2c_fmt, fmt); > + > + return c2c_a->dim == c2c_b->dim; > +} > diff --git a/tools/perf/util/c2c.h b/tools/perf/util/c2c.h > new file mode 100644 > index 000000000000..bd0c9d1c9a1a > --- /dev/null > +++ b/tools/perf/util/c2c.h > @@ -0,0 +1,101 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef __PERF_UTIL_C2C_H > +#define __PERF_UTIL_C2C_H > + > +#include <stdbool.h> > +#include <stdint.h> > +#include <linux/types.h> > +#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); > + > +#endif /* __PERF_UTIL_C2C_H */ > -- > 2.52.0 >