From: Tomas Glozar Date: Thu, 26 Jun 2025 12:33:59 +0000 (+0200) Subject: rtla/timerlat_bpf: Allow resuming tracing X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b78670e3a932c654dedf88807e70e19719cb0cb;p=thirdparty%2Fkernel%2Flinux.git 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 Cc: Luis Goncalves Cc: Arnaldo Carvalho de Melo Cc: Chang Yin Cc: Costa Shulyupin Cc: Crystal Wood Cc: Gabriele Monaco Link: https://lore.kernel.org/20250626123405.1496931-4-tglozar@redhat.com Signed-off-by: Tomas Glozar Signed-off-by: Steven Rostedt (Google) --- diff --git a/tools/tracing/rtla/src/timerlat.bpf.c b/tools/tracing/rtla/src/timerlat.bpf.c index 96196d46e1701..084cd10c21fc4 100644 --- a/tools/tracing/rtla/src/timerlat.bpf.c +++ b/tools/tracing/rtla/src/timerlat.bpf.c @@ -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; diff --git a/tools/tracing/rtla/src/timerlat_bpf.c b/tools/tracing/rtla/src/timerlat_bpf.c index 0bc44ce5d69bd..1666215dd687b 100644 --- a/tools/tracing/rtla/src/timerlat_bpf.c +++ b/tools/tracing/rtla/src/timerlat_bpf.c @@ -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, diff --git a/tools/tracing/rtla/src/timerlat_bpf.h b/tools/tracing/rtla/src/timerlat_bpf.h index f1b54dbddb0e2..118487436d304 100644 --- a/tools/tracing/rtla/src/timerlat_bpf.h +++ b/tools/tracing/rtla/src/timerlat_bpf.h @@ -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,