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 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.