summaryrefslogtreecommitdiff
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2021-06-27 16:18:09 +0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2021-07-01 22:14:37 +0300
commit291961fc3c28b4c1acfc3b03559aa14c286a6b0d (patch)
treedd2653c0fb8d0a619e7ccdc72382d0e58560a2ba /tools/perf/builtin-script.c
parentc435c166dcf526ac827bc964d82cc0d5e7a1fd0b (diff)
downloadlinux-291961fc3c28b4c1acfc3b03559aa14c286a6b0d.tar.xz
perf script: Add API for filtering via dynamically loaded shared object
In some cases, users want to filter very large amounts of data (e.g. from AUX area tracing like Intel PT) looking for something specific. While scripting such as Python can be used, Python is 10 to 20 times slower than C. So define a C API so that custom filters can be written and loaded. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: https://lore.kernel.org/r/20210627131818.810-2-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index d2771a997e26..aaf2922643a0 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -55,6 +55,7 @@
#include <subcmd/pager.h>
#include <perf/evlist.h>
#include <linux/err.h>
+#include "util/dlfilter.h"
#include "util/record.h"
#include "util/util.h"
#include "perf.h"
@@ -79,6 +80,7 @@ static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
static struct perf_stat_config stat_config;
static int max_blocks;
static bool native_arch;
+static struct dlfilter *dlfilter;
unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
@@ -2175,6 +2177,7 @@ static int process_sample_event(struct perf_tool *tool,
struct perf_script *scr = container_of(tool, struct perf_script, tool);
struct addr_location al;
struct addr_location addr_al;
+ int ret = 0;
if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,
sample->time)) {
@@ -2213,6 +2216,13 @@ static int process_sample_event(struct perf_tool *tool,
if (evswitch__discard(&scr->evswitch, evsel))
goto out_put;
+ ret = dlfilter__filter_event(dlfilter, event, sample, evsel, machine, &al, &addr_al);
+ if (ret) {
+ if (ret > 0)
+ ret = 0;
+ goto out_put;
+ }
+
if (scripting_ops) {
struct addr_location *addr_al_ptr = NULL;
@@ -2229,7 +2239,7 @@ static int process_sample_event(struct perf_tool *tool,
out_put:
addr_location__put(&al);
- return 0;
+ return ret;
}
static int process_attr(struct perf_tool *tool, union perf_event *event,
@@ -3568,6 +3578,7 @@ int cmd_script(int argc, const char **argv)
};
struct utsname uts;
char *script_path = NULL;
+ const char *dlfilter_file = NULL;
const char **__argv;
int i, j, err = 0;
struct perf_script script = {
@@ -3615,6 +3626,7 @@ int cmd_script(int argc, const char **argv)
parse_scriptname),
OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
"generate perf-script.xx script in specified language"),
+ OPT_STRING(0, "dlfilter", &dlfilter_file, "file", "filter .so file name"),
OPT_STRING('i', "input", &input_name, "file", "input file name"),
OPT_BOOLEAN('d', "debug-mode", &debug_mode,
"do various checks like samples ordering and lost events"),
@@ -3933,6 +3945,12 @@ script_found:
exit(-1);
}
+ if (dlfilter_file) {
+ dlfilter = dlfilter__new(dlfilter_file);
+ if (!dlfilter)
+ return -1;
+ }
+
if (!script_name) {
setup_pager();
use_browser = 0;
@@ -4032,6 +4050,10 @@ script_found:
goto out_delete;
}
+ err = dlfilter__start(dlfilter, session);
+ if (err)
+ goto out_delete;
+
if (script_name) {
err = scripting_ops->start_script(script_name, argc, argv, session);
if (err)
@@ -4081,6 +4103,7 @@ out_delete:
if (script_started)
cleanup_scripting();
+ dlfilter__cleanup(dlfilter);
out:
return err;
}