tools/perf/util/bpf_skel/bperf_cgroup.bpf.c

Source file repositories/reference/linux-study-clean/tools/perf/util/bpf_skel/bperf_cgroup.bpf.c

File Facts

System
Linux kernel
Corpus path
tools/perf/util/bpf_skel/bperf_cgroup.bpf.c
Extension
.c
Size
5594 bytes
Lines
226
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 cgroup___new {
	int level;
	struct cgroup *ancestors[];
} __attribute__((preserve_access_index));

/* old kernel cgroup definition */
struct cgroup___old {
	int level;
	u64 ancestor_ids[];
} __attribute__((preserve_access_index));

const volatile __u32 num_events = 1;
const volatile __u32 num_cpus = 1;
const volatile int use_cgroup_v2 = 0;

int enabled = 0;
int perf_subsys_id = -1;

static inline __u64 get_cgroup_v1_ancestor_id(struct cgroup *cgrp, int level)
{
	/* recast pointer to capture new type for compiler */
	struct cgroup___new *cgrp_new = (void *)cgrp;

	if (bpf_core_field_exists(cgrp_new->ancestors)) {
		return BPF_CORE_READ(cgrp_new, ancestors[level], kn, id);
	} else {
		/* recast pointer to capture old type for compiler */
		struct cgroup___old *cgrp_old = (void *)cgrp;

		return BPF_CORE_READ(cgrp_old, ancestor_ids[level]);
	}
}

static inline int get_cgroup_v1_idx(__u32 *cgrps, int size)
{
	struct task_struct *p = (void *)bpf_get_current_task();
	struct cgroup *cgrp;
	register int i = 0;
	__u32 *elem;
	int level;
	int cnt;

	if (perf_subsys_id == -1) {
#if __has_builtin(__builtin_preserve_enum_value)
		perf_subsys_id = bpf_core_enum_value(enum cgroup_subsys_id,
						     perf_event_cgrp_id);
#else
		perf_subsys_id = perf_event_cgrp_id;
#endif
	}
	cgrp = BPF_CORE_READ(p, cgroups, subsys[perf_subsys_id], cgroup);
	level = BPF_CORE_READ(cgrp, level);

	for (cnt = 0; i < BPERF_CGROUP__MAX_LEVELS; i++) {
		__u64 cgrp_id;

		if (i > level)
			break;

		// convert cgroup-id to a map index
		cgrp_id = get_cgroup_v1_ancestor_id(cgrp, i);
		elem = bpf_map_lookup_elem(&cgrp_idx, &cgrp_id);
		if (!elem)
			continue;

		cgrps[cnt++] = *elem;
		if (cnt == size)
			break;
	}

	return cnt;
}

static inline int get_cgroup_v2_idx(__u32 *cgrps, int size)
{
	register int i = 0;
	__u32 *elem;
	int cnt;

	for (cnt = 0; i < BPERF_CGROUP__MAX_LEVELS; i++) {
		__u64 cgrp_id = bpf_get_current_ancestor_cgroup_id(i);

		if (cgrp_id == 0)
			break;

		// convert cgroup-id to a map index
		elem = bpf_map_lookup_elem(&cgrp_idx, &cgrp_id);
		if (!elem)
			continue;

Annotation

Implementation Notes