diff options
Diffstat (limited to 'tools/perf/builtin-kmem.c')
| -rw-r--r-- | tools/perf/builtin-kmem.c | 73 |
1 files changed, 42 insertions, 31 deletions
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 8ae0a1535293..7929a5fa5f46 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "builtin.h" -#include "perf.h" #include "util/dso.h" #include "util/evlist.h" @@ -24,6 +23,7 @@ #include "util/debug.h" #include "util/string2.h" +#include "util/util.h" #include <linux/kernel.h> #include <linux/numa.h> @@ -36,7 +36,7 @@ #include <regex.h> #include <linux/ctype.h> -#include <traceevent/event-parse.h> +#include <event-parse.h> static int kmem_slab; static int kmem_page; @@ -399,21 +399,29 @@ static u64 find_callsite(struct evsel *evsel, struct perf_sample *sample) struct addr_location al; struct machine *machine = &kmem_session->machines.host; struct callchain_cursor_node *node; + struct callchain_cursor *cursor; + u64 result = sample->ip; + addr_location__init(&al); if (alloc_func_list == NULL) { if (build_alloc_func_list() < 0) goto out; } al.thread = machine__findnew_thread(machine, sample->pid, sample->tid); - sample__resolve_callchain(sample, &callchain_cursor, NULL, evsel, &al, 16); - callchain_cursor_commit(&callchain_cursor); + cursor = get_tls_callchain_cursor(); + if (cursor == NULL) + goto out; + + sample__resolve_callchain(sample, cursor, NULL, evsel, &al, 16); + + callchain_cursor_commit(cursor); while (true) { struct alloc_func key, *caller; u64 addr; - node = callchain_cursor_current(&callchain_cursor); + node = callchain_cursor_current(cursor); if (node == NULL) break; @@ -423,20 +431,22 @@ static u64 find_callsite(struct evsel *evsel, struct perf_sample *sample) if (!caller) { /* found */ if (node->ms.map) - addr = map__unmap_ip(node->ms.map, node->ip); + addr = map__dso_unmap_ip(node->ms.map, node->ip); else addr = node->ip; - return addr; + result = addr; + goto out; } else pr_debug3("skipping alloc function: %s\n", caller->name); - callchain_cursor_advance(&callchain_cursor); + callchain_cursor_advance(cursor); } -out: pr_debug2("unknown callsite: %"PRIx64 "\n", sample->ip); - return sample->ip; +out: + addr_location__exit(&al); + return result; } struct sort_dimension { @@ -653,7 +663,6 @@ static const struct { { "__GFP_HIGHMEM", "HM" }, { "GFP_DMA32", "D32" }, { "__GFP_HIGH", "H" }, - { "__GFP_ATOMIC", "_A" }, { "__GFP_IO", "I" }, { "__GFP_FS", "F" }, { "__GFP_NOWARN", "NWR" }, @@ -752,6 +761,7 @@ static int parse_gfp_flags(struct evsel *evsel, struct perf_sample *sample, }; struct trace_seq seq; char *str, *pos = NULL; + const struct tep_event *tp_format; if (nr_gfps) { struct gfp_flag key = { @@ -763,8 +773,9 @@ static int parse_gfp_flags(struct evsel *evsel, struct perf_sample *sample, } trace_seq_init(&seq); - tep_print_event(evsel->tp_format->tep, - &seq, &record, "%s", TEP_PRINT_INFO); + tp_format = evsel__tp_format(evsel); + if (tp_format) + tep_print_event(tp_format->tep, &seq, &record, "%s", TEP_PRINT_INFO); str = strtok_r(seq.buffer, " ", &pos); while (str) { @@ -946,7 +957,7 @@ static bool perf_kmem__skip_sample(struct perf_sample *sample) typedef int (*tracepoint_handler)(struct evsel *evsel, struct perf_sample *sample); -static int process_sample_event(struct perf_tool *tool __maybe_unused, +static int process_sample_event(const struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct evsel *evsel, @@ -965,7 +976,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, if (perf_kmem__skip_sample(sample)) return 0; - dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid); + dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread__tid(thread)); if (evsel->handler != NULL) { tracepoint_handler f = evsel->handler; @@ -977,15 +988,6 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, return err; } -static struct perf_tool perf_kmem = { - .sample = process_sample_event, - .comm = perf_event__process_comm, - .mmap = perf_event__process_mmap, - .mmap2 = perf_event__process_mmap2, - .namespaces = perf_event__process_namespaces, - .ordered_events = true, -}; - static double fragmentation(unsigned long n_req, unsigned long n_alloc) { if (n_alloc == 0) @@ -1025,7 +1027,7 @@ static void __print_slab_result(struct rb_root *root, if (sym != NULL) snprintf(buf, sizeof(buf), "%s+%" PRIx64 "", sym->name, - addr - map->unmap_ip(map, sym->start)); + addr - map__unmap_ip(map, sym->start)); else snprintf(buf, sizeof(buf), "%#" PRIx64 "", addr); printf(" %-34s |", buf); @@ -1399,7 +1401,7 @@ static int __cmd_kmem(struct perf_session *session) } evlist__for_each_entry(session->evlist, evsel) { - if (!strcmp(evsel__name(evsel), "kmem:mm_page_alloc") && + if (evsel__name_is(evsel, "kmem:mm_page_alloc") && evsel__field(evsel, "pfn")) { use_pfn = true; break; @@ -1962,6 +1964,7 @@ int cmd_kmem(int argc, const char **argv) NULL }; struct perf_session *session; + struct perf_tool perf_kmem; static const char errmsg[] = "No %s allocation events found. Have you run 'perf kmem record --%s'?\n"; int ret = perf_config(kmem_config, NULL); @@ -1989,6 +1992,13 @@ int cmd_kmem(int argc, const char **argv) data.path = input_name; + perf_tool__init(&perf_kmem, /*ordered_events=*/true); + perf_kmem.sample = process_sample_event; + perf_kmem.comm = perf_event__process_comm; + perf_kmem.mmap = perf_event__process_mmap; + perf_kmem.mmap2 = perf_event__process_mmap2; + perf_kmem.namespaces = perf_event__process_namespaces; + kmem_session = session = perf_session__new(&data, &perf_kmem); if (IS_ERR(session)) return PTR_ERR(session); @@ -2004,17 +2014,17 @@ int cmd_kmem(int argc, const char **argv) if (kmem_page) { struct evsel *evsel = evlist__find_tracepoint_by_name(session->evlist, "kmem:mm_page_alloc"); + const struct tep_event *tp_format = evsel ? evsel__tp_format(evsel) : NULL; - if (evsel == NULL) { + if (tp_format == NULL) { pr_err(errmsg, "page", "page"); goto out_delete; } - - kmem_page_size = tep_get_page_size(evsel->tp_format->tep); + kmem_page_size = tep_get_page_size(tp_format->tep); symbol_conf.use_callchain = true; } - symbol__init(&session->header.env); + symbol__init(perf_session__env(session)); if (perf_time__parse_str(&ptime, time_str) != 0) { pr_err("Invalid time string\n"); @@ -2049,7 +2059,8 @@ int cmd_kmem(int argc, const char **argv) out_delete: perf_session__delete(session); + /* free usage string allocated by parse_options_subcommand */ + free((void *)kmem_usage[0]); return ret; } - |
