summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuchit Karunakaran <suchitkarunakaran@gmail.com>2026-05-31 01:29:40 +0530
committerArnaldo Carvalho de Melo <acme@redhat.com>2026-06-04 17:34:52 -0300
commit824b18f607d82503a956d3e00f9e9c0b24efcbca (patch)
tree14cfeb668702e0d1c5f26548dd61b3e012670f85
parentbe694c488a1e96e728517b26de9f15fed56b2e74 (diff)
downloadlinux-824b18f607d82503a956d3e00f9e9c0b24efcbca.tar.gz
linux-824b18f607d82503a956d3e00f9e9c0b24efcbca.zip
perf lock contention: Enable end-timestamp accounting for cgroup aggregation
update_lock_stat() handles lock contentions that start but never reach a contention_end event (e.g., locks still held when profiling stops), but previously treated LOCK_AGGR_CGROUP as a no-op due to missing cgroup context in userspace. Fix this by adding a cgroup_id field to struct tstamp_data, recording it at contention_begin using get_current_cgroup_id() when aggr_mode is LOCK_AGGR_CGROUP. Capturing it at contention_begin is semantically correct, the contention cost is incurred by the task that had to wait, not by whatever task happens to be running at contention_end. It is also preferable from a performance standpoint, as contention_end runs just before the task enters the critical section. Update contention_end to use pelem->cgroup_id instead of calling get_current_cgroup_id() dynamically, ensuring both complete and incomplete contention events attribute the wait time to the cgroup at wait-start time consistently. Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Suchit Karunakaran <suchitkarunakaran@gmail.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Tycho Andersen (AMD) <tycho@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/bpf_lock_contention.c4
-rw-r--r--tools/perf/util/bpf_skel/lock_contention.bpf.c4
-rw-r--r--tools/perf/util/bpf_skel/lock_data.h1
3 files changed, 6 insertions, 3 deletions
diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c
index eb8e29b8064b..b1cfa63a488f 100644
--- a/tools/perf/util/bpf_lock_contention.c
+++ b/tools/perf/util/bpf_lock_contention.c
@@ -470,8 +470,8 @@ static void update_lock_stat(int map_fd, int pid, u64 end_ts,
stat_key.lock_addr_or_cgroup = ts_data->lock;
break;
case LOCK_AGGR_CGROUP:
- /* TODO */
- return;
+ stat_key.lock_addr_or_cgroup = ts_data->cgroup_id;
+ break;
default:
return;
}
diff --git a/tools/perf/util/bpf_skel/lock_contention.bpf.c b/tools/perf/util/bpf_skel/lock_contention.bpf.c
index d4186ae9f85c..0d9c6f55050e 100644
--- a/tools/perf/util/bpf_skel/lock_contention.bpf.c
+++ b/tools/perf/util/bpf_skel/lock_contention.bpf.c
@@ -597,6 +597,8 @@ int contention_begin(u64 *ctx)
pelem->timestamp = bpf_ktime_get_ns();
pelem->lock = (__u64)ctx[0];
pelem->flags = (__u32)ctx[1];
+ if (aggr_mode == LOCK_AGGR_CGROUP)
+ pelem->cgroup_id = get_current_cgroup_id();
if (needs_callstack) {
u32 i = 0;
@@ -832,7 +834,7 @@ skip_owner:
key.stack_id = pelem->stack_id;
break;
case LOCK_AGGR_CGROUP:
- key.lock_addr_or_cgroup = get_current_cgroup_id();
+ key.lock_addr_or_cgroup = pelem->cgroup_id;
break;
default:
/* should not happen */
diff --git a/tools/perf/util/bpf_skel/lock_data.h b/tools/perf/util/bpf_skel/lock_data.h
index 28c5e5aced7f..652e114e6b87 100644
--- a/tools/perf/util/bpf_skel/lock_data.h
+++ b/tools/perf/util/bpf_skel/lock_data.h
@@ -13,6 +13,7 @@ struct owner_tracing_data {
struct tstamp_data {
u64 timestamp;
u64 lock;
+ u64 cgroup_id;
u32 flags;
s32 stack_id;
};