From: Chun-Tse Shao <ctshao@google.com>
To: linux-kernel@vger.kernel.org
Cc: Chun-Tse Shao <ctshao@google.com>,
Namhyung Kim <namhyung@kernel.org>,
peterz@infradead.org, mingo@redhat.com, acme@kernel.org,
mark.rutland@arm.com, alexander.shishkin@linux.intel.com,
jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com,
kan.liang@linux.intel.com, nick.forrington@arm.com,
linux-perf-users@vger.kernel.org, bpf@vger.kernel.org
Subject: [PATCH v1] perf lock: Add --duration-filter option
Date: Thu, 10 Apr 2025 22:24:19 -0700 [thread overview]
Message-ID: <20250411052548.2089332-1-ctshao@google.com> (raw)
This patch introduces the `--duration-filter` option, allows users to
exclude lock contention samples with durations shorter than the
specified filter value.
Signed-off-by: Chun-Tse Shao <ctshao@google.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/Documentation/perf-lock.txt | 3 +++
tools/perf/builtin-lock.c | 3 +++
tools/perf/util/bpf_lock_contention.c | 22 ++++++++++++++-----
.../perf/util/bpf_skel/lock_contention.bpf.c | 7 ++++++
tools/perf/util/lock-contention.h | 1 +
5 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/tools/perf/Documentation/perf-lock.txt b/tools/perf/Documentation/perf-lock.txt
index 859dc11a7372..1f57f5fc59e0 100644
--- a/tools/perf/Documentation/perf-lock.txt
+++ b/tools/perf/Documentation/perf-lock.txt
@@ -216,6 +216,9 @@ CONTENTION OPTIONS
--cgroup-filter=<value>::
Show lock contention only in the given cgroups (comma separated list).
+--duration-filter=<value>::
+ Filter out lock contention samples which durations less than the specified
+ value (default: 0). The unit is nanoseconds (ns).
SEE ALSO
--------
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 05e7bc30488a..d7b454e712bf 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -60,6 +60,7 @@ static int stack_skip = CONTENTION_STACK_SKIP;
static int print_nr_entries = INT_MAX / 2;
static const char *output_name = NULL;
static FILE *lock_output;
+static int duration_filter;
static struct lock_filter filters;
@@ -2004,6 +2005,7 @@ static int __cmd_contention(int argc, const char **argv)
.save_callstack = needs_callstack(),
.owner = show_lock_owner,
.cgroups = RB_ROOT,
+ .duration_filter = duration_filter,
};
lockhash_table = calloc(LOCKHASH_SIZE, sizeof(*lockhash_table));
@@ -2580,6 +2582,7 @@ int cmd_lock(int argc, const char **argv)
OPT_BOOLEAN(0, "lock-cgroup", &show_lock_cgroups, "show lock stats by cgroup"),
OPT_CALLBACK('G', "cgroup-filter", NULL, "CGROUPS",
"Filter specific cgroups", parse_cgroup_filter),
+ OPT_INTEGER(0, "duration-filter", &duration_filter, "Filter samples by duration"),
OPT_PARENT(lock_options)
};
diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c
index 5af8f6d1bc95..7b982a3e4000 100644
--- a/tools/perf/util/bpf_lock_contention.c
+++ b/tools/perf/util/bpf_lock_contention.c
@@ -203,6 +203,7 @@ int lock_contention_prepare(struct lock_contention *con)
skel->rodata->aggr_mode = con->aggr_mode;
skel->rodata->needs_callstack = con->save_callstack;
skel->rodata->lock_owner = con->owner;
+ skel->rodata->duration_filter = con->duration_filter;
if (con->aggr_mode == LOCK_AGGR_CGROUP || con->filters->nr_cgrps) {
if (cgroup_is_v2("perf_event"))
@@ -568,12 +569,23 @@ struct lock_stat *pop_owner_stack_trace(struct lock_contention *con)
if (stack_trace == NULL)
goto out_err;
- if (bpf_map_get_next_key(stacks_fd, NULL, stack_trace))
- goto out_err;
+ /*
+ * `owner_stacks` contains stacks recorded in `contention_begin()` that either never reached
+ * `contention_end()` or were filtered out and not stored in `owner_stat`. We skip if we
+ * cannot find corresponding `contention_data` in `owner_stat` with the given `stack_id`.
+ */
+ while (true) {
+ if (bpf_map_get_next_key(stacks_fd, NULL, stack_trace))
+ goto out_err;
+
+ bpf_map_lookup_elem(stacks_fd, stack_trace, &stack_id);
+ ckey.stack_id = stack_id;
+ if (bpf_map_lookup_elem(stat_fd, &ckey, &cdata) == 0)
+ break;
- bpf_map_lookup_elem(stacks_fd, stack_trace, &stack_id);
- ckey.stack_id = stack_id;
- bpf_map_lookup_elem(stat_fd, &ckey, &cdata);
+ /* Can not find `contention_data`, delete and skip. */
+ bpf_map_delete_elem(stacks_fd, stack_trace);
+ }
st = zalloc(sizeof(struct lock_stat));
if (!st)
diff --git a/tools/perf/util/bpf_skel/lock_contention.bpf.c b/tools/perf/util/bpf_skel/lock_contention.bpf.c
index 69be7a4234e0..26ddc0f21378 100644
--- a/tools/perf/util/bpf_skel/lock_contention.bpf.c
+++ b/tools/perf/util/bpf_skel/lock_contention.bpf.c
@@ -176,6 +176,7 @@ const volatile int stack_skip;
const volatile int lock_owner;
const volatile int use_cgroup_v2;
const volatile int max_stack;
+const volatile int duration_filter;
/* determine the key of lock stat */
const volatile int aggr_mode;
@@ -457,6 +458,9 @@ static inline void update_contention_data(struct contention_data *data, u64 dura
static inline void update_owner_stat(u32 id, u64 duration, u32 flags)
{
+ if (duration < duration_filter)
+ return;
+
struct contention_key key = {
.stack_id = id,
.pid = 0,
@@ -707,6 +711,9 @@ int contention_end(u64 *ctx)
}
}
skip_owner:
+ if (duration < duration_filter)
+ goto out;
+
switch (aggr_mode) {
case LOCK_AGGR_CALLER:
key.stack_id = pelem->stack_id;
diff --git a/tools/perf/util/lock-contention.h b/tools/perf/util/lock-contention.h
index b5d916aa49df..97042e6d8b10 100644
--- a/tools/perf/util/lock-contention.h
+++ b/tools/perf/util/lock-contention.h
@@ -149,6 +149,7 @@ struct lock_contention {
int owner;
int nr_filtered;
bool save_callstack;
+ int duration_filter;
};
struct option;
--
2.49.0.604.gff1f9ca942-goog
next reply other threads:[~2025-04-11 5:26 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-11 5:24 Chun-Tse Shao [this message]
2025-04-11 21:25 ` [PATCH v1] perf lock: Add --duration-filter option Namhyung Kim
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=20250411052548.2089332-1-ctshao@google.com \
--to=ctshao@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=bpf@vger.kernel.org \
--cc=irogers@google.com \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--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=nick.forrington@arm.com \
--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.