Commit b743a136 authored by Ian Rogers's avatar Ian Rogers Committed by Namhyung Kim
Browse files

perf header: Clean up use of perf_env



Always use the perf_env from the feat_fd's perf_header. Cache the
value on entry to a function in `env` and use `env->` consistently in
the code. Ensure the header is initialized for use in
perf_session__do_write_header.

Signed-off-by: default avatarIan Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250724163302.596743-12-irogers@google.com


Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
parent 57ddb9cb
Loading
Loading
Loading
Loading
+98 −76
Original line number Diff line number Diff line
@@ -557,6 +557,7 @@ static int write_event_desc(struct feat_fd *ff,
static int write_cmdline(struct feat_fd *ff,
			 struct evlist *evlist __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	char pbuf[MAXPATHLEN], *buf;
	int i, ret, n;

@@ -564,7 +565,7 @@ static int write_cmdline(struct feat_fd *ff,
	buf = perf_exe(pbuf, MAXPATHLEN);

	/* account for binary path */
	n = perf_env.nr_cmdline + 1;
	n = env->nr_cmdline + 1;

	ret = do_write(ff, &n, sizeof(n));
	if (ret < 0)
@@ -574,8 +575,8 @@ static int write_cmdline(struct feat_fd *ff,
	if (ret < 0)
		return ret;

	for (i = 0 ; i < perf_env.nr_cmdline; i++) {
		ret = do_write_string(ff, perf_env.cmdline_argv[i]);
	for (i = 0 ; i < env->nr_cmdline; i++) {
		ret = do_write_string(ff, env->cmdline_argv[i]);
		if (ret < 0)
			return ret;
	}
@@ -586,6 +587,7 @@ static int write_cmdline(struct feat_fd *ff,
static int write_cpu_topology(struct feat_fd *ff,
			      struct evlist *evlist __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	struct cpu_topology *tp;
	u32 i;
	int ret, j;
@@ -613,17 +615,17 @@ static int write_cpu_topology(struct feat_fd *ff,
			break;
	}

	ret = perf_env__read_cpu_topology_map(&perf_env);
	ret = perf_env__read_cpu_topology_map(env);
	if (ret < 0)
		goto done;

	for (j = 0; j < perf_env.nr_cpus_avail; j++) {
		ret = do_write(ff, &perf_env.cpu[j].core_id,
			       sizeof(perf_env.cpu[j].core_id));
	for (j = 0; j < env->nr_cpus_avail; j++) {
		ret = do_write(ff, &env->cpu[j].core_id,
			       sizeof(env->cpu[j].core_id));
		if (ret < 0)
			return ret;
		ret = do_write(ff, &perf_env.cpu[j].socket_id,
			       sizeof(perf_env.cpu[j].socket_id));
		ret = do_write(ff, &env->cpu[j].socket_id,
			       sizeof(env->cpu[j].socket_id));
		if (ret < 0)
			return ret;
	}
@@ -641,9 +643,9 @@ static int write_cpu_topology(struct feat_fd *ff,
			goto done;
	}

	for (j = 0; j < perf_env.nr_cpus_avail; j++) {
		ret = do_write(ff, &perf_env.cpu[j].die_id,
			       sizeof(perf_env.cpu[j].die_id));
	for (j = 0; j < env->nr_cpus_avail; j++) {
		ret = do_write(ff, &env->cpu[j].die_id,
			       sizeof(env->cpu[j].die_id));
		if (ret < 0)
			return ret;
	}
@@ -2123,17 +2125,18 @@ static void print_cpu_pmu_caps(struct feat_fd *ff, FILE *fp)

static void print_pmu_caps(struct feat_fd *ff, FILE *fp)
{
	struct perf_env *env = &ff->ph->env;
	struct pmu_caps *pmu_caps;

	for (int i = 0; i < ff->ph->env.nr_pmus_with_caps; i++) {
		pmu_caps = &ff->ph->env.pmu_caps[i];
	for (int i = 0; i < env->nr_pmus_with_caps; i++) {
		pmu_caps = &env->pmu_caps[i];
		__print_pmu_caps(fp, pmu_caps->nr_caps, pmu_caps->caps,
				 pmu_caps->pmu_name);
	}

	if (strcmp(perf_env__arch(&ff->ph->env), "x86") == 0 &&
	    perf_env__has_pmu_mapping(&ff->ph->env, "ibs_op")) {
		char *max_precise = perf_env__find_pmu_cap(&ff->ph->env, "cpu", "max_precise");
	if (strcmp(perf_env__arch(env), "x86") == 0 &&
	    perf_env__has_pmu_mapping(env, "ibs_op")) {
		char *max_precise = perf_env__find_pmu_cap(env, "cpu", "max_precise");

		if (max_precise != NULL && atoi(max_precise) == 0)
			fprintf(fp, "# AMD systems uses ibs_op// PMU for some precise events, e.g.: cycles:p, see the 'perf list' man page for further details.\n");
@@ -2142,18 +2145,19 @@ static void print_pmu_caps(struct feat_fd *ff, FILE *fp)

static void print_pmu_mappings(struct feat_fd *ff, FILE *fp)
{
	struct perf_env *env = &ff->ph->env;
	const char *delimiter = "# pmu mappings: ";
	char *str, *tmp;
	u32 pmu_num;
	u32 type;

	pmu_num = ff->ph->env.nr_pmu_mappings;
	pmu_num = env->nr_pmu_mappings;
	if (!pmu_num) {
		fprintf(fp, "# pmu mappings: not available\n");
		return;
	}

	str = ff->ph->env.pmu_mappings;
	str = env->pmu_mappings;

	while (pmu_num) {
		type = strtoul(str, &tmp, 0);
@@ -2235,17 +2239,18 @@ static void memory_node__fprintf(struct memory_node *n,

static void print_mem_topology(struct feat_fd *ff, FILE *fp)
{
	struct perf_env *env = &ff->ph->env;
	struct memory_node *nodes;
	int i, nr;

	nodes = ff->ph->env.memory_nodes;
	nr    = ff->ph->env.nr_memory_nodes;
	nodes = env->memory_nodes;
	nr    = env->nr_memory_nodes;

	fprintf(fp, "# memory nodes (nr %d, block size 0x%llx):\n",
		nr, ff->ph->env.memory_bsize);
		nr, env->memory_bsize);

	for (i = 0; i < nr; i++) {
		memory_node__fprintf(&nodes[i], ff->ph->env.memory_bsize, fp);
		memory_node__fprintf(&nodes[i], env->memory_bsize, fp);
	}
}

@@ -2443,6 +2448,7 @@ static int process_build_id(struct feat_fd *ff, void *data __maybe_unused)

static int process_nrcpus(struct feat_fd *ff, void *data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	int ret;
	u32 nr_cpus_avail, nr_cpus_online;

@@ -2453,20 +2459,21 @@ static int process_nrcpus(struct feat_fd *ff, void *data __maybe_unused)
	ret = do_read_u32(ff, &nr_cpus_online);
	if (ret)
		return ret;
	ff->ph->env.nr_cpus_avail = (int)nr_cpus_avail;
	ff->ph->env.nr_cpus_online = (int)nr_cpus_online;
	env->nr_cpus_avail = (int)nr_cpus_avail;
	env->nr_cpus_online = (int)nr_cpus_online;
	return 0;
}

static int process_total_mem(struct feat_fd *ff, void *data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	u64 total_mem;
	int ret;

	ret = do_read_u64(ff, &total_mem);
	if (ret)
		return -1;
	ff->ph->env.total_mem = (unsigned long long)total_mem;
	env->total_mem = (unsigned long long)total_mem;
	return 0;
}

@@ -2527,13 +2534,14 @@ process_event_desc(struct feat_fd *ff, void *data __maybe_unused)

static int process_cmdline(struct feat_fd *ff, void *data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	char *str, *cmdline = NULL, **argv = NULL;
	u32 nr, i, len = 0;

	if (do_read_u32(ff, &nr))
		return -1;

	ff->ph->env.nr_cmdline = nr;
	env->nr_cmdline = nr;

	cmdline = zalloc(ff->size + nr + 1);
	if (!cmdline)
@@ -2553,8 +2561,8 @@ static int process_cmdline(struct feat_fd *ff, void *data __maybe_unused)
		len += strlen(str) + 1;
		free(str);
	}
	ff->ph->env.cmdline = cmdline;
	ff->ph->env.cmdline_argv = (const char **) argv;
	env->cmdline = cmdline;
	env->cmdline_argv = (const char **) argv;
	return 0;

error:
@@ -2568,18 +2576,18 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
	u32 nr, i;
	char *str = NULL;
	struct strbuf sb;
	int cpu_nr = ff->ph->env.nr_cpus_avail;
	struct perf_env *env = &ff->ph->env;
	int cpu_nr = env->nr_cpus_avail;
	u64 size = 0;
	struct perf_header *ph = ff->ph;

	ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu));
	if (!ph->env.cpu)
	env->cpu = calloc(cpu_nr, sizeof(*env->cpu));
	if (!env->cpu)
		return -1;

	if (do_read_u32(ff, &nr))
		goto free_cpu;

	ph->env.nr_sibling_cores = nr;
	env->nr_sibling_cores = nr;
	size += sizeof(u32);
	if (strbuf_init(&sb, 128) < 0)
		goto free_cpu;
@@ -2595,12 +2603,12 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
		size += string_size(str);
		zfree(&str);
	}
	ph->env.sibling_cores = strbuf_detach(&sb, NULL);
	env->sibling_cores = strbuf_detach(&sb, NULL);

	if (do_read_u32(ff, &nr))
		return -1;

	ph->env.nr_sibling_threads = nr;
	env->nr_sibling_threads = nr;
	size += sizeof(u32);

	for (i = 0; i < nr; i++) {
@@ -2614,14 +2622,14 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
		size += string_size(str);
		zfree(&str);
	}
	ph->env.sibling_threads = strbuf_detach(&sb, NULL);
	env->sibling_threads = strbuf_detach(&sb, NULL);

	/*
	 * The header may be from old perf,
	 * which doesn't include core id and socket id information.
	 */
	if (ff->size <= size) {
		zfree(&ph->env.cpu);
		zfree(&env->cpu);
		return 0;
	}

@@ -2629,13 +2637,13 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
		if (do_read_u32(ff, &nr))
			goto free_cpu;

		ph->env.cpu[i].core_id = nr;
		env->cpu[i].core_id = nr;
		size += sizeof(u32);

		if (do_read_u32(ff, &nr))
			goto free_cpu;

		ph->env.cpu[i].socket_id = nr;
		env->cpu[i].socket_id = nr;
		size += sizeof(u32);
	}

@@ -2649,7 +2657,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
	if (do_read_u32(ff, &nr))
		return -1;

	ph->env.nr_sibling_dies = nr;
	env->nr_sibling_dies = nr;
	size += sizeof(u32);

	for (i = 0; i < nr; i++) {
@@ -2663,13 +2671,13 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
		size += string_size(str);
		zfree(&str);
	}
	ph->env.sibling_dies = strbuf_detach(&sb, NULL);
	env->sibling_dies = strbuf_detach(&sb, NULL);

	for (i = 0; i < (u32)cpu_nr; i++) {
		if (do_read_u32(ff, &nr))
			goto free_cpu;

		ph->env.cpu[i].die_id = nr;
		env->cpu[i].die_id = nr;
	}

	return 0;
@@ -2678,12 +2686,13 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
	strbuf_release(&sb);
	zfree(&str);
free_cpu:
	zfree(&ph->env.cpu);
	zfree(&env->cpu);
	return -1;
}

static int process_numa_topology(struct feat_fd *ff, void *data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	struct numa_node *nodes, *n;
	u32 nr, i;
	char *str;
@@ -2718,8 +2727,8 @@ static int process_numa_topology(struct feat_fd *ff, void *data __maybe_unused)
		if (!n->map)
			goto error;
	}
	ff->ph->env.nr_numa_nodes = nr;
	ff->ph->env.numa_nodes = nodes;
	env->nr_numa_nodes = nr;
	env->numa_nodes = nodes;
	return 0;

error:
@@ -2729,6 +2738,7 @@ static int process_numa_topology(struct feat_fd *ff, void *data __maybe_unused)

static int process_pmu_mappings(struct feat_fd *ff, void *data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	char *name;
	u32 pmu_num;
	u32 type;
@@ -2742,7 +2752,7 @@ static int process_pmu_mappings(struct feat_fd *ff, void *data __maybe_unused)
		return 0;
	}

	ff->ph->env.nr_pmu_mappings = pmu_num;
	env->nr_pmu_mappings = pmu_num;
	if (strbuf_init(&sb, 128) < 0)
		return -1;

@@ -2761,14 +2771,14 @@ static int process_pmu_mappings(struct feat_fd *ff, void *data __maybe_unused)
			goto error;

		if (!strcmp(name, "msr"))
			ff->ph->env.msr_pmu_type = type;
			env->msr_pmu_type = type;

		free(name);
		pmu_num--;
	}
	/* AMD may set it by evlist__has_amd_ibs() from perf_session__new() */
	free(ff->ph->env.pmu_mappings);
	ff->ph->env.pmu_mappings = strbuf_detach(&sb, NULL);
	free(env->pmu_mappings);
	env->pmu_mappings = strbuf_detach(&sb, NULL);
	return 0;

error:
@@ -2778,6 +2788,7 @@ static int process_pmu_mappings(struct feat_fd *ff, void *data __maybe_unused)

static int process_group_desc(struct feat_fd *ff, void *data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	size_t ret = -1;
	u32 i, nr, nr_groups;
	struct perf_session *session;
@@ -2791,7 +2802,7 @@ static int process_group_desc(struct feat_fd *ff, void *data __maybe_unused)
	if (do_read_u32(ff, &nr_groups))
		return -1;

	ff->ph->env.nr_groups = nr_groups;
	env->nr_groups = nr_groups;
	if (!nr_groups) {
		pr_debug("group desc not available\n");
		return 0;
@@ -2875,6 +2886,7 @@ static int process_auxtrace(struct feat_fd *ff, void *data __maybe_unused)

static int process_cache(struct feat_fd *ff, void *data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	struct cpu_cache_level *caches;
	u32 cnt, i, version;

@@ -2915,8 +2927,8 @@ static int process_cache(struct feat_fd *ff, void *data __maybe_unused)
		#undef _R
	}

	ff->ph->env.caches = caches;
	ff->ph->env.caches_cnt = cnt;
	env->caches = caches;
	env->caches_cnt = cnt;
	return 0;
out_free_caches:
	for (i = 0; i < cnt; i++) {
@@ -2952,6 +2964,7 @@ static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
static int process_mem_topology(struct feat_fd *ff,
				void *data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	struct memory_node *nodes;
	u64 version, i, nr, bsize;
	int ret = -1;
@@ -2990,9 +3003,9 @@ static int process_mem_topology(struct feat_fd *ff,
		nodes[i] = n;
	}

	ff->ph->env.memory_bsize    = bsize;
	ff->ph->env.memory_nodes    = nodes;
	ff->ph->env.nr_memory_nodes = nr;
	env->memory_bsize    = bsize;
	env->memory_nodes    = nodes;
	env->nr_memory_nodes = nr;
	ret = 0;

out:
@@ -3004,7 +3017,9 @@ static int process_mem_topology(struct feat_fd *ff,
static int process_clockid(struct feat_fd *ff,
			   void *data __maybe_unused)
{
	if (do_read_u64(ff, &ff->ph->env.clock.clockid_res_ns))
	struct perf_env *env = &ff->ph->env;

	if (do_read_u64(ff, &env->clock.clockid_res_ns))
		return -1;

	return 0;
@@ -3013,6 +3028,7 @@ static int process_clockid(struct feat_fd *ff,
static int process_clock_data(struct feat_fd *ff,
			      void *_data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	u32 data32;
	u64 data64;

@@ -3027,26 +3043,27 @@ static int process_clock_data(struct feat_fd *ff,
	if (do_read_u32(ff, &data32))
		return -1;

	ff->ph->env.clock.clockid = data32;
	env->clock.clockid = data32;

	/* TOD ref time */
	if (do_read_u64(ff, &data64))
		return -1;

	ff->ph->env.clock.tod_ns = data64;
	env->clock.tod_ns = data64;

	/* clockid ref time */
	if (do_read_u64(ff, &data64))
		return -1;

	ff->ph->env.clock.clockid_ns = data64;
	ff->ph->env.clock.enabled = true;
	env->clock.clockid_ns = data64;
	env->clock.enabled = true;
	return 0;
}

static int process_hybrid_topology(struct feat_fd *ff,
				   void *data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	struct hybrid_node *nodes, *n;
	u32 nr, i;

@@ -3070,8 +3087,8 @@ static int process_hybrid_topology(struct feat_fd *ff,
			goto error;
	}

	ff->ph->env.nr_hybrid_nodes = nr;
	ff->ph->env.hybrid_nodes = nodes;
	env->nr_hybrid_nodes = nr;
	env->hybrid_nodes = nodes;
	return 0;

error:
@@ -3224,19 +3241,21 @@ static int process_bpf_btf(struct feat_fd *ff, void *data __maybe_unused)
static int process_compressed(struct feat_fd *ff,
			      void *data __maybe_unused)
{
	if (do_read_u32(ff, &(ff->ph->env.comp_ver)))
	struct perf_env *env = &ff->ph->env;

	if (do_read_u32(ff, &(env->comp_ver)))
		return -1;

	if (do_read_u32(ff, &(ff->ph->env.comp_type)))
	if (do_read_u32(ff, &(env->comp_type)))
		return -1;

	if (do_read_u32(ff, &(ff->ph->env.comp_level)))
	if (do_read_u32(ff, &(env->comp_level)))
		return -1;

	if (do_read_u32(ff, &(ff->ph->env.comp_ratio)))
	if (do_read_u32(ff, &(env->comp_ratio)))
		return -1;

	if (do_read_u32(ff, &(ff->ph->env.comp_mmap_len)))
	if (do_read_u32(ff, &(env->comp_mmap_len)))
		return -1;

	return 0;
@@ -3308,19 +3327,21 @@ static int __process_pmu_caps(struct feat_fd *ff, int *nr_caps,
static int process_cpu_pmu_caps(struct feat_fd *ff,
				void *data __maybe_unused)
{
	int ret = __process_pmu_caps(ff, &ff->ph->env.nr_cpu_pmu_caps,
				     &ff->ph->env.cpu_pmu_caps,
				     &ff->ph->env.max_branches,
				     &ff->ph->env.br_cntr_nr,
				     &ff->ph->env.br_cntr_width);
	struct perf_env *env = &ff->ph->env;
	int ret = __process_pmu_caps(ff, &env->nr_cpu_pmu_caps,
				     &env->cpu_pmu_caps,
				     &env->max_branches,
				     &env->br_cntr_nr,
				     &env->br_cntr_width);

	if (!ret && !ff->ph->env.cpu_pmu_caps)
	if (!ret && !env->cpu_pmu_caps)
		pr_debug("cpu pmu capabilities not available\n");
	return ret;
}

static int process_pmu_caps(struct feat_fd *ff, void *data __maybe_unused)
{
	struct perf_env *env = &ff->ph->env;
	struct pmu_caps *pmu_caps;
	u32 nr_pmu, i;
	int ret;
@@ -3358,8 +3379,8 @@ static int process_pmu_caps(struct feat_fd *ff, void *data __maybe_unused)
		}
	}

	ff->ph->env.nr_pmus_with_caps = nr_pmu;
	ff->ph->env.pmu_caps = pmu_caps;
	env->nr_pmus_with_caps = nr_pmu;
	env->pmu_caps = pmu_caps;
	return 0;

err:
@@ -3657,6 +3678,7 @@ static int perf_session__do_write_header(struct perf_session *session,
	struct perf_header *header = &session->header;
	struct evsel *evsel;
	struct feat_fd ff = {
		.ph = header,
		.fd = fd,
	};
	u64 attr_offset = sizeof(f_header), attr_size = 0;