machine: Adopt is_lock_function() from builtin-lock.c
authorArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 6 Dec 2022 16:49:04 +0000 (13:49 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 14 Dec 2022 14:16:12 +0000 (11:16 -0300)
It is used in bpf_lock_contention.c and builtin-lock.c will be made
CONFIG_LIBTRACEEVENT=y conditional, so move it to machine.c, that is
always available.

This makes those 4 global variables for sched and lock text start and
end to move to 'struct machine' too, as conceivably we can have that
info for several machine instances, say some 'perf diff' like tool.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: bpf@vger.kernel.org
Link: http://lore.kernel.org/lkml/
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/lock-contention.h
tools/perf/util/machine.c
tools/perf/util/machine.h

index 0d280093b19a55d4b413f301be304116a7ebcd69..15ce6358f12799e05fd8c6e7ed7fedd90a46a9ac 100644 (file)
@@ -67,11 +67,6 @@ static enum {
        LOCK_AGGR_CALLER,
 } aggr_mode = LOCK_AGGR_ADDR;
 
-static u64 sched_text_start;
-static u64 sched_text_end;
-static u64 lock_text_start;
-static u64 lock_text_end;
-
 static struct thread_stat *thread_stat_find(u32 tid)
 {
        struct rb_node *node;
@@ -854,55 +849,6 @@ end:
        return 0;
 }
 
-bool is_lock_function(struct machine *machine, u64 addr)
-{
-       if (!sched_text_start) {
-               struct map *kmap;
-               struct symbol *sym;
-
-               sym = machine__find_kernel_symbol_by_name(machine,
-                                                         "__sched_text_start",
-                                                         &kmap);
-               if (!sym) {
-                       /* to avoid retry */
-                       sched_text_start = 1;
-                       return false;
-               }
-
-               sched_text_start = kmap->unmap_ip(kmap, sym->start);
-
-               /* should not fail from here */
-               sym = machine__find_kernel_symbol_by_name(machine,
-                                                         "__sched_text_end",
-                                                         &kmap);
-               sched_text_end = kmap->unmap_ip(kmap, sym->start);
-
-               sym = machine__find_kernel_symbol_by_name(machine,
-                                                         "__lock_text_start",
-                                                         &kmap);
-               lock_text_start = kmap->unmap_ip(kmap, sym->start);
-
-               sym = machine__find_kernel_symbol_by_name(machine,
-                                                         "__lock_text_end",
-                                                         &kmap);
-               lock_text_end = kmap->unmap_ip(kmap, sym->start);
-       }
-
-       /* failed to get kernel symbols */
-       if (sched_text_start == 1)
-               return false;
-
-       /* mutex and rwsem functions are in sched text section */
-       if (sched_text_start <= addr && addr < sched_text_end)
-               return true;
-
-       /* spinlock functions are in lock text section */
-       if (lock_text_start <= addr && addr < lock_text_end)
-               return true;
-
-       return false;
-}
-
 static int get_symbol_name_offset(struct map *map, struct symbol *sym, u64 ip,
                                  char *buf, int size)
 {
@@ -961,7 +907,7 @@ static int lock_contention_caller(struct evsel *evsel, struct perf_sample *sampl
                        goto next;
 
                sym = node->ms.sym;
-               if (sym && !is_lock_function(machine, node->ip)) {
+               if (sym && !machine__is_lock_function(machine, node->ip)) {
                        get_symbol_name_offset(node->ms.map, sym, node->ip,
                                               buf, size);
                        return 0;
@@ -1007,7 +953,7 @@ static u64 callchain_id(struct evsel *evsel, struct perf_sample *sample)
                if (++skip <= stack_skip)
                        goto next;
 
-               if (node->ms.sym && is_lock_function(machine, node->ip))
+               if (node->ms.sym && machine__is_lock_function(machine, node->ip))
                        goto next;
 
                hash ^= hash_long((unsigned long)node->ip, 64);
index 4db9ad3d50c41ac78aa85105fe7d5c3256cea61d..f4ebb9a2e3809a7f2af652cbaf211ffd8cad2124 100644 (file)
@@ -153,7 +153,7 @@ int lock_contention_read(struct lock_contention *con)
                bpf_map_lookup_elem(stack, &key, stack_trace);
 
                /* skip lock internal functions */
-               while (is_lock_function(machine, stack_trace[idx]) &&
+               while (machine__is_lock_function(machine, stack_trace[idx]) &&
                       idx < con->max_stack - 1)
                        idx++;
 
index e3c061b1795ba37784949d7f4bafcfd6bf4f916d..a2346875098dca030e0e4a64929e360cca5c4376 100644 (file)
@@ -145,6 +145,4 @@ static inline int lock_contention_read(struct lock_contention *con __maybe_unuse
 
 #endif  /* HAVE_BPF_SKEL */
 
-bool is_lock_function(struct machine *machine, u64 addr);
-
 #endif  /* PERF_LOCK_CONTENTION_H */
index 76316e459c3de9c42fd141dcac01d706cf7cc041..803c9d1803dd26ef6d4a296fb66ba3c9de9fca3a 100644 (file)
@@ -3336,3 +3336,43 @@ int machine__for_each_kernel_map(struct machine *machine, machine__map_t fn, voi
        }
        return err;
 }
+
+bool machine__is_lock_function(struct machine *machine, u64 addr)
+{
+       if (!machine->sched.text_start) {
+               struct map *kmap;
+               struct symbol *sym = machine__find_kernel_symbol_by_name(machine, "__sched_text_start", &kmap);
+
+               if (!sym) {
+                       /* to avoid retry */
+                       machine->sched.text_start = 1;
+                       return false;
+               }
+
+               machine->sched.text_start = kmap->unmap_ip(kmap, sym->start);
+
+               /* should not fail from here */
+               sym = machine__find_kernel_symbol_by_name(machine, "__sched_text_end", &kmap);
+               machine->sched.text_end = kmap->unmap_ip(kmap, sym->start);
+
+               sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_start", &kmap);
+               machine->lock.text_start = kmap->unmap_ip(kmap, sym->start);
+
+               sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_end", &kmap);
+               machine->lock.text_end = kmap->unmap_ip(kmap, sym->start);
+       }
+
+       /* failed to get kernel symbols */
+       if (machine->sched.text_start == 1)
+               return false;
+
+       /* mutex and rwsem functions are in sched text section */
+       if (machine->sched.text_start <= addr && addr < machine->sched.text_end)
+               return true;
+
+       /* spinlock functions are in lock text section */
+       if (machine->lock.text_start <= addr && addr < machine->lock.text_end)
+               return true;
+
+       return false;
+}
index 6267c1d6f2321128cc75ed10424bf5831fcf89a4..d034ecaf89c193ea3a16bee3378bbca185422d04 100644 (file)
@@ -56,6 +56,10 @@ struct machine {
        struct maps       *kmaps;
        struct map        *vmlinux_map;
        u64               kernel_start;
+       struct {
+               u64       text_start;
+               u64       text_end;
+       } sched, lock;
        pid_t             *current_tid;
        size_t            current_tid_sz;
        union { /* Tool specific area */
@@ -212,6 +216,7 @@ static inline bool machine__is_host(struct machine *machine)
        return machine ? machine->pid == HOST_KERNEL_ID : false;
 }
 
+bool machine__is_lock_function(struct machine *machine, u64 addr);
 bool machine__is(struct machine *machine, const char *arch);
 bool machine__normalized_is(struct machine *machine, const char *arch);
 int machine__nr_cpus_avail(struct machine *machine);