[PATCH v7 2/4] perf env: Add helper to lazily compute the os_release

Ian Rogers
2026-05-01T18:20:31Z

In live mode the os_release isn't being initialized, make a lazy
initialization helper that assumes when the os_release isn't
initialized this is live mode.

Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/util/data-convert-bt.c | 2 +-
tools/perf/util/env.c | 21 +++++++++++++++++++++
tools/perf/util/env.h | 1 +
tools/perf/util/header.c | 16 +++++++++++-----
tools/perf/util/symbol.c | 4 ++--
5 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index 3b8f2df823a9..2c88420fe33e 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -1414,7 +1414,7 @@ do { \

ADD("host", env->hostname);
ADD("sysname", "Linux");
- ADD("release", env->os_release);
+ ADD("release", perf_env__os_release(env));
ADD("version", env->version);
ADD("machine", env->arch);
ADD("domain", "kernel");
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index 1671769d4441..c3e464c6de2f 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -330,6 +330,27 @@ int perf_env__kernel_is_64_bit(struct perf_env *env)
return env->kernel_is_64_bit;
}

+const char *perf_env__os_release(struct perf_env *env)
+{
+ struct utsname uts;
+ int ret;
+
+ if (!env)
+ return perf_version_string;
+
+ if (env->os_release)
+ return env->os_release;
+
+ /*
+ * The os_release is being accessed but wasn't initialized from a data
+ * file, assume this is 'live' mode and use the release from uname. If
+ * uname or strdup fails then use the current perf tool version.
+ */
+ ret = uname(&uts);
+ env->os_release = strdup(ret < 0 ? perf_version_string : uts.release);
+ return env->os_release ?: perf_version_string;
+}
+
int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[])
{
int i;
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index d36a0fb2cd04..56020f4381cd 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -175,6 +175,7 @@ void free_cpu_domain_info(struct cpu_domain_map **cd_map, u32 schedstat_version,
void perf_env__exit(struct perf_env *env);

int perf_env__kernel_is_64_bit(struct perf_env *env);
+const char *perf_env__os_release(struct perf_env *env);

int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[]);

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 8d5152bde25d..cfafed3cc69f 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -370,13 +370,19 @@ static int write_osrelease(struct feat_fd *ff,
struct evlist *evlist __maybe_unused)
{
struct utsname uts;
- int ret;
+ const char *release = NULL;

- ret = uname(&uts);
- if (ret < 0)
- return -1;
+ if (evlist->session)
+ release = perf_env__os_release(perf_session__env(evlist->session));

- return do_write_string(ff, uts.release);
+ if (!release) {
+ int ret = uname(&uts);
+
+ if (ret < 0)
+ return -1;
+ release = uts.release;
+ }
+ return do_write_string(ff, release);
}

static int write_arch(struct feat_fd *ff, struct evlist *evlist)
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index fcaeeddbbb6b..fd332db56157 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2209,7 +2209,7 @@ static int vmlinux_path__init(struct perf_env *env)
{
struct utsname uts;
char bf[PATH_MAX];
- char *kernel_version;
+ const char *kernel_version;
unsigned int i;

vmlinux_path = malloc(sizeof(char *) * (ARRAY_SIZE(vmlinux_paths) +
@@ -2226,7 +2226,7 @@ static int vmlinux_path__init(struct perf_env *env)
return 0;

if (env) {
- kernel_version = env->os_release;
+ kernel_version = perf_env__os_release(env);
} else {
if (uname(&uts) < 0)
goto out_fail;
--
2.54.0.545.g6539524ca2-goog