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 RFC 05/11] perf script: Add dlfilter__filter_event_early()
Date: Mon, 21 Jun 2021 18:05:08 +0300 [thread overview]
Message-ID: <20210621150514.32159-6-adrian.hunter@intel.com> (raw)
In-Reply-To: <20210621150514.32159-1-adrian.hunter@intel.com>
filter_event_early() can be more than 30% faster than filter_event()
because it is called before internal filtering. In other respects it
is the same as filter_event(), except that it will be passed events
that have yet to be filtered out.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/Documentation/perf-dlfilter.txt | 13 +++++++----
tools/perf/builtin-script.c | 26 +++++++++++++++-------
tools/perf/util/dlfilter.c | 9 ++++++--
tools/perf/util/dlfilter.h | 21 +++++++++++++++--
tools/perf/util/perf_dlfilter.h | 6 +++++
5 files changed, 59 insertions(+), 16 deletions(-)
diff --git a/tools/perf/Documentation/perf-dlfilter.txt b/tools/perf/Documentation/perf-dlfilter.txt
index d8f80998790f..8eada542330a 100644
--- a/tools/perf/Documentation/perf-dlfilter.txt
+++ b/tools/perf/Documentation/perf-dlfilter.txt
@@ -31,15 +31,16 @@ const struct perf_dlfilter_fns perf_dlfilter_fns;
int start(void **data);
int stop(void *data);
int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx);
+int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx);
----
If implemented, 'start' will be called at the beginning, before any
-calls to 'filter_event' . Return 0 to indicate success,
+calls to 'filter_event' or 'filter_event_early'. Return 0 to indicate success,
or return a negative error code. '*data' can be assigned for use by other
functions.
If implemented, 'stop' will be called at the end, after any calls to
-'filter_event'. Return 0 to indicate success, or
+'filter_event' or 'filter_event_early'. Return 0 to indicate success, or
return a negative error code. 'data' is set by 'start'.
If implemented, 'filter_event' will be called for each sample event.
@@ -47,10 +48,13 @@ Return 0 to keep the sample event, 1 to filter it out, or return a negative
error code. 'data' is set by 'start'. 'ctx' is needed for calls to
'perf_dlfilter_fns'.
+'filter_event_early' is the same as 'filter_event' except it is called before
+internal filtering.
+
The perf_dlfilter_sample structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-'filter_event' is passed a perf_dlfilter_sample
+'filter_event' and 'filter_event_early' are passed a perf_dlfilter_sample
structure, which contains the following fields:
[source,c]
----
@@ -97,7 +101,8 @@ The perf_dlfilter_fns structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'perf_dlfilter_fns' structure is populated with function pointers when the
-file is loaded. The functions can be called by 'filter_event'.
+file is loaded. The functions can be called by 'filter_event' or
+'filter_event_early'.
[source,c]
----
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index aaf2922643a0..e47affe674a5 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -2179,9 +2179,20 @@ static int process_sample_event(struct perf_tool *tool,
struct addr_location addr_al;
int ret = 0;
+ /* Set thread to NULL to indicate addr_al and al are not initialized */
+ addr_al.thread = NULL;
+ al.thread = NULL;
+
+ ret = dlfilter__filter_event_early(dlfilter, event, sample, evsel, machine, &al, &addr_al);
+ if (ret) {
+ if (ret > 0)
+ ret = 0;
+ goto out_put;
+ }
+
if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,
sample->time)) {
- return 0;
+ goto out_put;
}
if (debug_mode) {
@@ -2192,24 +2203,22 @@ static int process_sample_event(struct perf_tool *tool,
nr_unordered++;
}
last_timestamp = sample->time;
- return 0;
+ goto out_put;
}
if (filter_cpu(sample))
- return 0;
+ goto out_put;
if (machine__resolve(machine, &al, sample) < 0) {
pr_err("problem processing %d event, skipping it.\n",
event->header.type);
- return -1;
+ ret = -1;
+ goto out_put;
}
if (al.filtered)
goto out_put;
- /* Set thread to NULL to indicate addr_al is not initialized */
- addr_al.thread = NULL;
-
if (!show_event(sample, evsel, al.thread, &al, &addr_al))
goto out_put;
@@ -2238,7 +2247,8 @@ static int process_sample_event(struct perf_tool *tool,
}
out_put:
- addr_location__put(&al);
+ if (al.thread)
+ addr_location__put(&al);
return ret;
}
diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c
index 15cb9de13a4b..8a2b196f07a7 100644
--- a/tools/perf/util/dlfilter.c
+++ b/tools/perf/util/dlfilter.c
@@ -175,6 +175,7 @@ static int dlfilter__open(struct dlfilter *d)
}
d->start = dlsym(d->handle, "start");
d->filter_event = dlsym(d->handle, "filter_event");
+ d->filter_event_early = dlsym(d->handle, "filter_event_early");
d->stop = dlsym(d->handle, "stop");
d->fns = dlsym(d->handle, "perf_dlfilter_fns");
if (d->fns)
@@ -251,7 +252,8 @@ int dlfilter__do_filter_event(struct dlfilter *d,
struct evsel *evsel,
struct machine *machine,
struct addr_location *al,
- struct addr_location *addr_al)
+ struct addr_location *addr_al,
+ bool early)
{
struct perf_dlfilter_sample d_sample;
struct perf_dlfilter_al d_ip_al;
@@ -322,7 +324,10 @@ int dlfilter__do_filter_event(struct dlfilter *d,
d->ctx_valid = true;
- ret = d->filter_event(d->data, &d_sample, d);
+ if (early)
+ ret = d->filter_event_early(d->data, &d_sample, d);
+ else
+ ret = d->filter_event(d->data, &d_sample, d);
d->ctx_valid = false;
diff --git a/tools/perf/util/dlfilter.h b/tools/perf/util/dlfilter.h
index 671e2d3d5a06..eee799ea4382 100644
--- a/tools/perf/util/dlfilter.h
+++ b/tools/perf/util/dlfilter.h
@@ -40,6 +40,9 @@ struct dlfilter {
int (*filter_event)(void *data,
const struct perf_dlfilter_sample *sample,
void *ctx);
+ int (*filter_event_early)(void *data,
+ const struct perf_dlfilter_sample *sample,
+ void *ctx);
struct perf_dlfilter_fns *fns;
};
@@ -54,7 +57,8 @@ int dlfilter__do_filter_event(struct dlfilter *d,
struct evsel *evsel,
struct machine *machine,
struct addr_location *al,
- struct addr_location *addr_al);
+ struct addr_location *addr_al,
+ bool early);
void dlfilter__cleanup(struct dlfilter *d);
@@ -68,7 +72,20 @@ static inline int dlfilter__filter_event(struct dlfilter *d,
{
if (!d || !d->filter_event)
return 0;
- return dlfilter__do_filter_event(d, event, sample, evsel, machine, al, addr_al);
+ return dlfilter__do_filter_event(d, event, sample, evsel, machine, al, addr_al, false);
+}
+
+static inline int dlfilter__filter_event_early(struct dlfilter *d,
+ union perf_event *event,
+ struct perf_sample *sample,
+ struct evsel *evsel,
+ struct machine *machine,
+ struct addr_location *al,
+ struct addr_location *addr_al)
+{
+ if (!d || !d->filter_event_early)
+ return 0;
+ return dlfilter__do_filter_event(d, event, sample, evsel, machine, al, addr_al, true);
}
#endif
diff --git a/tools/perf/util/perf_dlfilter.h b/tools/perf/util/perf_dlfilter.h
index 132f833f0a0b..d24c3e2a8407 100644
--- a/tools/perf/util/perf_dlfilter.h
+++ b/tools/perf/util/perf_dlfilter.h
@@ -117,4 +117,10 @@ int stop(void *data);
*/
int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx);
+/*
+ * The same as 'filter_event' except it is called before internal
+ * filtering.
+ */
+int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx);
+
#endif
--
2.17.1
next prev parent reply other threads:[~2021-06-21 15:05 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-21 15:05 [PATCH RFC 00/11] perf script: Add API for filtering via dynamically loaded shared object Adrian Hunter
2021-06-21 15:05 ` [PATCH RFC 01/11] perf script: Move filter_cpu() earlier Adrian Hunter
2021-06-22 18:16 ` Arnaldo Carvalho de Melo
2021-06-21 15:05 ` [PATCH RFC 02/11] perf script: Move filtering before scripting Adrian Hunter
2021-06-22 18:18 ` Arnaldo Carvalho de Melo
2021-06-21 15:05 ` [PATCH RFC 03/11] perf script: Share addr_al between functions Adrian Hunter
2021-06-22 18:21 ` Arnaldo Carvalho de Melo
2021-06-21 15:05 ` [PATCH RFC 04/11] perf script: Add API for filtering via dynamically loaded shared object Adrian Hunter
2021-06-22 18:32 ` Arnaldo Carvalho de Melo
2021-06-23 9:25 ` Adrian Hunter
2021-06-21 15:05 ` Adrian Hunter [this message]
2021-06-21 15:05 ` [PATCH RFC 06/11] perf build: Install perf_dlfilter.h Adrian Hunter
2021-06-21 15:05 ` [PATCH RFC 07/11] perf dlfilter: Add resolve_address() to perf_dlfilter_fns Adrian Hunter
2021-06-21 15:05 ` [PATCH RFC 08/11] perf dlfilter: Add insn() " Adrian Hunter
2021-06-21 15:05 ` [PATCH RFC 09/11] perf dlfilter: Add srcline() " Adrian Hunter
2021-06-21 15:05 ` [PATCH RFC 10/11] perf dlfilter: Add attr() " Adrian Hunter
2021-06-21 15:05 ` [PATCH RFC 11/11] perf dlfilter: Add object_code() " Adrian Hunter
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=20210621150514.32159-6-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).