perf lock contention: Track and show mmap_lock with address
Sometimes there are severe contentions on the mmap_lock and we want see it in the -l/--lock-addr output. However it cannot symbolize the mmap_lock because it's allocated dynamically without symbols. Stephane and Hao gave me an idea separately to display mmap_lock by following the current->mm pointer. I added a flag to mark mmap_lock after comparing the lock address so that it can show them differently. With this change it can show mmap_lock like below: $ sudo ./perf lock con -abl -- sleep 10 contended total wait max wait avg wait address symbol ... 16344 312.30 ms 2.22 ms 19.11 us ffff8cc702595640 17686 310.08 ms 1.49 ms 17.53 us ffff8cc7025952c0 3 84.14 ms 45.79 ms 28.05 ms ffff8cc78114c478 mmap_lock 3557 76.80 ms 68.75 us 21.59 us ffff8cc77ca3af58 1 68.27 ms 68.27 ms 68.27 ms ffff8cda745dfd70 9 54.53 ms 7.96 ms 6.06 ms ffff8cc7642a48b8 mmap_lock 14629 44.01 ms 60.00 us 3.01 us ffff8cc7625f9ca0 3481 42.63 ms 140.71 us 12.24 us ffffffff937906ac vmap_area_lock 16194 38.73 ms 42.15 us 2.39 us ffff8cd397cbc560 11 38.44 ms 10.39 ms 3.49 ms ffff8ccd6d12fbb8 mmap_lock 1 5.43 ms 5.43 ms 5.43 ms ffff8cd70018f0d8 1674 5.38 ms 422.93 us 3.21 us ffffffff92e06080 tasklist_lock 581 4.51 ms 130.68 us 7.75 us ffff8cc9b1259058 5 3.52 ms 1.27 ms 703.23 us ffff8cc754510070 112 3.47 ms 56.47 us 31.02 us ffff8ccee38b3120 381 3.31 ms 73.44 us 8.69 us ffffffff93790690 purge_vmap_area_lock 255 3.19 ms 36.35 us 12.49 us ffff8d053ce30c80 Note that mmap_lock was renamed some time ago and it needs to support old kernels with a different name 'mmap_sem'. Suggested-by: Hao Luo <haoluo@google.com> Suggested-by: Stephane Eranian <eranian@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Juri Lelli <juri.lelli@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Song Liu <song@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Waiman Long <longman@redhat.com> Cc: Will Deacon <will@kernel.org> Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20230313204825.2665483-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
8d98ca5c02
commit
3ace2435bb
|
@ -1663,7 +1663,7 @@ static void print_contention_result(struct lock_contention *con)
|
|||
break;
|
||||
case LOCK_AGGR_ADDR:
|
||||
pr_info(" %016llx %s\n", (unsigned long long)st->addr,
|
||||
st->name ? : "");
|
||||
(st->flags & LCD_F_MMAP_LOCK) ? "mmap_lock" : st->name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -92,6 +92,14 @@ struct rw_semaphore___new {
|
|||
atomic_long_t owner;
|
||||
} __attribute__((preserve_access_index));
|
||||
|
||||
struct mm_struct___old {
|
||||
struct rw_semaphore mmap_sem;
|
||||
} __attribute__((preserve_access_index));
|
||||
|
||||
struct mm_struct___new {
|
||||
struct rw_semaphore mmap_lock;
|
||||
} __attribute__((preserve_access_index));
|
||||
|
||||
/* control flags */
|
||||
int enabled;
|
||||
int has_cpu;
|
||||
|
@ -210,6 +218,36 @@ static inline struct task_struct *get_lock_owner(__u64 lock, __u32 flags)
|
|||
return task;
|
||||
}
|
||||
|
||||
static inline __u32 check_lock_type(__u64 lock, __u32 flags)
|
||||
{
|
||||
struct task_struct *curr;
|
||||
struct mm_struct___old *mm_old;
|
||||
struct mm_struct___new *mm_new;
|
||||
|
||||
switch (flags) {
|
||||
case LCB_F_READ: /* rwsem */
|
||||
case LCB_F_WRITE:
|
||||
curr = bpf_get_current_task_btf();
|
||||
if (curr->mm == NULL)
|
||||
break;
|
||||
mm_new = (void *)curr->mm;
|
||||
if (bpf_core_field_exists(mm_new->mmap_lock)) {
|
||||
if (&mm_new->mmap_lock == (void *)lock)
|
||||
return LCD_F_MMAP_LOCK;
|
||||
break;
|
||||
}
|
||||
mm_old = (void *)curr->mm;
|
||||
if (bpf_core_field_exists(mm_old->mmap_sem)) {
|
||||
if (&mm_old->mmap_sem == (void *)lock)
|
||||
return LCD_F_MMAP_LOCK;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("tp_btf/contention_begin")
|
||||
int contention_begin(u64 *ctx)
|
||||
{
|
||||
|
@ -320,6 +358,9 @@ int contention_end(u64 *ctx)
|
|||
.flags = pelem->flags,
|
||||
};
|
||||
|
||||
if (aggr_mode == LOCK_AGGR_ADDR)
|
||||
first.flags |= check_lock_type(pelem->lock, pelem->flags);
|
||||
|
||||
bpf_map_update_elem(&lock_stat, &key, &first, BPF_NOEXIST);
|
||||
bpf_map_delete_elem(&tstamp, &pid);
|
||||
return 0;
|
||||
|
|
|
@ -15,6 +15,12 @@ struct contention_task_data {
|
|||
char comm[TASK_COMM_LEN];
|
||||
};
|
||||
|
||||
/*
|
||||
* Upper bits of the flags in the contention_data are used to identify
|
||||
* some well-known locks which do not have symbols (non-global locks).
|
||||
*/
|
||||
#define LCD_F_MMAP_LOCK (1U << 31)
|
||||
|
||||
struct contention_data {
|
||||
u64 total_time;
|
||||
u64 min_time;
|
||||
|
|
Loading…
Reference in New Issue