* [PATCH] perf utilities: cln_size header
@ 2026-02-14 4:07 Ricky Ringler
2026-03-04 1:25 ` Namhyung Kim
0 siblings, 1 reply; 8+ messages in thread
From: Ricky Ringler @ 2026-02-14 4:07 UTC (permalink / raw)
To: acme; +Cc: namhyung, peterz, mingo, linux-kernel, linux-perf-users,
Ricky Ringler
Store cacheline size during perf record in header, so
that cacheline size can be used for other features, like
sort.
Follow-up patch from message ID "aYZiQk6Uftzlb_JV@x1"
Testing:
- Built perf
- Ran record + report with feat enabled
- Ran record + report with feat disabled
Tested-by: Ricky Ringler <ricky.ringler@proton.me>
Signed-off-by: Ricky Ringler <ricky.ringler@proton.me>
---
tools/perf/builtin-inject.c | 1 +
tools/perf/util/env.h | 1 +
| 29 +++++++++++++++++++++++++++++
| 1 +
tools/perf/util/sort.c | 37 ++++++++++++++++++++++++++-----------
5 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index aa7be4fb5838..9639154459d9 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -2047,6 +2047,7 @@ static bool keep_feat(int feat)
case HEADER_CLOCK_DATA:
case HEADER_HYBRID_TOPOLOGY:
case HEADER_PMU_CAPS:
+ case HEADER_CLN_SIZE:
return true;
/* Information that can be updated */
case HEADER_BUILD_ID:
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 9977b85523a8..04580c64847b 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -93,6 +93,7 @@ struct perf_env {
struct cpu_topology_map *cpu;
struct cpu_cache_level *caches;
int caches_cnt;
+ unsigned int cln_size;
u32 comp_ratio;
u32 comp_ver;
u32 comp_type;
--git a/tools/perf/util/header.c b/tools/perf/util/header.c
index f5cad377c99e..ad15829acc69 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -54,6 +54,7 @@
#include "bpf-event.h"
#include "bpf-utils.h"
#include "clockid.h"
+#include "cacheline.h"
#include <linux/ctype.h>
#include <internal/lib.h>
@@ -1288,6 +1289,18 @@ static int write_cache(struct feat_fd *ff,
return ret;
}
+static int write_cln_size(struct feat_fd *ff,
+ struct evlist *evlist __maybe_unused)
+{
+ int cln_size = cacheline_size();
+
+ if (!cln_size)
+ cln_size = 0;
+ ff->ph->env.cln_size = cln_size;
+
+ return do_write(ff, &cln_size, sizeof(cln_size));
+}
+
static int write_stat(struct feat_fd *ff __maybe_unused,
struct evlist *evlist __maybe_unused)
{
@@ -2084,6 +2097,11 @@ static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused)
}
}
+static void print_cln_size(struct feat_fd *ff, FILE *fp __maybe_unused)
+{
+ fprintf(fp, "# cacheline size: %u\n", ff->ph->env.cln_size);
+}
+
static void print_compressed(struct feat_fd *ff, FILE *fp)
{
fprintf(fp, "# compressed : %s, level = %d, ratio = %d\n",
@@ -2933,6 +2951,16 @@ static int process_cache(struct feat_fd *ff, void *data __maybe_unused)
return -1;
}
+static int process_cln_size(struct feat_fd *ff, void *data __maybe_unused)
+{
+ struct perf_env *env = &ff->ph->env;
+
+ if (do_read_u32(ff, &env->cln_size))
+ return -1;
+
+ return 0;
+}
+
static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
{
struct perf_session *session;
@@ -3453,6 +3481,7 @@ const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = {
FEAT_OPR(CLOCK_DATA, clock_data, false),
FEAT_OPN(HYBRID_TOPOLOGY, hybrid_topology, true),
FEAT_OPR(PMU_CAPS, pmu_caps, false),
+ FEAT_OPR(CLN_SIZE, cln_size, false),
};
struct header_print_data {
--git a/tools/perf/util/header.h b/tools/perf/util/header.h
index c058021c3150..04394331630f 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -53,6 +53,7 @@ enum {
HEADER_CLOCK_DATA,
HEADER_HYBRID_TOPOLOGY,
HEADER_PMU_CAPS,
+ HEADER_CLN_SIZE,
HEADER_LAST_FEATURE,
HEADER_FEAT_BITS = 256,
};
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index aa79eb6476dd..e636b9f88e5c 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -30,6 +30,7 @@
#include "time-utils.h"
#include "cgroup.h"
#include "machine.h"
+#include "session.h"
#include "trace-event.h"
#include <linux/kernel.h>
#include <linux/string.h>
@@ -2474,7 +2475,26 @@ struct sort_entry sort_type_offset = {
/* --sort typecln */
-#define DEFAULT_CACHELINE_SIZE 64
+static int
+hist_entry__cln_size(struct hist_entry *he)
+{
+ int ret = 0;
+
+ if (he && he->hists) {
+ struct evsel *evsel = hists_to_evsel(he->hists);
+
+ if (evsel && evsel->evlist->session && evsel->evlist->session)
+ ret = evsel->evlist->session->header.env.cln_size;
+ }
+
+ if (!ret || ret < 1) {
+ int default_cacheline_size = 64; // avoid div/0 later
+
+ ret = default_cacheline_size;
+ }
+
+ return ret;
+}
static int64_t
sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
@@ -2482,11 +2502,9 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
struct annotated_data_type *left_type = left->mem_type;
struct annotated_data_type *right_type = right->mem_type;
int64_t left_cln, right_cln;
+ int64_t cln_size_left = hist_entry__cln_size(left);
+ int64_t cln_size_right = hist_entry__cln_size(right);
int64_t ret;
- int cln_size = cacheline_size();
-
- if (cln_size == 0)
- cln_size = DEFAULT_CACHELINE_SIZE;
if (!left_type) {
sort__type_init(left);
@@ -2502,8 +2520,8 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
if (ret)
return ret;
- left_cln = left->mem_type_off / cln_size;
- right_cln = right->mem_type_off / cln_size;
+ left_cln = left->mem_type_off / cln_size_left;
+ right_cln = right->mem_type_off / cln_size_right;
return left_cln - right_cln;
}
@@ -2511,10 +2529,7 @@ static int hist_entry__typecln_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width __maybe_unused)
{
struct annotated_data_type *he_type = he->mem_type;
- int cln_size = cacheline_size();
-
- if (cln_size == 0)
- cln_size = DEFAULT_CACHELINE_SIZE;
+ int cln_size = hist_entry__cln_size(he);
return repsep_snprintf(bf, size, "%s: cache-line %d", he_type->self.type_name,
he->mem_type_off / cln_size);
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH] perf utilities: cln_size header
2026-02-14 4:07 [PATCH] perf utilities: cln_size header Ricky Ringler
@ 2026-03-04 1:25 ` Namhyung Kim
2026-03-05 23:57 ` [PATCH v2] " Ricky Ringler
0 siblings, 1 reply; 8+ messages in thread
From: Namhyung Kim @ 2026-03-04 1:25 UTC (permalink / raw)
To: Ricky Ringler; +Cc: acme, peterz, mingo, linux-kernel, linux-perf-users
Hello,
On Sat, Feb 14, 2026 at 04:07:25AM +0000, Ricky Ringler wrote:
> Store cacheline size during perf record in header, so
> that cacheline size can be used for other features, like
> sort.
>
> Follow-up patch from message ID "aYZiQk6Uftzlb_JV@x1"
>
> Testing:
> - Built perf
> - Ran record + report with feat enabled
> - Ran record + report with feat disabled
Sorry for the delay. Can you please rebase this on top of the current
perf-tools-next? We added a couple more header features recently.
Thanks,
Namhyung
>
> Tested-by: Ricky Ringler <ricky.ringler@proton.me>
> Signed-off-by: Ricky Ringler <ricky.ringler@proton.me>
> ---
> tools/perf/builtin-inject.c | 1 +
> tools/perf/util/env.h | 1 +
> tools/perf/util/header.c | 29 +++++++++++++++++++++++++++++
> tools/perf/util/header.h | 1 +
> tools/perf/util/sort.c | 37 ++++++++++++++++++++++++++-----------
> 5 files changed, 58 insertions(+), 11 deletions(-)
>
> diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
> index aa7be4fb5838..9639154459d9 100644
> --- a/tools/perf/builtin-inject.c
> +++ b/tools/perf/builtin-inject.c
> @@ -2047,6 +2047,7 @@ static bool keep_feat(int feat)
> case HEADER_CLOCK_DATA:
> case HEADER_HYBRID_TOPOLOGY:
> case HEADER_PMU_CAPS:
> + case HEADER_CLN_SIZE:
> return true;
> /* Information that can be updated */
> case HEADER_BUILD_ID:
> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
> index 9977b85523a8..04580c64847b 100644
> --- a/tools/perf/util/env.h
> +++ b/tools/perf/util/env.h
> @@ -93,6 +93,7 @@ struct perf_env {
> struct cpu_topology_map *cpu;
> struct cpu_cache_level *caches;
> int caches_cnt;
> + unsigned int cln_size;
> u32 comp_ratio;
> u32 comp_ver;
> u32 comp_type;
> diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
> index f5cad377c99e..ad15829acc69 100644
> --- a/tools/perf/util/header.c
> +++ b/tools/perf/util/header.c
> @@ -54,6 +54,7 @@
> #include "bpf-event.h"
> #include "bpf-utils.h"
> #include "clockid.h"
> +#include "cacheline.h"
>
> #include <linux/ctype.h>
> #include <internal/lib.h>
> @@ -1288,6 +1289,18 @@ static int write_cache(struct feat_fd *ff,
> return ret;
> }
>
> +static int write_cln_size(struct feat_fd *ff,
> + struct evlist *evlist __maybe_unused)
> +{
> + int cln_size = cacheline_size();
> +
> + if (!cln_size)
> + cln_size = 0;
> + ff->ph->env.cln_size = cln_size;
> +
> + return do_write(ff, &cln_size, sizeof(cln_size));
> +}
> +
> static int write_stat(struct feat_fd *ff __maybe_unused,
> struct evlist *evlist __maybe_unused)
> {
> @@ -2084,6 +2097,11 @@ static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused)
> }
> }
>
> +static void print_cln_size(struct feat_fd *ff, FILE *fp __maybe_unused)
> +{
> + fprintf(fp, "# cacheline size: %u\n", ff->ph->env.cln_size);
> +}
> +
> static void print_compressed(struct feat_fd *ff, FILE *fp)
> {
> fprintf(fp, "# compressed : %s, level = %d, ratio = %d\n",
> @@ -2933,6 +2951,16 @@ static int process_cache(struct feat_fd *ff, void *data __maybe_unused)
> return -1;
> }
>
> +static int process_cln_size(struct feat_fd *ff, void *data __maybe_unused)
> +{
> + struct perf_env *env = &ff->ph->env;
> +
> + if (do_read_u32(ff, &env->cln_size))
> + return -1;
> +
> + return 0;
> +}
> +
> static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
> {
> struct perf_session *session;
> @@ -3453,6 +3481,7 @@ const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = {
> FEAT_OPR(CLOCK_DATA, clock_data, false),
> FEAT_OPN(HYBRID_TOPOLOGY, hybrid_topology, true),
> FEAT_OPR(PMU_CAPS, pmu_caps, false),
> + FEAT_OPR(CLN_SIZE, cln_size, false),
> };
>
> struct header_print_data {
> diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
> index c058021c3150..04394331630f 100644
> --- a/tools/perf/util/header.h
> +++ b/tools/perf/util/header.h
> @@ -53,6 +53,7 @@ enum {
> HEADER_CLOCK_DATA,
> HEADER_HYBRID_TOPOLOGY,
> HEADER_PMU_CAPS,
> + HEADER_CLN_SIZE,
> HEADER_LAST_FEATURE,
> HEADER_FEAT_BITS = 256,
> };
> diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
> index aa79eb6476dd..e636b9f88e5c 100644
> --- a/tools/perf/util/sort.c
> +++ b/tools/perf/util/sort.c
> @@ -30,6 +30,7 @@
> #include "time-utils.h"
> #include "cgroup.h"
> #include "machine.h"
> +#include "session.h"
> #include "trace-event.h"
> #include <linux/kernel.h>
> #include <linux/string.h>
> @@ -2474,7 +2475,26 @@ struct sort_entry sort_type_offset = {
>
> /* --sort typecln */
>
> -#define DEFAULT_CACHELINE_SIZE 64
> +static int
> +hist_entry__cln_size(struct hist_entry *he)
> +{
> + int ret = 0;
> +
> + if (he && he->hists) {
> + struct evsel *evsel = hists_to_evsel(he->hists);
> +
> + if (evsel && evsel->evlist->session && evsel->evlist->session)
> + ret = evsel->evlist->session->header.env.cln_size;
> + }
> +
> + if (!ret || ret < 1) {
> + int default_cacheline_size = 64; // avoid div/0 later
> +
> + ret = default_cacheline_size;
> + }
> +
> + return ret;
> +}
>
> static int64_t
> sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
> @@ -2482,11 +2502,9 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
> struct annotated_data_type *left_type = left->mem_type;
> struct annotated_data_type *right_type = right->mem_type;
> int64_t left_cln, right_cln;
> + int64_t cln_size_left = hist_entry__cln_size(left);
> + int64_t cln_size_right = hist_entry__cln_size(right);
> int64_t ret;
> - int cln_size = cacheline_size();
> -
> - if (cln_size == 0)
> - cln_size = DEFAULT_CACHELINE_SIZE;
>
> if (!left_type) {
> sort__type_init(left);
> @@ -2502,8 +2520,8 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
> if (ret)
> return ret;
>
> - left_cln = left->mem_type_off / cln_size;
> - right_cln = right->mem_type_off / cln_size;
> + left_cln = left->mem_type_off / cln_size_left;
> + right_cln = right->mem_type_off / cln_size_right;
> return left_cln - right_cln;
> }
>
> @@ -2511,10 +2529,7 @@ static int hist_entry__typecln_snprintf(struct hist_entry *he, char *bf,
> size_t size, unsigned int width __maybe_unused)
> {
> struct annotated_data_type *he_type = he->mem_type;
> - int cln_size = cacheline_size();
> -
> - if (cln_size == 0)
> - cln_size = DEFAULT_CACHELINE_SIZE;
> + int cln_size = hist_entry__cln_size(he);
>
> return repsep_snprintf(bf, size, "%s: cache-line %d", he_type->self.type_name,
> he->mem_type_off / cln_size);
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v2] perf utilities: cln_size header
2026-03-04 1:25 ` Namhyung Kim
@ 2026-03-05 23:57 ` Ricky Ringler
2026-03-06 0:12 ` Ricky Ringler
0 siblings, 1 reply; 8+ messages in thread
From: Ricky Ringler @ 2026-03-05 23:57 UTC (permalink / raw)
To: namhyung; +Cc: peterz, mingo, acme, linux-kernel, linux-perf-users,
Ricky Ringler
Store cacheline size during perf record in header, so
that cacheline size can be used for other features, like
sort.
Follow-up patch from message ID "aYZiQk6Uftzlb_JV@x1"
Testing:
- Built perf
- Ran record + report with feat enabled
- Ran record + report with feat disabled
Tested-by: Ricky Ringler <ricky.ringler@proton.me>
Signed-off-by: Ricky Ringler <ricky.ringler@proton.me>
---
tools/perf/builtin-inject.c | 1 +
tools/perf/util/env.h | 1 +
| 29 +++++++++++++++++++++++++++++
| 1 +
tools/perf/util/sort.c | 37 ++++++++++++++++++++++++++-----------
5 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index aa7be4fb5838..9639154459d9 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -2047,6 +2047,7 @@ static bool keep_feat(int feat)
case HEADER_CLOCK_DATA:
case HEADER_HYBRID_TOPOLOGY:
case HEADER_PMU_CAPS:
+ case HEADER_CLN_SIZE:
return true;
/* Information that can be updated */
case HEADER_BUILD_ID:
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 9977b85523a8..04580c64847b 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -93,6 +93,7 @@ struct perf_env {
struct cpu_topology_map *cpu;
struct cpu_cache_level *caches;
int caches_cnt;
+ unsigned int cln_size;
u32 comp_ratio;
u32 comp_ver;
u32 comp_type;
--git a/tools/perf/util/header.c b/tools/perf/util/header.c
index f5cad377c99e..ad15829acc69 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -54,6 +54,7 @@
#include "bpf-event.h"
#include "bpf-utils.h"
#include "clockid.h"
+#include "cacheline.h"
#include <linux/ctype.h>
#include <internal/lib.h>
@@ -1288,6 +1289,18 @@ static int write_cache(struct feat_fd *ff,
return ret;
}
+static int write_cln_size(struct feat_fd *ff,
+ struct evlist *evlist __maybe_unused)
+{
+ int cln_size = cacheline_size();
+
+ if (!cln_size)
+ cln_size = 0;
+ ff->ph->env.cln_size = cln_size;
+
+ return do_write(ff, &cln_size, sizeof(cln_size));
+}
+
static int write_stat(struct feat_fd *ff __maybe_unused,
struct evlist *evlist __maybe_unused)
{
@@ -2084,6 +2097,11 @@ static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused)
}
}
+static void print_cln_size(struct feat_fd *ff, FILE *fp __maybe_unused)
+{
+ fprintf(fp, "# cacheline size: %u\n", ff->ph->env.cln_size);
+}
+
static void print_compressed(struct feat_fd *ff, FILE *fp)
{
fprintf(fp, "# compressed : %s, level = %d, ratio = %d\n",
@@ -2933,6 +2951,16 @@ static int process_cache(struct feat_fd *ff, void *data __maybe_unused)
return -1;
}
+static int process_cln_size(struct feat_fd *ff, void *data __maybe_unused)
+{
+ struct perf_env *env = &ff->ph->env;
+
+ if (do_read_u32(ff, &env->cln_size))
+ return -1;
+
+ return 0;
+}
+
static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
{
struct perf_session *session;
@@ -3453,6 +3481,7 @@ const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = {
FEAT_OPR(CLOCK_DATA, clock_data, false),
FEAT_OPN(HYBRID_TOPOLOGY, hybrid_topology, true),
FEAT_OPR(PMU_CAPS, pmu_caps, false),
+ FEAT_OPR(CLN_SIZE, cln_size, false),
};
struct header_print_data {
--git a/tools/perf/util/header.h b/tools/perf/util/header.h
index c058021c3150..04394331630f 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -53,6 +53,7 @@ enum {
HEADER_CLOCK_DATA,
HEADER_HYBRID_TOPOLOGY,
HEADER_PMU_CAPS,
+ HEADER_CLN_SIZE,
HEADER_LAST_FEATURE,
HEADER_FEAT_BITS = 256,
};
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index aa79eb6476dd..e636b9f88e5c 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -30,6 +30,7 @@
#include "time-utils.h"
#include "cgroup.h"
#include "machine.h"
+#include "session.h"
#include "trace-event.h"
#include <linux/kernel.h>
#include <linux/string.h>
@@ -2474,7 +2475,26 @@ struct sort_entry sort_type_offset = {
/* --sort typecln */
-#define DEFAULT_CACHELINE_SIZE 64
+static int
+hist_entry__cln_size(struct hist_entry *he)
+{
+ int ret = 0;
+
+ if (he && he->hists) {
+ struct evsel *evsel = hists_to_evsel(he->hists);
+
+ if (evsel && evsel->evlist->session && evsel->evlist->session)
+ ret = evsel->evlist->session->header.env.cln_size;
+ }
+
+ if (!ret || ret < 1) {
+ int default_cacheline_size = 64; // avoid div/0 later
+
+ ret = default_cacheline_size;
+ }
+
+ return ret;
+}
static int64_t
sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
@@ -2482,11 +2502,9 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
struct annotated_data_type *left_type = left->mem_type;
struct annotated_data_type *right_type = right->mem_type;
int64_t left_cln, right_cln;
+ int64_t cln_size_left = hist_entry__cln_size(left);
+ int64_t cln_size_right = hist_entry__cln_size(right);
int64_t ret;
- int cln_size = cacheline_size();
-
- if (cln_size == 0)
- cln_size = DEFAULT_CACHELINE_SIZE;
if (!left_type) {
sort__type_init(left);
@@ -2502,8 +2520,8 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
if (ret)
return ret;
- left_cln = left->mem_type_off / cln_size;
- right_cln = right->mem_type_off / cln_size;
+ left_cln = left->mem_type_off / cln_size_left;
+ right_cln = right->mem_type_off / cln_size_right;
return left_cln - right_cln;
}
@@ -2511,10 +2529,7 @@ static int hist_entry__typecln_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width __maybe_unused)
{
struct annotated_data_type *he_type = he->mem_type;
- int cln_size = cacheline_size();
-
- if (cln_size == 0)
- cln_size = DEFAULT_CACHELINE_SIZE;
+ int cln_size = hist_entry__cln_size(he);
return repsep_snprintf(bf, size, "%s: cache-line %d", he_type->self.type_name,
he->mem_type_off / cln_size);
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v2] perf utilities: cln_size header
2026-03-05 23:57 ` [PATCH v2] " Ricky Ringler
@ 2026-03-06 0:12 ` Ricky Ringler
2026-03-08 17:20 ` [PATCH v3] " Ricky Ringler
0 siblings, 1 reply; 8+ messages in thread
From: Ricky Ringler @ 2026-03-06 0:12 UTC (permalink / raw)
To: namhyung; +Cc: peterz, mingo, acme, linux-kernel, linux-perf-users,
Ricky Ringler
Apologies all. I just realized I rebased on the kernel instead of perf-tools-next. Please hold off reviewing. I will submit a v3 patch rebased on perf-tools-next.
On Thursday, March 5th, 2026 at 5:57 PM, Ricky Ringler <ricky.ringler@proton.me> wrote:
> Store cacheline size during perf record in header, so
> that cacheline size can be used for other features, like
> sort.
>
> Follow-up patch from message ID "aYZiQk6Uftzlb_JV@x1"
>
> Testing:
> - Built perf
> - Ran record + report with feat enabled
> - Ran record + report with feat disabled
>
> Tested-by: Ricky Ringler <ricky.ringler@proton.me>
> Signed-off-by: Ricky Ringler <ricky.ringler@proton.me>
> ---
> tools/perf/builtin-inject.c | 1 +
> tools/perf/util/env.h | 1 +
> tools/perf/util/header.c | 29 +++++++++++++++++++++++++++++
> tools/perf/util/header.h | 1 +
> tools/perf/util/sort.c | 37 ++++++++++++++++++++++++++-----------
> 5 files changed, 58 insertions(+), 11 deletions(-)
>
> diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
> index aa7be4fb5838..9639154459d9 100644
> --- a/tools/perf/builtin-inject.c
> +++ b/tools/perf/builtin-inject.c
> @@ -2047,6 +2047,7 @@ static bool keep_feat(int feat)
> case HEADER_CLOCK_DATA:
> case HEADER_HYBRID_TOPOLOGY:
> case HEADER_PMU_CAPS:
> + case HEADER_CLN_SIZE:
> return true;
> /* Information that can be updated */
> case HEADER_BUILD_ID:
> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
> index 9977b85523a8..04580c64847b 100644
> --- a/tools/perf/util/env.h
> +++ b/tools/perf/util/env.h
> @@ -93,6 +93,7 @@ struct perf_env {
> struct cpu_topology_map *cpu;
> struct cpu_cache_level *caches;
> int caches_cnt;
> + unsigned int cln_size;
> u32 comp_ratio;
> u32 comp_ver;
> u32 comp_type;
> diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
> index f5cad377c99e..ad15829acc69 100644
> --- a/tools/perf/util/header.c
> +++ b/tools/perf/util/header.c
> @@ -54,6 +54,7 @@
> #include "bpf-event.h"
> #include "bpf-utils.h"
> #include "clockid.h"
> +#include "cacheline.h"
>
> #include <linux/ctype.h>
> #include <internal/lib.h>
> @@ -1288,6 +1289,18 @@ static int write_cache(struct feat_fd *ff,
> return ret;
> }
>
> +static int write_cln_size(struct feat_fd *ff,
> + struct evlist *evlist __maybe_unused)
> +{
> + int cln_size = cacheline_size();
> +
> + if (!cln_size)
> + cln_size = 0;
> + ff->ph->env.cln_size = cln_size;
> +
> + return do_write(ff, &cln_size, sizeof(cln_size));
> +}
> +
> static int write_stat(struct feat_fd *ff __maybe_unused,
> struct evlist *evlist __maybe_unused)
> {
> @@ -2084,6 +2097,11 @@ static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused)
> }
> }
>
> +static void print_cln_size(struct feat_fd *ff, FILE *fp __maybe_unused)
> +{
> + fprintf(fp, "# cacheline size: %u\n", ff->ph->env.cln_size);
> +}
> +
> static void print_compressed(struct feat_fd *ff, FILE *fp)
> {
> fprintf(fp, "# compressed : %s, level = %d, ratio = %d\n",
> @@ -2933,6 +2951,16 @@ static int process_cache(struct feat_fd *ff, void *data __maybe_unused)
> return -1;
> }
>
> +static int process_cln_size(struct feat_fd *ff, void *data __maybe_unused)
> +{
> + struct perf_env *env = &ff->ph->env;
> +
> + if (do_read_u32(ff, &env->cln_size))
> + return -1;
> +
> + return 0;
> +}
> +
> static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
> {
> struct perf_session *session;
> @@ -3453,6 +3481,7 @@ const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = {
> FEAT_OPR(CLOCK_DATA, clock_data, false),
> FEAT_OPN(HYBRID_TOPOLOGY, hybrid_topology, true),
> FEAT_OPR(PMU_CAPS, pmu_caps, false),
> + FEAT_OPR(CLN_SIZE, cln_size, false),
> };
>
> struct header_print_data {
> diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
> index c058021c3150..04394331630f 100644
> --- a/tools/perf/util/header.h
> +++ b/tools/perf/util/header.h
> @@ -53,6 +53,7 @@ enum {
> HEADER_CLOCK_DATA,
> HEADER_HYBRID_TOPOLOGY,
> HEADER_PMU_CAPS,
> + HEADER_CLN_SIZE,
> HEADER_LAST_FEATURE,
> HEADER_FEAT_BITS = 256,
> };
> diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
> index aa79eb6476dd..e636b9f88e5c 100644
> --- a/tools/perf/util/sort.c
> +++ b/tools/perf/util/sort.c
> @@ -30,6 +30,7 @@
> #include "time-utils.h"
> #include "cgroup.h"
> #include "machine.h"
> +#include "session.h"
> #include "trace-event.h"
> #include <linux/kernel.h>
> #include <linux/string.h>
> @@ -2474,7 +2475,26 @@ struct sort_entry sort_type_offset = {
>
> /* --sort typecln */
>
> -#define DEFAULT_CACHELINE_SIZE 64
> +static int
> +hist_entry__cln_size(struct hist_entry *he)
> +{
> + int ret = 0;
> +
> + if (he && he->hists) {
> + struct evsel *evsel = hists_to_evsel(he->hists);
> +
> + if (evsel && evsel->evlist->session && evsel->evlist->session)
> + ret = evsel->evlist->session->header.env.cln_size;
> + }
> +
> + if (!ret || ret < 1) {
> + int default_cacheline_size = 64; // avoid div/0 later
> +
> + ret = default_cacheline_size;
> + }
> +
> + return ret;
> +}
>
> static int64_t
> sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
> @@ -2482,11 +2502,9 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
> struct annotated_data_type *left_type = left->mem_type;
> struct annotated_data_type *right_type = right->mem_type;
> int64_t left_cln, right_cln;
> + int64_t cln_size_left = hist_entry__cln_size(left);
> + int64_t cln_size_right = hist_entry__cln_size(right);
> int64_t ret;
> - int cln_size = cacheline_size();
> -
> - if (cln_size == 0)
> - cln_size = DEFAULT_CACHELINE_SIZE;
>
> if (!left_type) {
> sort__type_init(left);
> @@ -2502,8 +2520,8 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
> if (ret)
> return ret;
>
> - left_cln = left->mem_type_off / cln_size;
> - right_cln = right->mem_type_off / cln_size;
> + left_cln = left->mem_type_off / cln_size_left;
> + right_cln = right->mem_type_off / cln_size_right;
> return left_cln - right_cln;
> }
>
> @@ -2511,10 +2529,7 @@ static int hist_entry__typecln_snprintf(struct hist_entry *he, char *bf,
> size_t size, unsigned int width __maybe_unused)
> {
> struct annotated_data_type *he_type = he->mem_type;
> - int cln_size = cacheline_size();
> -
> - if (cln_size == 0)
> - cln_size = DEFAULT_CACHELINE_SIZE;
> + int cln_size = hist_entry__cln_size(he);
>
> return repsep_snprintf(bf, size, "%s: cache-line %d", he_type->self.type_name,
> he->mem_type_off / cln_size);
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v3] perf utilities: cln_size header
2026-03-06 0:12 ` Ricky Ringler
@ 2026-03-08 17:20 ` Ricky Ringler
2026-03-09 15:28 ` Ian Rogers
0 siblings, 1 reply; 8+ messages in thread
From: Ricky Ringler @ 2026-03-08 17:20 UTC (permalink / raw)
To: namhyung; +Cc: mingo, acme, linux-kernel, linux-perf-users, Ricky Ringler
Store cacheline size during perf record in header, so
that cacheline size can be used for other features, like
sort.
Follow-up patch from message ID "aYZiQk6Uftzlb_JV@x1"
Testing:
- Built perf
- Ran record + report with feat enabled
- Ran record + report with feat disabled
Tested-by: Ricky Ringler <ricky.ringler@proton.me>
Signed-off-by: Ricky Ringler <ricky.ringler@proton.me>
---
tools/perf/builtin-inject.c | 1 +
tools/perf/util/env.h | 1 +
| 29 +++++++++++++++++++++++++++++
| 1 +
tools/perf/util/sort.c | 37 ++++++++++++++++++++++++++-----------
5 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 5b29f4296861..2675d32f88cf 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -2134,6 +2134,7 @@ static bool keep_feat(struct perf_inject *inject, int feat)
case HEADER_HYBRID_TOPOLOGY:
case HEADER_PMU_CAPS:
case HEADER_CPU_DOMAIN_INFO:
+ case HEADER_CLNq_SIZE:
return true;
/* Information that can be updated */
case HEADER_BUILD_ID:
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index a4501cbca375..c7052ac1f856 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -112,6 +112,7 @@ struct perf_env {
struct cpu_cache_level *caches;
struct cpu_domain_map **cpu_domain;
int caches_cnt;
+ unsigned int cln_size;
u32 comp_ratio;
u32 comp_ver;
u32 comp_type;
--git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 9142a8ba4019..4f65faafe75d 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -54,6 +54,7 @@
#include "bpf-event.h"
#include "bpf-utils.h"
#include "clockid.h"
+#include "cacheline.h"
#include <linux/ctype.h>
#include <internal/lib.h>
@@ -1304,6 +1305,18 @@ static int write_cache(struct feat_fd *ff,
return ret;
}
+static int write_cln_size(struct feat_fd *ff,
+ struct evlist *evlist __maybe_unused)
+{
+ int cln_size = cacheline_size();
+
+ if (!cln_size)
+ cln_size = 0;
+ ff->ph->env.cln_size = cln_size;
+
+ return do_write(ff, &cln_size, sizeof(cln_size));
+}
+
static int write_stat(struct feat_fd *ff __maybe_unused,
struct evlist *evlist __maybe_unused)
{
@@ -2261,6 +2274,11 @@ static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused)
}
}
+static void print_cln_size(struct feat_fd *ff, FILE *fp __maybe_unused)
+{
+ fprintf(fp, "# cacheline size: %u\n", ff->ph->env.cln_size);
+}
+
static void print_compressed(struct feat_fd *ff, FILE *fp)
{
fprintf(fp, "# compressed : %s, level = %d, ratio = %d\n",
@@ -3154,6 +3172,16 @@ static int process_cache(struct feat_fd *ff, void *data __maybe_unused)
return -1;
}
+static int process_cln_size(struct feat_fd *ff, void *data __maybe_unused)
+{
+ struct perf_env *env = &ff->ph->env;
+
+ if (do_read_u32(ff, &env->cln_size))
+ return -1;
+
+ return 0;
+}
+
static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
{
struct perf_session *session;
@@ -3763,6 +3791,7 @@ const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = {
FEAT_OPR(PMU_CAPS, pmu_caps, false),
FEAT_OPR(CPU_DOMAIN_INFO, cpu_domain_info, true),
FEAT_OPR(E_MACHINE, e_machine, false),
+ FEAT_OPR(CLN_SIZE, cln_size, false),
};
struct header_print_data {
--git a/tools/perf/util/header.h b/tools/perf/util/header.h
index cc40ac796f52..be315040727f 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -55,6 +55,7 @@ enum {
HEADER_PMU_CAPS,
HEADER_CPU_DOMAIN_INFO,
HEADER_E_MACHINE,
+ HEADER_CLN_SIZE,
HEADER_LAST_FEATURE,
HEADER_FEAT_BITS = 256,
};
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 42d5cd7ef4e2..13287ade784e 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -30,6 +30,7 @@
#include "time-utils.h"
#include "cgroup.h"
#include "machine.h"
+#include "session.h"
#include "trace-event.h"
#include <linux/kernel.h>
#include <linux/string.h>
@@ -2474,7 +2475,26 @@ struct sort_entry sort_type_offset = {
/* --sort typecln */
-#define DEFAULT_CACHELINE_SIZE 64
+static int
+hist_entry__cln_size(struct hist_entry *he)
+{
+ int ret = 0;
+
+ if (he && he->hists) {
+ struct evsel *evsel = hists_to_evsel(he->hists);
+
+ if (evsel && evsel->evlist->session && evsel->evlist->session)
+ ret = evsel->evlist->session->header.env.cln_size;
+ }
+
+ if (!ret || ret < 1) {
+ int default_cacheline_size = 64; // avoid div/0 later
+
+ ret = default_cacheline_size;
+ }
+
+ return ret;
+}
static int64_t
sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
@@ -2482,11 +2502,9 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
struct annotated_data_type *left_type = left->mem_type;
struct annotated_data_type *right_type = right->mem_type;
int64_t left_cln, right_cln;
+ int64_t cln_size_left = hist_entry__cln_size(left);
+ int64_t cln_size_right = hist_entry__cln_size(right);
int64_t ret;
- int cln_size = cacheline_size();
-
- if (cln_size == 0)
- cln_size = DEFAULT_CACHELINE_SIZE;
if (!left_type) {
sort__type_init(left);
@@ -2502,8 +2520,8 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
if (ret)
return ret;
- left_cln = left->mem_type_off / cln_size;
- right_cln = right->mem_type_off / cln_size;
+ left_cln = left->mem_type_off / cln_size_left;
+ right_cln = right->mem_type_off / cln_size_right;
return left_cln - right_cln;
}
@@ -2511,10 +2529,7 @@ static int hist_entry__typecln_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width __maybe_unused)
{
struct annotated_data_type *he_type = he->mem_type;
- int cln_size = cacheline_size();
-
- if (cln_size == 0)
- cln_size = DEFAULT_CACHELINE_SIZE;
+ int cln_size = hist_entry__cln_size(he);
return repsep_snprintf(bf, size, "%s: cache-line %d", he_type->self.type_name,
he->mem_type_off / cln_size);
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v3] perf utilities: cln_size header
2026-03-08 17:20 ` [PATCH v3] " Ricky Ringler
@ 2026-03-09 15:28 ` Ian Rogers
2026-03-21 20:41 ` [PATCH v4] " Ricky Ringler
0 siblings, 1 reply; 8+ messages in thread
From: Ian Rogers @ 2026-03-09 15:28 UTC (permalink / raw)
To: Ricky Ringler; +Cc: namhyung, mingo, acme, linux-kernel, linux-perf-users
On Sun, Mar 8, 2026 at 10:21 AM Ricky Ringler <ricky.ringler@proton.me> wrote:
>
> Store cacheline size during perf record in header, so
> that cacheline size can be used for other features, like
> sort.
>
> Follow-up patch from message ID "aYZiQk6Uftzlb_JV@x1"
>
> Testing:
> - Built perf
> - Ran record + report with feat enabled
> - Ran record + report with feat disabled
>
> Tested-by: Ricky Ringler <ricky.ringler@proton.me>
> Signed-off-by: Ricky Ringler <ricky.ringler@proton.me>
> ---
> tools/perf/builtin-inject.c | 1 +
> tools/perf/util/env.h | 1 +
> tools/perf/util/header.c | 29 +++++++++++++++++++++++++++++
> tools/perf/util/header.h | 1 +
> tools/perf/util/sort.c | 37 ++++++++++++++++++++++++++-----------
> 5 files changed, 58 insertions(+), 11 deletions(-)
>
> diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
> index 5b29f4296861..2675d32f88cf 100644
> --- a/tools/perf/builtin-inject.c
> +++ b/tools/perf/builtin-inject.c
> @@ -2134,6 +2134,7 @@ static bool keep_feat(struct perf_inject *inject, int feat)
> case HEADER_HYBRID_TOPOLOGY:
> case HEADER_PMU_CAPS:
> case HEADER_CPU_DOMAIN_INFO:
> + case HEADER_CLNq_SIZE:
Looks like a typo, s/HEADER_CLNq_SIZE/HEADER_CLN_SIZE/
> return true;
> /* Information that can be updated */
> case HEADER_BUILD_ID:
> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
> index a4501cbca375..c7052ac1f856 100644
> --- a/tools/perf/util/env.h
> +++ b/tools/perf/util/env.h
> @@ -112,6 +112,7 @@ struct perf_env {
> struct cpu_cache_level *caches;
> struct cpu_domain_map **cpu_domain;
> int caches_cnt;
> + unsigned int cln_size;
> u32 comp_ratio;
> u32 comp_ver;
> u32 comp_type;
> diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
> index 9142a8ba4019..4f65faafe75d 100644
> --- a/tools/perf/util/header.c
> +++ b/tools/perf/util/header.c
> @@ -54,6 +54,7 @@
> #include "bpf-event.h"
> #include "bpf-utils.h"
> #include "clockid.h"
> +#include "cacheline.h"
>
> #include <linux/ctype.h>
> #include <internal/lib.h>
> @@ -1304,6 +1305,18 @@ static int write_cache(struct feat_fd *ff,
> return ret;
> }
>
> +static int write_cln_size(struct feat_fd *ff,
> + struct evlist *evlist __maybe_unused)
> +{
> + int cln_size = cacheline_size();
> +
> + if (!cln_size)
> + cln_size = 0;
Did you mean to assign "cln_size = DEFAULT_CACHELINE_SIZE" here? It
seems strange to something with value 0 the value 0.
> + ff->ph->env.cln_size = cln_size;
> +
> + return do_write(ff, &cln_size, sizeof(cln_size));
> +}
> +
> static int write_stat(struct feat_fd *ff __maybe_unused,
> struct evlist *evlist __maybe_unused)
> {
> @@ -2261,6 +2274,11 @@ static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused)
> }
> }
>
> +static void print_cln_size(struct feat_fd *ff, FILE *fp __maybe_unused)
No need for the __maybe_unused on fp here.
> +{
> + fprintf(fp, "# cacheline size: %u\n", ff->ph->env.cln_size);
> +}
> +
> static void print_compressed(struct feat_fd *ff, FILE *fp)
> {
> fprintf(fp, "# compressed : %s, level = %d, ratio = %d\n",
> @@ -3154,6 +3172,16 @@ static int process_cache(struct feat_fd *ff, void *data __maybe_unused)
> return -1;
> }
>
> +static int process_cln_size(struct feat_fd *ff, void *data __maybe_unused)
> +{
> + struct perf_env *env = &ff->ph->env;
> +
> + if (do_read_u32(ff, &env->cln_size))
> + return -1;
> +
> + return 0;
> +}
> +
> static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
> {
> struct perf_session *session;
> @@ -3763,6 +3791,7 @@ const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = {
> FEAT_OPR(PMU_CAPS, pmu_caps, false),
> FEAT_OPR(CPU_DOMAIN_INFO, cpu_domain_info, true),
> FEAT_OPR(E_MACHINE, e_machine, false),
> + FEAT_OPR(CLN_SIZE, cln_size, false),
> };
>
> struct header_print_data {
> diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
> index cc40ac796f52..be315040727f 100644
> --- a/tools/perf/util/header.h
> +++ b/tools/perf/util/header.h
> @@ -55,6 +55,7 @@ enum {
> HEADER_PMU_CAPS,
> HEADER_CPU_DOMAIN_INFO,
> HEADER_E_MACHINE,
> + HEADER_CLN_SIZE,
> HEADER_LAST_FEATURE,
> HEADER_FEAT_BITS = 256,
> };
> diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
> index 42d5cd7ef4e2..13287ade784e 100644
> --- a/tools/perf/util/sort.c
> +++ b/tools/perf/util/sort.c
> @@ -30,6 +30,7 @@
> #include "time-utils.h"
> #include "cgroup.h"
> #include "machine.h"
> +#include "session.h"
> #include "trace-event.h"
> #include <linux/kernel.h>
> #include <linux/string.h>
> @@ -2474,7 +2475,26 @@ struct sort_entry sort_type_offset = {
>
> /* --sort typecln */
>
> -#define DEFAULT_CACHELINE_SIZE 64
> +static int
> +hist_entry__cln_size(struct hist_entry *he)
> +{
> + int ret = 0;
> +
> + if (he && he->hists) {
> + struct evsel *evsel = hists_to_evsel(he->hists);
> +
> + if (evsel && evsel->evlist->session && evsel->evlist->session)
> + ret = evsel->evlist->session->header.env.cln_size;
I think on these 2 lines, prefer evsel__session(evsel) rather than the
direct access.
Thanks,
Ian
> + }
> +
> + if (!ret || ret < 1) {
> + int default_cacheline_size = 64; // avoid div/0 later
> +
> + ret = default_cacheline_size;
> + }
> +
> + return ret;
> +}
>
> static int64_t
> sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
> @@ -2482,11 +2502,9 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
> struct annotated_data_type *left_type = left->mem_type;
> struct annotated_data_type *right_type = right->mem_type;
> int64_t left_cln, right_cln;
> + int64_t cln_size_left = hist_entry__cln_size(left);
> + int64_t cln_size_right = hist_entry__cln_size(right);
> int64_t ret;
> - int cln_size = cacheline_size();
> -
> - if (cln_size == 0)
> - cln_size = DEFAULT_CACHELINE_SIZE;
>
> if (!left_type) {
> sort__type_init(left);
> @@ -2502,8 +2520,8 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right)
> if (ret)
> return ret;
>
> - left_cln = left->mem_type_off / cln_size;
> - right_cln = right->mem_type_off / cln_size;
> + left_cln = left->mem_type_off / cln_size_left;
> + right_cln = right->mem_type_off / cln_size_right;
> return left_cln - right_cln;
> }
>
> @@ -2511,10 +2529,7 @@ static int hist_entry__typecln_snprintf(struct hist_entry *he, char *bf,
> size_t size, unsigned int width __maybe_unused)
> {
> struct annotated_data_type *he_type = he->mem_type;
> - int cln_size = cacheline_size();
> -
> - if (cln_size == 0)
> - cln_size = DEFAULT_CACHELINE_SIZE;
> + int cln_size = hist_entry__cln_size(he);
>
> return repsep_snprintf(bf, size, "%s: cache-line %d", he_type->self.type_name,
> he->mem_type_off / cln_size);
> --
> 2.53.0
>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v4] perf utilities: cln_size header
2026-03-09 15:28 ` Ian Rogers
@ 2026-03-21 20:41 ` Ricky Ringler
2026-03-26 22:43 ` Namhyung Kim
0 siblings, 1 reply; 8+ messages in thread
From: Ricky Ringler @ 2026-03-21 20:41 UTC (permalink / raw)
To: irogers
Cc: namhyung, mingo, acme, linux-kernel, linux-perf-users,
Ricky Ringler
Store cacheline size during perf record in header, so
that cacheline size can be used for other features, like
sort.
V4: Ian feedback
V3: Rebase off perf-tools-next round two
V2: Rebase off perf-tools-next
Follow-up patch from message ID "aYZiQk6Uftzlb_JV@x1"
Testing:
- Built perf
- Ran record + report with feat enabled
- Ran record + report with feat disabled
Tested-by: Ricky Ringler <ricky.ringler@proton.me>
Signed-off-by: Ricky Ringler <ricky.ringler@proton.me>
---
tools/perf/builtin-inject.c | 2 +-
| 11 ++++++++---
tools/perf/util/sort.c | 8 ++++++--
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 2675d32f88cf..11ac7c8c4be3 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -2134,7 +2134,7 @@ static bool keep_feat(struct perf_inject *inject, int feat)
case HEADER_HYBRID_TOPOLOGY:
case HEADER_PMU_CAPS:
case HEADER_CPU_DOMAIN_INFO:
- case HEADER_CLNq_SIZE:
+ case HEADER_CLN_SIZE:
return true;
/* Information that can be updated */
case HEADER_BUILD_ID:
--git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 4f65faafe75d..2d39da470267 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1310,8 +1310,13 @@ static int write_cln_size(struct feat_fd *ff,
{
int cln_size = cacheline_size();
- if (!cln_size)
- cln_size = 0;
+
+ if (!cln_size) {
+ int default_cacheline_size = 64;
+
+ cln_size = default_cacheline_size;
+ }
+
ff->ph->env.cln_size = cln_size;
return do_write(ff, &cln_size, sizeof(cln_size));
@@ -2274,7 +2279,7 @@ static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused)
}
}
-static void print_cln_size(struct feat_fd *ff, FILE *fp __maybe_unused)
+static void print_cln_size(struct feat_fd *ff, FILE *fp)
{
fprintf(fp, "# cacheline size: %u\n", ff->ph->env.cln_size);
}
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 13287ade784e..5f617cf03d5d 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -2483,8 +2483,12 @@ hist_entry__cln_size(struct hist_entry *he)
if (he && he->hists) {
struct evsel *evsel = hists_to_evsel(he->hists);
- if (evsel && evsel->evlist->session && evsel->evlist->session)
- ret = evsel->evlist->session->header.env.cln_size;
+
+ if (evsel) {
+ struct perf_session *session = evsel__session(evsel);
+
+ ret = session->header.env.cln_size;
+ }
}
if (!ret || ret < 1) {
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v4] perf utilities: cln_size header
2026-03-21 20:41 ` [PATCH v4] " Ricky Ringler
@ 2026-03-26 22:43 ` Namhyung Kim
0 siblings, 0 replies; 8+ messages in thread
From: Namhyung Kim @ 2026-03-26 22:43 UTC (permalink / raw)
To: Ricky Ringler; +Cc: irogers, mingo, acme, linux-kernel, linux-perf-users
Hello,
On Sat, Mar 21, 2026 at 08:41:55PM +0000, Ricky Ringler wrote:
> Store cacheline size during perf record in header, so
> that cacheline size can be used for other features, like
> sort.
>
> V4: Ian feedback
> V3: Rebase off perf-tools-next round two
> V2: Rebase off perf-tools-next
>
> Follow-up patch from message ID "aYZiQk6Uftzlb_JV@x1"
Please squash the patches into a single change and send it again.
>
> Testing:
> - Built perf
> - Ran record + report with feat enabled
> - Ran record + report with feat disabled
>
> Tested-by: Ricky Ringler <ricky.ringler@proton.me>
Tested-by tag from the author may not be meaningful. We always expect
authors to test their patches. :)
> Signed-off-by: Ricky Ringler <ricky.ringler@proton.me>
> ---
> tools/perf/builtin-inject.c | 2 +-
> tools/perf/util/header.c | 11 ++++++++---
> tools/perf/util/sort.c | 8 ++++++--
> 3 files changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
> index 2675d32f88cf..11ac7c8c4be3 100644
> --- a/tools/perf/builtin-inject.c
> +++ b/tools/perf/builtin-inject.c
> @@ -2134,7 +2134,7 @@ static bool keep_feat(struct perf_inject *inject, int feat)
> case HEADER_HYBRID_TOPOLOGY:
> case HEADER_PMU_CAPS:
> case HEADER_CPU_DOMAIN_INFO:
> - case HEADER_CLNq_SIZE:
> + case HEADER_CLN_SIZE:
> return true;
> /* Information that can be updated */
> case HEADER_BUILD_ID:
> diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
> index 4f65faafe75d..2d39da470267 100644
> --- a/tools/perf/util/header.c
> +++ b/tools/perf/util/header.c
> @@ -1310,8 +1310,13 @@ static int write_cln_size(struct feat_fd *ff,
> {
> int cln_size = cacheline_size();
>
> - if (!cln_size)
> - cln_size = 0;
> +
> + if (!cln_size) {
> + int default_cacheline_size = 64;
Let's get rid of the local variable.
Thanks,
Namhyung
> +
> + cln_size = default_cacheline_size;
> + }
> +
> ff->ph->env.cln_size = cln_size;
>
> return do_write(ff, &cln_size, sizeof(cln_size));
> @@ -2274,7 +2279,7 @@ static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused)
> }
> }
>
> -static void print_cln_size(struct feat_fd *ff, FILE *fp __maybe_unused)
> +static void print_cln_size(struct feat_fd *ff, FILE *fp)
> {
> fprintf(fp, "# cacheline size: %u\n", ff->ph->env.cln_size);
> }
> diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
> index 13287ade784e..5f617cf03d5d 100644
> --- a/tools/perf/util/sort.c
> +++ b/tools/perf/util/sort.c
> @@ -2483,8 +2483,12 @@ hist_entry__cln_size(struct hist_entry *he)
> if (he && he->hists) {
> struct evsel *evsel = hists_to_evsel(he->hists);
>
> - if (evsel && evsel->evlist->session && evsel->evlist->session)
> - ret = evsel->evlist->session->header.env.cln_size;
> +
> + if (evsel) {
> + struct perf_session *session = evsel__session(evsel);
> +
> + ret = session->header.env.cln_size;
> + }
> }
>
> if (!ret || ret < 1) {
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-03-26 22:43 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-14 4:07 [PATCH] perf utilities: cln_size header Ricky Ringler
2026-03-04 1:25 ` Namhyung Kim
2026-03-05 23:57 ` [PATCH v2] " Ricky Ringler
2026-03-06 0:12 ` Ricky Ringler
2026-03-08 17:20 ` [PATCH v3] " Ricky Ringler
2026-03-09 15:28 ` Ian Rogers
2026-03-21 20:41 ` [PATCH v4] " Ricky Ringler
2026-03-26 22:43 ` Namhyung Kim
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox