summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/tracing/rtla/src/timerlat.c11
-rw-r--r--tools/tracing/rtla/src/timerlat.h2
-rw-r--r--tools/tracing/rtla/src/timerlat_bpf.c53
-rw-r--r--tools/tracing/rtla/src/timerlat_bpf.h6
-rw-r--r--tools/tracing/rtla/src/timerlat_hist.c5
-rw-r--r--tools/tracing/rtla/src/timerlat_top.c5
6 files changed, 80 insertions, 2 deletions
diff --git a/tools/tracing/rtla/src/timerlat.c b/tools/tracing/rtla/src/timerlat.c
index ee15e344cf37..8f6cf55f4a94 100644
--- a/tools/tracing/rtla/src/timerlat.c
+++ b/tools/tracing/rtla/src/timerlat.c
@@ -48,6 +48,17 @@ timerlat_apply_config(struct osnoise_tool *tool, struct timerlat_params *params)
}
}
+ /* Check if BPF action program is requested but BPF is not available */
+ if (params->bpf_action_program) {
+ if (params->mode == TRACING_MODE_TRACEFS) {
+ err_msg("BPF actions are not supported in tracefs-only mode\n");
+ goto out_err;
+ }
+
+ if (timerlat_load_bpf_action_program(params->bpf_action_program))
+ goto out_err;
+ }
+
retval = osnoise_set_timerlat_period_us(tool->context,
params->timerlat_period_us ?
params->timerlat_period_us :
diff --git a/tools/tracing/rtla/src/timerlat.h b/tools/tracing/rtla/src/timerlat.h
index fd6065f48bb7..8dd5d134ce08 100644
--- a/tools/tracing/rtla/src/timerlat.h
+++ b/tools/tracing/rtla/src/timerlat.h
@@ -27,6 +27,7 @@ struct timerlat_params {
int dump_tasks;
int deepest_idle_state;
enum timerlat_tracing_mode mode;
+ const char *bpf_action_program;
};
#define to_timerlat_params(ptr) container_of(ptr, struct timerlat_params, common)
@@ -36,4 +37,3 @@ int timerlat_main(int argc, char *argv[]);
int timerlat_enable(struct osnoise_tool *tool);
void timerlat_analyze(struct osnoise_tool *tool, bool stopped);
void timerlat_free(struct osnoise_tool *tool);
-
diff --git a/tools/tracing/rtla/src/timerlat_bpf.c b/tools/tracing/rtla/src/timerlat_bpf.c
index 1d619e502c65..05adf18303df 100644
--- a/tools/tracing/rtla/src/timerlat_bpf.c
+++ b/tools/tracing/rtla/src/timerlat_bpf.c
@@ -7,6 +7,10 @@
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
*/
@@ -96,6 +100,11 @@ void timerlat_bpf_detach(void)
void timerlat_bpf_destroy(void)
{
timerlat_bpf__destroy(bpf);
+ bpf = NULL;
+ if (obj)
+ bpf_object__close(obj);
+ obj = NULL;
+ prog = NULL;
}
static int handle_rb_event(void *ctx, void *data, size_t data_sz)
@@ -190,4 +199,48 @@ int timerlat_bpf_get_summary_value(enum summary_field key,
bpf->maps.summary_user,
key, value_irq, value_thread, value_user, cpus);
}
+
+/*
+ * timerlat_load_bpf_action_program - load and register a BPF action program
+ */
+int timerlat_load_bpf_action_program(const char *program_path)
+{
+ int err;
+
+ obj = bpf_object__open_file(program_path, NULL);
+ if (!obj) {
+ err_msg("Failed to open BPF action program: %s\n", program_path);
+ goto out_err;
+ }
+
+ err = bpf_object__load(obj);
+ if (err) {
+ err_msg("Failed to load BPF action program: %s\n", program_path);
+ goto out_obj_err;
+ }
+
+ prog = bpf_object__find_program_by_name(obj, "action_handler");
+ if (!prog) {
+ err_msg("BPF action program must have 'action_handler' function: %s\n",
+ program_path);
+ goto out_obj_err;
+ }
+
+ err = timerlat_bpf_set_action(prog);
+ if (err) {
+ err_msg("Failed to register BPF action program: %s\n", program_path);
+ goto out_prog_err;
+ }
+
+ return 0;
+
+out_prog_err:
+ prog = NULL;
+out_obj_err:
+ bpf_object__close(obj);
+ obj = NULL;
+out_err:
+ return 1;
+}
+
#endif /* HAVE_BPF_SKEL */
diff --git a/tools/tracing/rtla/src/timerlat_bpf.h b/tools/tracing/rtla/src/timerlat_bpf.h
index b5009092c7a3..169abeaf4363 100644
--- a/tools/tracing/rtla/src/timerlat_bpf.h
+++ b/tools/tracing/rtla/src/timerlat_bpf.h
@@ -30,7 +30,7 @@ int timerlat_bpf_get_summary_value(enum summary_field key,
long long *value_thread,
long long *value_user,
int cpus);
-
+int timerlat_load_bpf_action_program(const char *program_path);
static inline int have_libbpf_support(void) { return 1; }
#else
static inline int timerlat_bpf_init(struct timerlat_params *params)
@@ -58,6 +58,10 @@ static inline int timerlat_bpf_get_summary_value(enum summary_field key,
{
return -1;
}
+static inline int timerlat_load_bpf_action_program(const char *program_path)
+{
+ return -1;
+}
static inline int have_libbpf_support(void) { return 0; }
#endif /* HAVE_BPF_SKEL */
#endif /* __bpf__ */
diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
index 2a5c543217ba..ec43e6fda743 100644
--- a/tools/tracing/rtla/src/timerlat_hist.c
+++ b/tools/tracing/rtla/src/timerlat_hist.c
@@ -746,6 +746,7 @@ static void timerlat_hist_usage(void)
" --deepest-idle-state n: only go down to idle state n on cpus used by timerlat to reduce exit from idle latency",
" --on-threshold <action>: define action to be executed at latency threshold, multiple are allowed",
" --on-end <action>: define action to be executed at measurement end, multiple are allowed",
+ " --bpf-action <program>: load and execute BPF program when latency threshold is exceeded",
NULL,
};
@@ -825,6 +826,7 @@ static struct common_params
{"deepest-idle-state", required_argument, 0, '\4'},
{"on-threshold", required_argument, 0, '\5'},
{"on-end", required_argument, 0, '\6'},
+ {"bpf-action", required_argument, 0, '\7'},
{0, 0, 0, 0}
};
@@ -1006,6 +1008,9 @@ static struct common_params
if (retval)
fatal("Invalid action %s", optarg);
break;
+ case '\7':
+ params->bpf_action_program = optarg;
+ break;
default:
fatal("Invalid option");
}
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index 9ed8b931552f..af20b3eee472 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -518,6 +518,7 @@ static void timerlat_top_usage(void)
" --deepest-idle-state n: only go down to idle state n on cpus used by timerlat to reduce exit from idle latency",
" --on-threshold <action>: define action to be executed at latency threshold, multiple are allowed",
" --on-end: define action to be executed at measurement end, multiple are allowed",
+ " --bpf-action <program>: load and execute BPF program when latency threshold is exceeded",
NULL,
};
@@ -589,6 +590,7 @@ static struct common_params
{"deepest-idle-state", required_argument, 0, '8'},
{"on-threshold", required_argument, 0, '9'},
{"on-end", required_argument, 0, '\1'},
+ {"bpf-action", required_argument, 0, '\2'},
{0, 0, 0, 0}
};
@@ -756,6 +758,9 @@ static struct common_params
if (retval)
fatal("Invalid action %s", optarg);
break;
+ case '\2':
+ params->bpf_action_program = optarg;
+ break;
default:
fatal("Invalid option");
}