tools/bpf/bpftool/map_perf_ring.c

Source file repositories/reference/linux-study-clean/tools/bpf/bpftool/map_perf_ring.c

File Facts

System
Linux kernel
Corpus path
tools/bpf/bpftool/map_perf_ring.c
Extension
.c
Size
5103 bytes
Lines
228
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 perf_event_sample {
	struct perf_event_header header;
	__u64 time;
	__u32 size;
	unsigned char data[];
};

struct perf_event_lost {
	struct perf_event_header header;
	__u64 id;
	__u64 lost;
};

static void int_exit(int signo)
{
	fprintf(stderr, "Stopping...\n");
	stop = true;
}

struct event_pipe_ctx {
	bool all_cpus;
	int cpu;
	int idx;
};

static enum bpf_perf_event_ret
print_bpf_output(void *private_data, int cpu, struct perf_event_header *event)
{
	struct perf_event_sample *e = container_of(event,
						   struct perf_event_sample,
						   header);
	struct perf_event_lost *lost = container_of(event,
						    struct perf_event_lost,
						    header);
	struct event_pipe_ctx *ctx = private_data;
	int idx = ctx->all_cpus ? cpu : ctx->idx;

	if (json_output) {
		jsonw_start_object(json_wtr);
		jsonw_name(json_wtr, "type");
		jsonw_uint(json_wtr, e->header.type);
		jsonw_name(json_wtr, "cpu");
		jsonw_uint(json_wtr, cpu);
		jsonw_name(json_wtr, "index");
		jsonw_uint(json_wtr, idx);
		if (e->header.type == PERF_RECORD_SAMPLE) {
			jsonw_name(json_wtr, "timestamp");
			jsonw_uint(json_wtr, e->time);
			jsonw_name(json_wtr, "data");
			print_data_json(e->data, e->size);
		} else if (e->header.type == PERF_RECORD_LOST) {
			jsonw_name(json_wtr, "lost");
			jsonw_start_object(json_wtr);
			jsonw_name(json_wtr, "id");
			jsonw_uint(json_wtr, lost->id);
			jsonw_name(json_wtr, "count");
			jsonw_uint(json_wtr, lost->lost);
			jsonw_end_object(json_wtr);
		}
		jsonw_end_object(json_wtr);
	} else {
		if (e->header.type == PERF_RECORD_SAMPLE) {
			printf("== @%llu.%09llu CPU: %d index: %d =====\n",
			       e->time / 1000000000ULL, e->time % 1000000000ULL,
			       cpu, idx);
			fprint_hex(stdout, e->data, e->size, " ");
			printf("\n");
		} else if (e->header.type == PERF_RECORD_LOST) {
			printf("lost %llu events\n", lost->lost);
		} else {
			printf("unknown event type=%u size=%u\n",
			       e->header.type, e->header.size);
		}
	}

	return LIBBPF_PERF_EVENT_CONT;
}

int do_event_pipe(int argc, char **argv)
{
	struct perf_event_attr perf_attr = {
		.sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_TIME,
		.type = PERF_TYPE_SOFTWARE,
		.config = PERF_COUNT_SW_BPF_OUTPUT,
		.sample_period = 1,
		.wakeup_events = 1,
	};
	struct bpf_map_info map_info = {};
	LIBBPF_OPTS(perf_buffer_raw_opts, opts);
	struct event_pipe_ctx ctx = {

Annotation

Implementation Notes