tools/tracing/rtla/src/timerlat_bpf.c

Source file repositories/reference/linux-study-clean/tools/tracing/rtla/src/timerlat_bpf.c

File Facts

System
Linux kernel
Corpus path
tools/tracing/rtla/src/timerlat_bpf.c
Extension
.c
Size
5789 bytes
Lines
244
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

// SPDX-License-Identifier: GPL-2.0
#ifdef HAVE_BPF_SKEL
#define _GNU_SOURCE
#include "timerlat.h"
#include "timerlat_bpf.h"
#include "timerlat.skel.h"

static struct timerlat_bpf *bpf;

/* BPF object and program for action program */
static struct bpf_object *obj;
static struct bpf_program *prog;

/*
 * timerlat_bpf_init - load and initialize BPF program to collect timerlat data
 */
int timerlat_bpf_init(struct timerlat_params *params)
{
	int err;

	debug_msg("Loading BPF program\n");

	bpf = timerlat_bpf__open();
	if (!bpf)
		return 1;

	/* Pass common options */
	bpf->rodata->output_divisor = params->common.output_divisor;
	bpf->rodata->entries = params->common.hist.entries;
	bpf->rodata->irq_threshold = params->common.stop_us;
	bpf->rodata->thread_threshold = params->common.stop_total_us;
	bpf->rodata->aa_only = params->common.aa_only;

	if (params->common.hist.entries != 0) {
		/* Pass histogram options */
		bpf->rodata->bucket_size = params->common.hist.bucket_size;

		/* Set histogram array sizes */
		bpf_map__set_max_entries(bpf->maps.hist_irq, params->common.hist.entries);
		bpf_map__set_max_entries(bpf->maps.hist_thread, params->common.hist.entries);
		bpf_map__set_max_entries(bpf->maps.hist_user, params->common.hist.entries);
	} else {
		/* No entries, disable histogram */
		bpf_map__set_autocreate(bpf->maps.hist_irq, false);
		bpf_map__set_autocreate(bpf->maps.hist_thread, false);
		bpf_map__set_autocreate(bpf->maps.hist_user, false);
	}

	if (params->common.aa_only) {
		/* Auto-analysis only, disable summary */
		bpf_map__set_autocreate(bpf->maps.summary_irq, false);
		bpf_map__set_autocreate(bpf->maps.summary_thread, false);
		bpf_map__set_autocreate(bpf->maps.summary_user, false);
	}

	/* Load and verify BPF program */
	err = timerlat_bpf__load(bpf);
	if (err) {
		timerlat_bpf__destroy(bpf);
		return err;
	}

	return 0;
}

/*
 * timerlat_bpf_set_action - set action on threshold executed on BPF side
 */
static int timerlat_bpf_set_action(struct bpf_program *prog)
{
	unsigned int key = 0, value = bpf_program__fd(prog);

	return bpf_map__update_elem(bpf->maps.bpf_action,
				    &key, sizeof(key),
				    &value, sizeof(value),
				    BPF_ANY);
}

/*
 * timerlat_bpf_attach - attach BPF program to collect timerlat data
 */
int timerlat_bpf_attach(void)
{
	debug_msg("Attaching BPF program\n");

	return timerlat_bpf__attach(bpf);
}

/*
 * timerlat_bpf_detach - detach BPF program to collect timerlat data

Annotation

Implementation Notes