From: Adrian Hunter <adrian.hunter@intel.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>, Andi Kleen <ak@linux.intel.com>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Mark Rutland <mark.rutland@arm.com>,
Namhyung Kim <namhyung@kernel.org>, Leo Yan <leo.yan@linaro.org>,
Kan Liang <kan.liang@linux.intel.com>,
linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH V2 04/10] perf script: Add option to pass arguments to dlfilters
Date: Sun, 27 Jun 2021 16:18:12 +0300 [thread overview]
Message-ID: <20210627131818.810-5-adrian.hunter@intel.com> (raw)
In-Reply-To: <20210627131818.810-1-adrian.hunter@intel.com>
Add option --dlarg to pass arguments to dlfilters. The --dlarg option can
be repeated to pass more than 1 argument.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/Documentation/perf-dlfilter.txt | 10 +++--
tools/perf/Documentation/perf-script.txt | 4 ++
tools/perf/builtin-script.c | 35 ++++++++++++++++-
tools/perf/util/dlfilter.c | 45 ++++++++++++++++++----
tools/perf/util/dlfilter.h | 6 ++-
tools/perf/util/perf_dlfilter.h | 4 +-
6 files changed, 91 insertions(+), 13 deletions(-)
diff --git a/tools/perf/Documentation/perf-dlfilter.txt b/tools/perf/Documentation/perf-dlfilter.txt
index 8bc219f3eb83..5795ab3ca23b 100644
--- a/tools/perf/Documentation/perf-dlfilter.txt
+++ b/tools/perf/Documentation/perf-dlfilter.txt
@@ -9,13 +9,14 @@ object file
SYNOPSIS
--------
[verse]
-'perf script' [--dlfilter file.so ]
+'perf script' [--dlfilter file.so ] [ --dlarg arg ]...
DESCRIPTION
-----------
This option is used to process data through a custom filter provided by a
-dynamically loaded shared object file.
+dynamically loaded shared object file. Arguments can be passed using --dlarg
+and retrieved using perf_dlfilter_fns.args().
If 'file.so' does not contain "/", then it will be found either in the current
directory, or perf tools exec path which is ~/libexec/perf-core/dlfilters for
@@ -121,7 +122,8 @@ file is loaded. The functions can be called by 'filter_event' or
struct perf_dlfilter_fns {
const struct perf_dlfilter_al *(*resolve_ip)(void *ctx);
const struct perf_dlfilter_al *(*resolve_addr)(void *ctx);
- void *(*reserved[126])(void *);
+ char **(*args)(void *ctx, int *dlargc);
+ void *(*reserved[125])(void *);
};
----
@@ -129,6 +131,8 @@ struct perf_dlfilter_fns {
'resolve_addr' returns information about addr (if addr_correlates_sym).
+'args' returns arguments from --dlarg options.
+
The perf_dlfilter_al structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index d2705d6b9874..aa3a0b2c29a2 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -102,6 +102,10 @@ OPTIONS
Filter sample events using the given shared object file.
Refer linkperf:perf-dlfilter[1]
+--dlarg=<arg>::
+ Pass 'arg' as an argument to the dlfilter. --dlarg may be repeated
+ to add more arguments.
+
--list-dlfilters=::
Display a list of available dlfilters. Use with option -v (must come
before option --list-dlfilters) to show long descriptions.
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 4ffba1dbc55d..2030936cc891 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -81,6 +81,8 @@ static struct perf_stat_config stat_config;
static int max_blocks;
static bool native_arch;
static struct dlfilter *dlfilter;
+static int dlargc;
+static char **dlargv;
unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
@@ -3175,6 +3177,34 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
exit(0);
}
+static int add_dlarg(const struct option *opt __maybe_unused,
+ const char *s, int unset __maybe_unused)
+{
+ char *arg = strdup(s);
+ void *a;
+
+ if (!arg)
+ return -1;
+
+ a = realloc(dlargv, sizeof(dlargv[0]) * (dlargc + 1));
+ if (!a) {
+ free(arg);
+ return -1;
+ }
+
+ dlargv = a;
+ dlargv[dlargc++] = arg;
+
+ return 0;
+}
+
+static void free_dlarg(void)
+{
+ while (dlargc--)
+ free(dlargv[dlargc]);
+ free(dlargv);
+}
+
/*
* Some scripts specify the required events in their "xxx-record" file,
* this function will check if the events in perf.data match those
@@ -3639,6 +3669,8 @@ int cmd_script(int argc, const char **argv)
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_CALLBACK(0, "dlarg", NULL, "argument", "filter argument",
+ add_dlarg),
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"),
@@ -3958,7 +3990,7 @@ int cmd_script(int argc, const char **argv)
}
if (dlfilter_file) {
- dlfilter = dlfilter__new(dlfilter_file);
+ dlfilter = dlfilter__new(dlfilter_file, dlargc, dlargv);
if (!dlfilter)
return -1;
}
@@ -4116,6 +4148,7 @@ int cmd_script(int argc, const char **argv)
if (script_started)
cleanup_scripting();
dlfilter__cleanup(dlfilter);
+ free_dlarg();
out:
return err;
}
diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c
index 288a2b57378c..eaa3cea49178 100644
--- a/tools/perf/util/dlfilter.c
+++ b/tools/perf/util/dlfilter.c
@@ -133,9 +133,26 @@ static const struct perf_dlfilter_al *dlfilter__resolve_addr(void *ctx)
return d_addr_al;
}
+static char **dlfilter__args(void *ctx, int *dlargc)
+{
+ struct dlfilter *d = (struct dlfilter *)ctx;
+
+ if (dlargc)
+ *dlargc = 0;
+ else
+ return NULL;
+
+ if (!d->ctx_valid && !d->in_start && !d->in_stop)
+ return NULL;
+
+ *dlargc = d->dlargc;
+ return d->dlargv;
+}
+
static const struct perf_dlfilter_fns perf_dlfilter_fns = {
.resolve_ip = dlfilter__resolve_ip,
.resolve_addr = dlfilter__resolve_addr,
+ .args = dlfilter__args,
};
static char *find_dlfilter(const char *file)
@@ -169,7 +186,7 @@ static char *find_dlfilter(const char *file)
#define CHECK_FLAG(x) BUILD_BUG_ON((u64)PERF_DLFILTER_FLAG_ ## x != (u64)PERF_IP_FLAG_ ## x)
-static int dlfilter__init(struct dlfilter *d, const char *file)
+static int dlfilter__init(struct dlfilter *d, const char *file, int dlargc, char **dlargv)
{
CHECK_FLAG(BRANCH);
CHECK_FLAG(CALL);
@@ -189,6 +206,8 @@ static int dlfilter__init(struct dlfilter *d, const char *file)
d->file = find_dlfilter(file);
if (!d->file)
return -1;
+ d->dlargc = dlargc;
+ d->dlargv = dlargv;
return 0;
}
@@ -219,14 +238,14 @@ static int dlfilter__close(struct dlfilter *d)
return dlclose(d->handle);
}
-struct dlfilter *dlfilter__new(const char *file)
+struct dlfilter *dlfilter__new(const char *file, int dlargc, char **dlargv)
{
struct dlfilter *d = malloc(sizeof(*d));
if (!d)
return NULL;
- if (dlfilter__init(d, file))
+ if (dlfilter__init(d, file, dlargc, dlargv))
goto err_free;
if (dlfilter__open(d))
@@ -253,16 +272,28 @@ int dlfilter__start(struct dlfilter *d, struct perf_session *session)
{
if (d) {
d->session = session;
- if (d->start)
- return d->start(&d->data, d);
+ if (d->start) {
+ int ret;
+
+ d->in_start = true;
+ ret = d->start(&d->data, d);
+ d->in_start = false;
+ return ret;
+ }
}
return 0;
}
static int dlfilter__stop(struct dlfilter *d)
{
- if (d && d->stop)
- return d->stop(d->data, d);
+ if (d && d->stop) {
+ int ret;
+
+ d->in_stop = true;
+ ret = d->stop(d->data, d);
+ d->in_stop = false;
+ return ret;
+ }
return 0;
}
diff --git a/tools/perf/util/dlfilter.h b/tools/perf/util/dlfilter.h
index a1ed38da3ce6..505980442360 100644
--- a/tools/perf/util/dlfilter.h
+++ b/tools/perf/util/dlfilter.h
@@ -23,6 +23,10 @@ struct dlfilter {
void *data;
struct perf_session *session;
bool ctx_valid;
+ bool in_start;
+ bool in_stop;
+ int dlargc;
+ char **dlargv;
union perf_event *event;
struct perf_sample *sample;
@@ -47,7 +51,7 @@ struct dlfilter {
struct perf_dlfilter_fns *fns;
};
-struct dlfilter *dlfilter__new(const char *file);
+struct dlfilter *dlfilter__new(const char *file, int dlargc, char **dlargv);
int dlfilter__start(struct dlfilter *d, struct perf_session *session);
diff --git a/tools/perf/util/perf_dlfilter.h b/tools/perf/util/perf_dlfilter.h
index 31ad4c100181..35e03aa41a7f 100644
--- a/tools/perf/util/perf_dlfilter.h
+++ b/tools/perf/util/perf_dlfilter.h
@@ -90,8 +90,10 @@ struct perf_dlfilter_fns {
const struct perf_dlfilter_al *(*resolve_ip)(void *ctx);
/* Return information about addr (if addr_correlates_sym) */
const struct perf_dlfilter_al *(*resolve_addr)(void *ctx);
+ /* Return arguments from --dlarg option */
+ char **(*args)(void *ctx, int *dlargc);
/* Reserved */
- void *(*reserved[126])(void *);
+ void *(*reserved[125])(void *);
};
/*
--
2.17.1
next prev parent reply other threads:[~2021-06-27 13:18 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-27 13:18 [PATCH V2 00/10] perf script: Add API for filtering via dynamically loaded shared object Adrian Hunter
2021-06-27 13:18 ` [PATCH V2 01/10] " Adrian Hunter
2021-06-27 13:18 ` [PATCH V2 02/10] perf script: Add dlfilter__filter_event_early() Adrian Hunter
2021-06-27 13:18 ` [PATCH V2 03/10] perf script: Add option to list dlfilters Adrian Hunter
2021-06-27 13:18 ` Adrian Hunter [this message]
2021-06-27 13:18 ` [PATCH V2 05/10] perf build: Install perf_dlfilter.h Adrian Hunter
2021-06-27 13:18 ` [PATCH V2 06/10] perf dlfilter: Add resolve_address() to perf_dlfilter_fns Adrian Hunter
2021-06-27 13:18 ` [PATCH V2 07/10] perf dlfilter: Add insn() " Adrian Hunter
2021-06-27 13:18 ` [PATCH V2 08/10] perf dlfilter: Add srcline() " Adrian Hunter
2021-06-27 13:18 ` [PATCH V2 09/10] perf dlfilter: Add attr() " Adrian Hunter
2021-06-27 13:18 ` [PATCH V2 10/10] perf dlfilter: Add object_code() " Adrian Hunter
2021-06-27 16:13 ` [PATCH V2 00/10] perf script: Add API for filtering via dynamically loaded shared object Andi Kleen
2021-06-28 7:23 ` Adrian Hunter
2021-06-28 14:57 ` Andi Kleen
2021-06-28 19:30 ` Adrian Hunter
2021-06-29 19:28 ` Namhyung Kim
2021-07-01 17:40 ` Arnaldo Carvalho de Melo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210627131818.810-5-adrian.hunter@intel.com \
--to=adrian.hunter@intel.com \
--cc=acme@kernel.org \
--cc=ak@linux.intel.com \
--cc=jolsa@redhat.com \
--cc=kan.liang@linux.intel.com \
--cc=leo.yan@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.