perf lock contention: Add data failure stat
authorNamhyung Kim <namhyung@kernel.org>
Thu, 6 Apr 2023 21:06:08 +0000 (14:06 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 7 Apr 2023 00:52:31 +0000 (21:52 -0300)
It's possible to fail to update the data when the lock_stat map is full.
We should check that case and show the number at the end.

  $ sudo ./perf lock con -ablv -E3 -- ./perf bench sched messaging
  ...
   contended   total wait     max wait     avg wait            address   symbol

        6157    208.48 ms     69.29 us     33.86 us   ffff934c001c1f00    (spinlock)
        4030     72.04 ms     61.84 us     17.88 us   ffff934c000415c0    (spinlock)
        3201     50.30 ms     47.73 us     15.71 us   ffff934c2eead850    (spinlock)

  === output for debug ===

  bad: 0, total: 13388
  bad rate: 0.00 %
  histogram of failure reasons
         task: 0
        stack: 0
         time: 0
         data: 0      <----- added

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Hao Luo <haoluo@google.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: bpf@vger.kernel.org
Link: https://lore.kernel.org/r/20230406210611.1622492-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-lock.c
tools/perf/util/bpf_lock_contention.c
tools/perf/util/bpf_skel/lock_contention.bpf.c
tools/perf/util/lock-contention.h

index 9b92c7a5aefb59f9eb65df779ffb8daa0ff5cd48..01b318d6c80a3cee4e5dc523450f02122b63ff5f 100644 (file)
@@ -1626,7 +1626,7 @@ static void sort_contention_result(void)
 static void print_bpf_events(int total, struct lock_contention_fails *fails)
 {
        /* Output for debug, this have to be removed */
-       int broken = fails->task + fails->stack + fails->time;
+       int broken = fails->task + fails->stack + fails->time + fails->data;
 
        if (quiet || total == 0 || (broken == 0 && verbose <= 0))
                return;
@@ -1640,7 +1640,9 @@ static void print_bpf_events(int total, struct lock_contention_fails *fails)
        pr_info(" %10s: %d\n", "task", fails->task);
        pr_info(" %10s: %d\n", "stack", fails->stack);
        pr_info(" %10s: %d\n", "time", fails->time);
+       pr_info(" %10s: %d\n", "data", fails->data);
 }
+
 static void print_contention_result(struct lock_contention *con)
 {
        struct lock_stat *st;
index 8a5d0eb441898e9a6a50ad2e663e4549fd2d4ba1..0071058ac3d2b573252b077186728dad596ef07c 100644 (file)
@@ -262,6 +262,7 @@ int lock_contention_read(struct lock_contention *con)
        con->fails.task = skel->bss->task_fail;
        con->fails.stack = skel->bss->stack_fail;
        con->fails.time = skel->bss->time_fail;
+       con->fails.data = skel->bss->data_fail;
 
        stack_trace = zalloc(stack_size);
        if (stack_trace == NULL)
index f9d2d792ccc83724ea4a76dfd68465f6b353e6e5..cb87c98e53408d2e695ef34088a955a624792c89 100644 (file)
@@ -124,6 +124,7 @@ int aggr_mode;
 int task_fail;
 int stack_fail;
 int time_fail;
+int data_fail;
 
 static inline int can_record(u64 *ctx)
 {
@@ -380,7 +381,8 @@ int contention_end(u64 *ctx)
                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);
+               if (bpf_map_update_elem(&lock_stat, &key, &first, BPF_NOEXIST) < 0)
+                       __sync_fetch_and_add(&data_fail, 1);
                bpf_map_delete_elem(&tstamp, &pid);
                return 0;
        }
index 10c28302420cecdbfcea4301fbfd4da3bebc58de..3ed1cad370fca0fbcdf24225286a2c5a233a51b8 100644 (file)
@@ -126,6 +126,7 @@ struct lock_contention_fails {
        int task;
        int stack;
        int time;
+       int data;
 };
 
 struct lock_contention {