Skip to content

Commit 3d032a2

Browse files
ahunter6acmel
authored andcommitted
perf script: Add option to pass arguments to dlfilters
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> 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-5-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent 638e2b9 commit 3d032a2

6 files changed

Lines changed: 91 additions & 13 deletions

File tree

tools/perf/Documentation/perf-dlfilter.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ object file
99
SYNOPSIS
1010
--------
1111
[verse]
12-
'perf script' [--dlfilter file.so ]
12+
'perf script' [--dlfilter file.so ] [ --dlarg arg ]...
1313

1414
DESCRIPTION
1515
-----------
1616

1717
This option is used to process data through a custom filter provided by a
18-
dynamically loaded shared object file.
18+
dynamically loaded shared object file. Arguments can be passed using --dlarg
19+
and retrieved using perf_dlfilter_fns.args().
1920

2021
If 'file.so' does not contain "/", then it will be found either in the current
2122
directory, or perf tools exec path which is ~/libexec/perf-core/dlfilters for
@@ -121,14 +122,17 @@ file is loaded. The functions can be called by 'filter_event' or
121122
struct perf_dlfilter_fns {
122123
const struct perf_dlfilter_al *(*resolve_ip)(void *ctx);
123124
const struct perf_dlfilter_al *(*resolve_addr)(void *ctx);
124-
void *(*reserved[126])(void *);
125+
char **(*args)(void *ctx, int *dlargc);
126+
void *(*reserved[125])(void *);
125127
};
126128
----
127129

128130
'resolve_ip' returns information about ip.
129131

130132
'resolve_addr' returns information about addr (if addr_correlates_sym).
131133

134+
'args' returns arguments from --dlarg options.
135+
132136
The perf_dlfilter_al structure
133137
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
134138

tools/perf/Documentation/perf-script.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ OPTIONS
102102
Filter sample events using the given shared object file.
103103
Refer linkperf:perf-dlfilter[1]
104104

105+
--dlarg=<arg>::
106+
Pass 'arg' as an argument to the dlfilter. --dlarg may be repeated
107+
to add more arguments.
108+
105109
--list-dlfilters=::
106110
Display a list of available dlfilters. Use with option -v (must come
107111
before option --list-dlfilters) to show long descriptions.

tools/perf/builtin-script.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ static struct perf_stat_config stat_config;
8181
static int max_blocks;
8282
static bool native_arch;
8383
static struct dlfilter *dlfilter;
84+
static int dlargc;
85+
static char **dlargv;
8486

8587
unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
8688

@@ -3175,6 +3177,34 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
31753177
exit(0);
31763178
}
31773179

