tools/perf/util/cputopo.c

Source file repositories/reference/linux-study-clean/tools/perf/util/cputopo.c

File Facts

System
Linux kernel
Corpus path
tools/perf/util/cputopo.c
Extension
.c
Size
9880 bytes
Lines
507
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

perf_cpu_map__for_each_cpu(cpu, idx, core_cpus) {
			if (first) {
				has_first = perf_cpu_map__has(user_requested_cpus, cpu);
				first = false;
			} else {
				/*
				 * If the first core CPU is user requested then
				 * all subsequent CPUs in the core must be user
				 * requested too. If the first CPU isn't user
				 * requested then none of the others must be
				 * too.
				 */
				if (perf_cpu_map__has(user_requested_cpus, cpu) != has_first) {
					perf_cpu_map__put(core_cpus);
					perf_cpu_map__put(user_requested_cpus);
					return false;
				}
			}
		}
		perf_cpu_map__put(core_cpus);
	}
	perf_cpu_map__put(user_requested_cpus);
	return true;
}

static bool has_die_topology(void)
{
	char filename[MAXPATHLEN];
	struct utsname uts;

	if (uname(&uts) < 0)
		return false;

	if (strncmp(uts.machine, "x86_64", 6) &&
	    strncmp(uts.machine, "s390x", 5))
		return false;

	scnprintf(filename, MAXPATHLEN, DIE_CPUS_FMT,
		  sysfs__mountpoint(), 0);
	if (access(filename, F_OK) == -1)
		return false;

	return true;
}

const struct cpu_topology *online_topology(void)
{
	static const struct cpu_topology *topology;

	if (!topology) {
		topology = cpu_topology__new();
		if (!topology) {
			pr_err("Error creating CPU topology");
			abort();
		}
	}
	return topology;
}

struct cpu_topology *cpu_topology__new(void)
{
	struct cpu_topology *tp = NULL;
	void *addr;
	u32 nr, i, nr_addr;
	size_t sz;
	long ncpus;
	int ret = -1;
	struct perf_cpu_map *map;
	bool has_die = has_die_topology();

	ncpus = cpu__max_present_cpu().cpu;

	/* build online CPU map */
	map = perf_cpu_map__new_online_cpus();
	if (map == NULL) {
		pr_debug("failed to get system cpumap\n");
		return NULL;
	}

	nr = (u32)(ncpus & UINT_MAX);

	sz = nr * sizeof(char *);
	if (has_die)
		nr_addr = 3;
	else
		nr_addr = 2;
	addr = calloc(1, sizeof(*tp) + nr_addr * sz);
	if (!addr)
		goto out_free;

Annotation

Implementation Notes