Skip to content

Commit 16cad1d

Browse files
namhyungacmel
authored andcommitted
perf lock contention: Use lock_stat_find{,new}
This is a preparation work to support complex keys of BPF maps. Now it has single value key according to the aggregation mode like stack_id or pid. But we want to use a combination of those keys. Then lock_contention_read() should still aggregate the result based on the key that was requested by user. The other key info will be used for filtering. So instead of creating a lock_stat entry always, Check if it's already there using lock_stat_find() first. Signed-off-by: Namhyung Kim <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Hao Luo <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Juri Lelli <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Song Liu <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 492fef2 commit 16cad1d

File tree

4 files changed

+34
-19
lines changed

4 files changed

+34
-19
lines changed

tools/perf/builtin-lock.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ static struct lock_stat *pop_from_result(void)
465465
return container_of(node, struct lock_stat, rb);
466466
}
467467

468-
static struct lock_stat *lock_stat_find(u64 addr)
468+
struct lock_stat *lock_stat_find(u64 addr)
469469
{
470470
struct hlist_head *entry = lockhashentry(addr);
471471
struct lock_stat *ret;
@@ -477,7 +477,7 @@ static struct lock_stat *lock_stat_find(u64 addr)
477477
return NULL;
478478
}
479479

480-
static struct lock_stat *lock_stat_findnew(u64 addr, const char *name, int flags)
480+
struct lock_stat *lock_stat_findnew(u64 addr, const char *name, int flags)
481481
{
482482
struct hlist_head *entry = lockhashentry(addr);
483483
struct lock_stat *ret, *new;

tools/perf/util/Build

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,10 @@ perf-$(CONFIG_PERF_BPF_SKEL) += bpf_counter.o
154154
perf-$(CONFIG_PERF_BPF_SKEL) += bpf_counter_cgroup.o
155155
perf-$(CONFIG_PERF_BPF_SKEL) += bpf_ftrace.o
156156
perf-$(CONFIG_PERF_BPF_SKEL) += bpf_off_cpu.o
157-
perf-$(CONFIG_PERF_BPF_SKEL) += bpf_lock_contention.o
157+
158+
ifeq ($(CONFIG_LIBTRACEEVENT),y)
159+
perf-$(CONFIG_PERF_BPF_SKEL) += bpf_lock_contention.o
160+
endif
158161

159162
ifeq ($(CONFIG_LIBTRACEEVENT),y)
160163
perf-$(CONFIG_PERF_BPF_SKEL) += bpf_kwork.o

tools/perf/util/bpf_lock_contention.c

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,34 @@ int lock_contention_read(struct lock_contention *con)
256256
prev_key = NULL;
257257
while (!bpf_map_get_next_key(fd, prev_key, &key)) {
258258
s32 stack_id;
259+
const char *name;
259260

260261
/* to handle errors in the loop body */
261262
err = -1;
262263

263264
bpf_map_lookup_elem(fd, &key, &data);
264-
st = zalloc(sizeof(*st));
265+
266+
if (con->save_callstack) {
267+
stack_id = key.aggr_key;
268+
bpf_map_lookup_elem(stack, &stack_id, stack_trace);
269+
}
270+
271+
st = lock_stat_find(key.aggr_key);
272+
if (st != NULL) {
273+
st->wait_time_total += data.total_time;
274+
if (st->wait_time_max < data.max_time)
275+
st->wait_time_max = data.max_time;
276+
if (st->wait_time_min > data.min_time)
277+
st->wait_time_min = data.min_time;
278+
279+
st->nr_contended += data.count;
280+
if (st->nr_contended)
281+
st->avg_wait_time = st->wait_time_total / st->nr_contended;
282+
goto next;
283+
}
284+
285+
name = lock_contention_get_name(con, &key, stack_trace);
286+
st = lock_stat_findnew(key.aggr_key, name, data.flags);
265287
if (st == NULL)
266288
break;
267289

@@ -274,34 +296,21 @@ int lock_contention_read(struct lock_contention *con)
274296
st->avg_wait_time = data.total_time / data.count;
275297

276298
st->flags = data.flags;
277-
st->addr = key.aggr_key;
278-
279-
stack_id = key.aggr_key;
280-
bpf_map_lookup_elem(stack, &stack_id, stack_trace);
281-
282-
st->name = strdup(lock_contention_get_name(con, &key, stack_trace));
283-
if (st->name == NULL)
284-
break;
285299

286300
if (con->save_callstack) {
287301
st->callstack = memdup(stack_trace, stack_size);
288302
if (st->callstack == NULL)
289303
break;
290304
}
291305

292-
hlist_add_head(&st->hash_entry, con->result);
306+
next:
293307
prev_key = &key;
294308

295-
/* we're fine now, reset the values */
296-
st = NULL;
309+
/* we're fine now, reset the error */
297310
err = 0;
298311
}
299312

300313
free(stack_trace);
301-
if (st) {
302-
free(st->name);
303-
free(st);
304-
}
305314

306315
return err;
307316
}

tools/perf/util/lock-contention.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ struct lock_stat {
6565
*/
6666
#define MAX_LOCK_DEPTH 48
6767

68+
struct lock_stat *lock_stat_find(u64 addr);
69+
struct lock_stat *lock_stat_findnew(u64 addr, const char *name, int flags);
70+
6871
/*
6972
* struct lock_seq_stat:
7073
* Place to put on state of one lock sequence

0 commit comments

Comments
 (0)