3180+
static int add_dlarg(const struct option *opt __maybe_unused,
3181+
const char *s, int unset __maybe_unused)
3182+
{
3183+
char *arg = strdup(s);
3184+
void *a;
3185+
3186+
if (!arg)
3187+
return -1;
3188+
3189+
a = realloc(dlargv, sizeof(dlargv[0]) * (dlargc + 1));
3190+
if (!a) {
3191+
free(arg);
3192+
return -1;
3193+
}
3194+
3195+
dlargv = a;
3196+
dlargv[dlargc++] = arg;
3197+
3198+
return 0;
3199+
}
3200+
3201+
static void free_dlarg(void)
3202+
{
3203+
while (dlargc--)
3204+
free(dlargv[dlargc]);
3205+
free(dlargv);
3206+
}
3207+
31783208
/*
31793209
* Some scripts specify the required events in their "xxx-record" file,
31803210
* this function will check if the events in perf.data match those
@@ -3639,6 +3669,8 @@ int cmd_script(int argc, const char **argv)
36393669
OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
36403670
"generate perf-script.xx script in specified language"),
36413671
OPT_STRING(0, "dlfilter", &dlfilter_file, "file", "filter .so file name"),
3672+
OPT_CALLBACK(0, "dlarg", NULL, "argument", "filter argument",
3673+
add_dlarg),
36423674
OPT_STRING('i', "input", &input_name, "file", "input file name"),
36433675
OPT_BOOLEAN('d', "debug-mode", &debug_mode,
36443676
"do various checks like samples ordering and lost events"),
@@ -3958,7 +3990,7 @@ int cmd_script(int argc, const char **argv)
39583990
}
39593991

39603992
if (dlfilter_file) {
3961-
dlfilter = dlfilter__new(dlfilter_file);
3993+
dlfilter = dlfilter__new(dlfilter_file, dlargc, dlargv);
39623994
if (!dlfilter)
39633995
return -1;
39643996
}
@@ -4116,6 +4148,7 @@ int cmd_script(int argc, const char **argv)
41164148
if (script_started)
41174149
cleanup_scripting();
41184150
dlfilter__cleanup(dlfilter);
4151+
free_dlarg();
41194152
out:
41204153
return err;
41214154
}

tools/perf/util/dlfilter.c

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,26 @@ static const struct perf_dlfilter_al *dlfilter__resolve_addr(void *ctx)
133133
return d_addr_al;
134134
}
135135

136+
static char **dlfilter__args(void *ctx, int *dlargc)
137+
{
138+
struct dlfilter *d = (struct dlfilter *)ctx;
139+
140+
if (dlargc)
141+
*dlargc = 0;
142+
else
143+
return NULL;
144+
145+
if (!d->ctx_valid && !d->in_start && !d->in_stop)
146+
return NULL;
147+
148+
*dlargc = d->dlargc;
149+
return d->dlargv;
150+
}
151+
136152
static const struct perf_dlfilter_fns perf_dlfilter_fns = {
137153
.resolve_ip = dlfilter__resolve_ip,
138154
.resolve_addr = dlfilter__resolve_addr,
155+
.args = dlfilter__args,
139156
};
140157

141158
static char *find_dlfilter(const char *file)
@@ -169,7 +186,7 @@ static char *find_dlfilter(const char *file)
169186

170187
#define CHECK_FLAG(x) BUILD_BUG_ON((u64)PERF_DLFILTER_FLAG_ ## x != (u64)PERF_IP_FLAG_ ## x)
171188

172-
static int dlfilter__init(struct dlfilter *d, const char *file)
189+
static int dlfilter__init(struct dlfilter *d, const char *file, int dlargc, char **dlargv)
173190
{
174191
CHECK_FLAG(BRANCH);
175192
CHECK_FLAG(CALL);
@@ -189,6 +206,8 @@ static int dlfilter__init(struct dlfilter *d, const char *file)
189206
d->file = find_dlfilter(file);
190207
if (!d->file)
191208
return -1;
209+
d->dlargc = dlargc;
210+
d->dlargv = dlargv;
192211
return 0;
193212
}
194213

@@ -219,14 +238,14 @@ static int dlfilter__close(struct dlfilter *d)
219238
return dlclose(d->handle);
220239
}
221240

222-
struct dlfilter *dlfilter__new(const char *file)
241+
struct dlfilter *dlfilter__new(const char *file, int dlargc, char **dlargv)
223242
{
224243
struct dlfilter *d = malloc(sizeof(*d));
225244

226245
if (!d)
227246
return NULL;
228247

229-
if (dlfilter__init(d, file))
248+
if (dlfilter__init(d, file, dlargc, dlargv))
230249
goto err_free;
231250

232251
if (dlfilter__open(d))
@@ -253,16 +272,28 @@ int dlfilter__start(struct dlfilter *d, struct perf_session *session)
253272
{
254273
if (d) {
255274
d->session = session;
256-
if (d->start)
257-
return d->start(&d->data, d);
275+
if (d->start) {
276+
int ret;
277+
278+
d->in_start = true;
279+
ret = d->start(&d->data, d);
280+
d->in_start = false;
281+
return ret;
282+
}
258283
}
259284
return 0;
260285
}
261286

262287
static int dlfilter__stop(struct dlfilter *d)
263288
{
264-
if (d && d->stop)
265-
return d->stop(d->data, d);
289+
if (d && d->stop) {
290+
int ret;
291+
292+
d->in_stop = true;
293+
ret = d->stop(d->data, d);
294+
d->in_stop = false;
295+
return ret;
296+
}
266297
return 0;
267298
}
268299

tools/perf/util/dlfilter.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ struct dlfilter {
2323
void *data;
2424
struct perf_session *session;
2525
bool ctx_valid;
26+
bool in_start;
27+
bool in_stop;
28+
int dlargc;
29+
char **dlargv;
2630

2731
union perf_event *event;
2832
struct perf_sample *sample;
@@ -47,7 +51,7 @@ struct dlfilter {
4751
struct perf_dlfilter_fns *fns;
4852
};
4953

50-
struct dlfilter *dlfilter__new(const char *file);
54+
struct dlfilter *dlfilter__new(const char *file, int dlargc, char **dlargv);
5155

5256
int dlfilter__start(struct dlfilter *d, struct perf_session *session);
5357

tools/perf/util/perf_dlfilter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,10 @@ struct perf_dlfilter_fns {
9090
const struct perf_dlfilter_al *(*resolve_ip)(void *ctx);
9191
/* Return information about addr (if addr_correlates_sym) */
9292
const struct perf_dlfilter_al *(*resolve_addr)(void *ctx);
93+
/* Return arguments from --dlarg option */
94+
char **(*args)(void *ctx, int *dlargc);
9395
/* Reserved */
94-
void *(*reserved[126])(void *);
96+
void *(*reserved[125])(void *);
9597
};
9698

9799
/*

0 commit comments

Comments
 (0)