Commit 3b78670e authored by Tomas Glozar's avatar Tomas Glozar Committed by Steven Rostedt (Google)
Browse files

rtla/timerlat_bpf: Allow resuming tracing

Currently, rtla-timerlat BPF program uses a global variable stored in a
.bss section to store whether tracing has been stopped.

Move the information to a separate map, so that it is easily writable
from userspace, and add a function that clears the value, resuming
tracing after it has been stopped.

Cc: John Kacur <jkacur@redhat.com>
Cc: Luis Goncalves <lgoncalv@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Chang Yin <cyin@redhat.com>
Cc: Costa Shulyupin <costa.shul@redhat.com>
Cc: Crystal Wood <crwood@redhat.com>
Cc: Gabriele Monaco <gmonaco@redhat.com>
Link: https://lore.kernel.org/20250626123405.1496931-4-tglozar@redhat.com


Signed-off-by: default avatarTomas Glozar <tglozar@redhat.com>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent 6ea082b1
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -28,6 +28,13 @@ struct {
	__type(value, unsigned long long);
} summary_irq SEC(".maps"), summary_thread SEC(".maps"), summary_user SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, 1);
	__type(key, unsigned int);
	__type(value, unsigned long long);
} stop_tracing SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_RINGBUF);
	__uint(max_entries, 1);
@@ -41,8 +48,6 @@ const volatile int irq_threshold;
const volatile int thread_threshold;
const volatile bool aa_only;

int stop_tracing;

nosubprog unsigned long long map_get(void *map,
				     unsigned int key)
{
@@ -109,7 +114,7 @@ nosubprog void set_stop_tracing(void)
	int value = 0;

	/* Suppress further sample processing */
	stop_tracing = 1;
	map_set(&stop_tracing, 0, 1);

	/* Signal to userspace */
	bpf_ringbuf_output(&signal_stop_tracing, &value, sizeof(value), 0);
@@ -121,7 +126,7 @@ int handle_timerlat_sample(struct trace_event_raw_timerlat_sample *tp_args)
	unsigned long long latency, latency_us;
	int bucket;

	if (stop_tracing)
	if (map_get(&stop_tracing, 0))
		return 0;

	latency = tp_args->timer_latency / output_divisor;
+13 −0
Original line number Diff line number Diff line
@@ -106,6 +106,19 @@ int timerlat_bpf_wait(int timeout)
	return retval;
}

/*
 * timerlat_bpf_restart_tracing - restart stopped tracing
 */
int timerlat_bpf_restart_tracing(void)
{
	unsigned int key = 0;
	unsigned long long value = 0;

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

static int get_value(struct bpf_map *map_irq,
		     struct bpf_map *map_thread,
		     struct bpf_map *map_user,
+3 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ int timerlat_bpf_attach(void);
void timerlat_bpf_detach(void);
void timerlat_bpf_destroy(void);
int timerlat_bpf_wait(int timeout);
int timerlat_bpf_restart_tracing(void);
int timerlat_bpf_get_hist_value(int key,
				long long *value_irq,
				long long *value_thread,
@@ -28,6 +29,7 @@ int timerlat_bpf_get_summary_value(enum summary_field key,
				   long long *value_thread,
				   long long *value_user,
				   int cpus);

static inline int have_libbpf_support(void) { return 1; }
#else
static inline int timerlat_bpf_init(struct timerlat_params *params)
@@ -38,6 +40,7 @@ static inline int timerlat_bpf_attach(void) { return -1; }
static inline void timerlat_bpf_detach(void) { };
static inline void timerlat_bpf_destroy(void) { };
static inline int timerlat_bpf_wait(int timeout) { return -1; }
static inline int timerlat_bpf_restart_tracing(void) { return -1; };
static inline int timerlat_bpf_get_hist_value(int key,
					      long long *value_irq,
					      long long *value_thread,