tools/perf/util/bpf_off_cpu.c

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

File Facts

System
Linux kernel
Corpus path
tools/perf/util/bpf_off_cpu.c
Extension
.c
Size
10193 bytes
Lines
429
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

struct off_cpu_key {
	u32 pid;
	u32 tgid;
	u32 stack_id;
	u32 state;
	u64 cgroup_id;
};

union off_cpu_data {
	struct perf_event_header hdr;
	u64 array[1024 / sizeof(u64)];
};

static u64 off_cpu_raw[MAX_STACKS + 5];

static int off_cpu_config(struct evlist *evlist)
{
	char off_cpu_event[64];
	struct evsel *evsel;

	scnprintf(off_cpu_event, sizeof(off_cpu_event), "bpf-output/name=%s/", OFFCPU_EVENT);
	if (parse_event(evlist, off_cpu_event)) {
		pr_err("Failed to open off-cpu event\n");
		return -1;
	}

	evlist__for_each_entry(evlist, evsel) {
		if (evsel__is_offcpu_event(evsel)) {
			evsel->core.system_wide = true;
			break;
		}
	}

	return 0;
}

static void off_cpu_start(void *arg)
{
	struct evlist *evlist = arg;
	struct evsel *evsel;
	struct perf_cpu pcpu;
	unsigned int i;

	/* update task filter for the given workload */
	if (skel->rodata->has_task && skel->rodata->uses_tgid &&
	    perf_thread_map__pid(evlist->core.threads, 0) != -1) {
		int fd;
		u32 pid;
		u8 val = 1;

		fd = bpf_map__fd(skel->maps.task_filter);
		pid = perf_thread_map__pid(evlist->core.threads, 0);
		bpf_map_update_elem(fd, &pid, &val, BPF_ANY);
	}

	/* update BPF perf_event map */
	evsel = evlist__find_evsel_by_str(evlist, OFFCPU_EVENT);
	if (evsel == NULL) {
		pr_err("%s evsel not found\n", OFFCPU_EVENT);
		return;
	}

	perf_cpu_map__for_each_cpu(pcpu, i, evsel->core.cpus) {
		int err;
		int cpu_nr = pcpu.cpu;

		err = bpf_map__update_elem(skel->maps.offcpu_output, &cpu_nr, sizeof(int),
					   xyarray__entry(evsel->core.fd, cpu_nr, 0),
					   sizeof(int), BPF_ANY);
		if (err) {
			pr_err("Failed to update perf event map for direct off-cpu dumping\n");
			return;
		}
	}

	skel->bss->enabled = 1;
}

static void off_cpu_finish(void *arg __maybe_unused)
{
	skel->bss->enabled = 0;
	off_cpu_bpf__destroy(skel);
}

/* v5.18 kernel added prev_state arg, so it needs to check the signature */
static void check_sched_switch_args(void)
{
	struct btf *btf = btf__load_vmlinux_btf();
	const struct btf_type *t1, *t2, *t3;
	u32 type_id;

Annotation

Implementation Notes