File Index
Files and directories
Sign in
FILE

timerlat_bpf.c

File preview with syntax highlighting.

linux-6.19.14/tools/tracing/rtla/src/timerlat_bpf.c C
  1// SPDX-License-Identifier: GPL-2.0
  2#ifdef HAVE_BPF_SKEL
  3#define _GNU_SOURCE
  4#include "timerlat.h"
  5#include "timerlat_bpf.h"
  6#include "timerlat.skel.h"
  7
  8static struct timerlat_bpf *bpf;
  9
 10/*
 11 * timerlat_bpf_init - load and initialize BPF program to collect timerlat data
 12 */
 13int timerlat_bpf_init(struct timerlat_params *params)
 14{
 15	int err;
 16
 17	debug_msg("Loading BPF program\n");
 18
 19	bpf = timerlat_bpf__open();
 20	if (!bpf)
 21		return 1;
 22
 23	/* Pass common options */
 24	bpf->rodata->output_divisor = params->common.output_divisor;
 25	bpf->rodata->entries = params->common.hist.entries;
 26	bpf->rodata->irq_threshold = params->common.stop_us;
 27	bpf->rodata->thread_threshold = params->common.stop_total_us;
 28	bpf->rodata->aa_only = params->common.aa_only;
 29
 30	if (params->common.hist.entries != 0) {
 31		/* Pass histogram options */
 32		bpf->rodata->bucket_size = params->common.hist.bucket_size;
 33
 34		/* Set histogram array sizes */
 35		bpf_map__set_max_entries(bpf->maps.hist_irq, params->common.hist.entries);
 36		bpf_map__set_max_entries(bpf->maps.hist_thread, params->common.hist.entries);
 37		bpf_map__set_max_entries(bpf->maps.hist_user, params->common.hist.entries);
 38	} else {
 39		/* No entries, disable histogram */
 40		bpf_map__set_autocreate(bpf->maps.hist_irq, false);
 41		bpf_map__set_autocreate(bpf->maps.hist_thread, false);
 42		bpf_map__set_autocreate(bpf->maps.hist_user, false);
 43	}
 44
 45	if (params->common.aa_only) {
 46		/* Auto-analysis only, disable summary */
 47		bpf_map__set_autocreate(bpf->maps.summary_irq, false);
 48		bpf_map__set_autocreate(bpf->maps.summary_thread, false);
 49		bpf_map__set_autocreate(bpf->maps.summary_user, false);
 50	}
 51
 52	/* Load and verify BPF program */
 53	err = timerlat_bpf__load(bpf);
 54	if (err) {
 55		timerlat_bpf__destroy(bpf);
 56		return err;
 57	}
 58
 59	return 0;
 60}
 61
 62/*
 63 * timerlat_bpf_attach - attach BPF program to collect timerlat data
 64 */
 65int timerlat_bpf_attach(void)
 66{
 67	debug_msg("Attaching BPF program\n");
 68
 69	return timerlat_bpf__attach(bpf);
 70}
 71
 72/*
 73 * timerlat_bpf_detach - detach BPF program to collect timerlat data
 74 */
 75void timerlat_bpf_detach(void)
 76{
 77	timerlat_bpf__detach(bpf);
 78}
 79
 80/*
 81 * timerlat_bpf_detach - destroy BPF program to collect timerlat data
 82 */
 83void timerlat_bpf_destroy(void)
 84{
 85	timerlat_bpf__destroy(bpf);
 86}
 87
 88static int handle_rb_event(void *ctx, void *data, size_t data_sz)
 89{
 90	return 0;
 91}
 92
 93/*
 94 * timerlat_bpf_wait - wait until tracing is stopped or signal
 95 */
 96int timerlat_bpf_wait(int timeout)
 97{
 98	struct ring_buffer *rb;
 99	int retval;
100
101	rb = ring_buffer__new(bpf_map__fd(bpf->maps.signal_stop_tracing),
102			      handle_rb_event, NULL, NULL);
103	retval = ring_buffer__poll(rb, timeout * 1000);
104	ring_buffer__free(rb);
105
106	return retval;
107}
108
109/*
110 * timerlat_bpf_restart_tracing - restart stopped tracing
111 */
112int timerlat_bpf_restart_tracing(void)
113{
114	unsigned int key = 0;
115	unsigned long long value = 0;
116
117	return bpf_map__update_elem(bpf->maps.stop_tracing,
118				    &key, sizeof(key),
119				    &value, sizeof(value), BPF_ANY);
120}
121
122static int get_value(struct bpf_map *map_irq,
123		     struct bpf_map *map_thread,
124		     struct bpf_map *map_user,
125		     int key,
126		     long long *value_irq,
127		     long long *value_thread,
128		     long long *value_user,
129		     int cpus)
130{
131	int err;
132
133	err = bpf_map__lookup_elem(map_irq, &key,
134				   sizeof(unsigned int), value_irq,
135				   sizeof(long long) * cpus, 0);
136	if (err)
137		return err;
138	err = bpf_map__lookup_elem(map_thread, &key,
139				   sizeof(unsigned int), value_thread,
140				   sizeof(long long) * cpus, 0);
141	if (err)
142		return err;
143	err = bpf_map__lookup_elem(map_user, &key,
144				   sizeof(unsigned int), value_user,
145				   sizeof(long long) * cpus, 0);
146	if (err)
147		return err;
148	return 0;
149}
150
151/*
152 * timerlat_bpf_get_hist_value - get value from BPF hist map
153 */
154int timerlat_bpf_get_hist_value(int key,
155				long long *value_irq,
156				long long *value_thread,
157				long long *value_user,
158				int cpus)
159{
160	return get_value(bpf->maps.hist_irq,
161			 bpf->maps.hist_thread,
162			 bpf->maps.hist_user,
163			 key, value_irq, value_thread, value_user, cpus);
164}
165
166/*
167 * timerlat_bpf_get_summary_value - get value from BPF summary map
168 */
169int timerlat_bpf_get_summary_value(enum summary_field key,
170				   long long *value_irq,
171				   long long *value_thread,
172				   long long *value_user,
173				   int cpus)
174{
175	return get_value(bpf->maps.summary_irq,
176			 bpf->maps.summary_thread,
177			 bpf->maps.summary_user,
178			 key, value_irq, value_thread, value_user, cpus);
179}
180#endif /* HAVE_BPF_SKEL */
~/ Read-only file preview.