tools/perf/util/bpf_kwork.c

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

File Facts

System
Linux kernel
Corpus path
tools/perf/util/bpf_kwork.c
Extension
.c
Size
8257 bytes
Lines
354
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 work_key {
	u32 type;
	u32 cpu;
	u64 id;
};

struct report_data {
	u64 nr;
	u64 total_time;
	u64 max_time;
	u64 max_time_start;
	u64 max_time_end;
};

struct kwork_class_bpf {
	struct kwork_class *class;

	void (*load_prepare)(struct perf_kwork *kwork);
	int  (*get_work_name)(struct work_key *key, char **ret_name);
};

static struct kwork_trace_bpf *skel;

static struct timespec ts_start;
static struct timespec ts_end;

void perf_kwork__trace_start(void)
{
	clock_gettime(CLOCK_MONOTONIC, &ts_start);
	skel->bss->enabled = 1;
}

void perf_kwork__trace_finish(void)
{
	clock_gettime(CLOCK_MONOTONIC, &ts_end);
	skel->bss->enabled = 0;
}

static int get_work_name_from_map(struct work_key *key, char **ret_name)
{
	char name[MAX_KWORKNAME] = { 0 };
	int fd = bpf_map__fd(skel->maps.perf_kwork_names);

	*ret_name = NULL;

	if (fd < 0) {
		pr_debug("Invalid names map fd\n");
		return 0;
	}

	if ((bpf_map_lookup_elem(fd, key, name) == 0) && (strlen(name) != 0)) {
		*ret_name = strdup(name);
		if (*ret_name == NULL) {
			pr_err("Failed to copy work name\n");
			return -1;
		}
	}

	return 0;
}

static void irq_load_prepare(struct perf_kwork *kwork)
{
	if (kwork->report == KWORK_REPORT_RUNTIME) {
		bpf_program__set_autoload(skel->progs.report_irq_handler_entry, true);
		bpf_program__set_autoload(skel->progs.report_irq_handler_exit, true);
	}
}

static struct kwork_class_bpf kwork_irq_bpf = {
	.load_prepare  = irq_load_prepare,
	.get_work_name = get_work_name_from_map,
};

static void softirq_load_prepare(struct perf_kwork *kwork)
{
	if (kwork->report == KWORK_REPORT_RUNTIME) {
		bpf_program__set_autoload(skel->progs.report_softirq_entry, true);
		bpf_program__set_autoload(skel->progs.report_softirq_exit, true);
	} else if (kwork->report == KWORK_REPORT_LATENCY) {
		bpf_program__set_autoload(skel->progs.latency_softirq_raise, true);
		bpf_program__set_autoload(skel->progs.latency_softirq_entry, true);
	}
}

static struct kwork_class_bpf kwork_softirq_bpf = {
	.load_prepare  = softirq_load_prepare,
	.get_work_name = get_work_name_from_map,
};

Annotation

Implementation Notes