X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=tools%2Fperf%2Fbuiltin-kmem.c;h=31f60a2535e0ec95b60e6b90e3e24818fa0dd972;hb=9aad9c0d939e97c144388630a2d3f6918e61f672;hp=5f209514f657262ef6d0f29159733136d37f9c90;hpb=7931241694b25589658b1ceb02218d2750540ae0;p=safe%2Fjmp%2Flinux-2.6 diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 5f20951..31f60a2 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -6,12 +6,12 @@ #include "util/symbol.h" #include "util/thread.h" #include "util/header.h" +#include "util/session.h" #include "util/parse-options.h" #include "util/trace-event.h" #include "util/debug.h" -#include "util/data_map.h" #include @@ -20,9 +20,6 @@ typedef int (*sort_fn_t)(struct alloc_stat *, struct alloc_stat *); static char const *input_name = "perf.data"; -static struct perf_header *header; -static u64 sample_type; - static int alloc_flag; static int caller_flag; @@ -95,23 +92,18 @@ static void setup_cpunode_map(void) if (!dir1) return; - while (true) { - dent1 = readdir(dir1); - if (!dent1) - break; - - if (sscanf(dent1->d_name, "node%u", &mem) < 1) + while ((dent1 = readdir(dir1)) != NULL) { + if (dent1->d_type != DT_DIR || + sscanf(dent1->d_name, "node%u", &mem) < 1) continue; snprintf(buf, PATH_MAX, "%s/%s", PATH_SYS_NODE, dent1->d_name); dir2 = opendir(buf); if (!dir2) continue; - while (true) { - dent2 = readdir(dir2); - if (!dent2) - break; - if (sscanf(dent2->d_name, "cpu%u", &cpu) < 1) + while ((dent2 = readdir(dir2)) != NULL) { + if (dent2->d_type != DT_LNK || + sscanf(dent2->d_name, "cpu%u", &cpu) < 1) continue; cpunode_map[cpu] = mem; } @@ -140,7 +132,7 @@ static void insert_alloc_stat(unsigned long call_site, unsigned long ptr, if (data && data->ptr == ptr) { data->hit++; data->bytes_req += bytes_req; - data->bytes_alloc += bytes_req; + data->bytes_alloc += bytes_alloc; } else { data = malloc(sizeof(*data)); if (!data) @@ -180,7 +172,7 @@ static void insert_caller_stat(unsigned long call_site, if (data && data->call_site == call_site) { data->hit++; data->bytes_req += bytes_req; - data->bytes_alloc += bytes_req; + data->bytes_alloc += bytes_alloc; } else { data = malloc(sizeof(*data)); if (!data) @@ -312,7 +304,7 @@ process_raw_event(event_t *raw_event __used, void *data, } } -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session) { struct sample_data data; struct thread *thread; @@ -322,15 +314,12 @@ static int process_sample_event(event_t *event) data.cpu = -1; data.period = 1; - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); - dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", - event->header.misc, - data.pid, data.tid, - (void *)(long)data.ip, - (long long)data.period); + dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, + data.pid, data.tid, data.ip, data.period); - thread = threads__findnew(event->ip.pid); + thread = perf_session__findnew(session, event->ip.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); @@ -345,35 +334,12 @@ static int process_sample_event(event_t *event) return 0; } -static int sample_type_check(u64 type) -{ - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_RAW)) { - fprintf(stderr, - "No trace sample to read. Did you call perf record " - "without -R?"); - return -1; - } - - return 0; -} - -static struct perf_file_handler file_handler = { - .process_sample_event = process_sample_event, - .process_comm_event = event__process_comm, - .sample_type_check = sample_type_check, +static struct perf_event_ops event_ops = { + .sample = process_sample_event, + .comm = event__process_comm, + .ordered_samples = true, }; -static int read_events(void) -{ - register_idle_thread(); - register_perf_file_handler(&file_handler); - - return mmap_dispatch_perf_file(&header, input_name, 0, 0, - &event__cwdlen, &event__cwd); -} - static double fragmentation(unsigned long n_req, unsigned long n_alloc) { if (n_alloc == 0) @@ -382,39 +348,47 @@ static double fragmentation(unsigned long n_req, unsigned long n_alloc) return 100.0 - (100.0 * n_req / n_alloc); } -static void __print_result(struct rb_root *root, int n_lines, int is_caller) +static void __print_result(struct rb_root *root, struct perf_session *session, + int n_lines, int is_caller) { struct rb_node *next; + struct machine *machine; printf("%.102s\n", graph_dotted_line); printf(" %-34s |", is_caller ? "Callsite": "Alloc Ptr"); - printf(" Total_alloc/Per | Total_req/Per | Hit | Ping-pong | Frag\n"); + printf(" Total_alloc/Per | Total_req/Per | Hit | Ping-pong | Frag\n"); printf("%.102s\n", graph_dotted_line); next = rb_first(root); + machine = perf_session__find_host_machine(session); + if (!machine) { + pr_err("__print_result: couldn't find kernel information\n"); + return; + } while (next && n_lines--) { struct alloc_stat *data = rb_entry(next, struct alloc_stat, node); struct symbol *sym = NULL; + struct map *map; char buf[BUFSIZ]; u64 addr; if (is_caller) { addr = data->call_site; if (!raw_ip) - sym = thread__find_function(kthread, addr, NULL); + sym = machine__find_kernel_function(machine, addr, &map, NULL); } else addr = data->ptr; if (sym != NULL) snprintf(buf, sizeof(buf), "%s+%Lx", sym->name, - addr - sym->start); + addr - map->unmap_ip(map, sym->start)); else snprintf(buf, sizeof(buf), "%#Lx", addr); printf(" %-34s |", buf); - printf(" %9llu/%-5lu | %9llu/%-5lu | %6lu | %8lu | %6.3f%%\n", + printf(" %9llu/%-5lu | %9llu/%-5lu | %8lu | %8lu | %6.3f%%\n", (unsigned long long)data->bytes_alloc, (unsigned long)data->bytes_alloc / data->hit, (unsigned long long)data->bytes_req, @@ -444,12 +418,12 @@ static void print_summary(void) printf("Cross CPU allocations: %lu/%lu\n", nr_cross_allocs, nr_allocs); } -static void print_result(void) +static void print_result(struct perf_session *session) { if (caller_flag) - __print_result(&root_caller_sorted, caller_lines, 1); + __print_result(&root_caller_sorted, session, caller_lines, 1); if (alloc_flag) - __print_result(&root_alloc_sorted, alloc_lines, 0); + __print_result(&root_alloc_sorted, session, alloc_lines, 0); print_summary(); } @@ -517,12 +491,26 @@ static void sort_result(void) static int __cmd_kmem(void) { + int err = -EINVAL; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false); + if (session == NULL) + return -ENOMEM; + + if (perf_session__create_kernel_maps(session) < 0) + goto out_delete; + + if (!perf_session__has_traces(session, "kmem record")) + goto out_delete; + setup_pager(); - read_events(); + err = perf_session__process_events(session, &event_ops); + if (err != 0) + goto out_delete; sort_result(); - print_result(); - - return 0; + print_result(session); +out_delete: + perf_session__delete(session); + return err; } static const char * const kmem_usage[] = { @@ -741,7 +729,6 @@ static const char *record_args[] = { "record", "-a", "-R", - "-M", "-f", "-c", "1", "-e", "kmem:kmalloc", @@ -771,13 +758,13 @@ static int __cmd_record(int argc, const char **argv) int cmd_kmem(int argc, const char **argv, const char *prefix __used) { - symbol__init(0); - argc = parse_options(argc, argv, kmem_options, kmem_usage, 0); if (!argc) usage_with_options(kmem_usage, kmem_options); + symbol__init(); + if (!strncmp(argv[0], "rec", 3)) { return __cmd_record(argc, argv); } else if (!strcmp(argv[0], "stat")) { @@ -789,7 +776,8 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __used) setup_sorting(&alloc_sort, default_sort_order); return __cmd_kmem(); - } + } else + usage_with_options(kmem_usage, kmem_options); return 0; }