diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-08-15 06:06:12 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-08-15 06:06:12 -0400 |
| commit | be750231ce1599b86fbba213e3da8344ece262e2 (patch) | |
| tree | a506c461082692bb5bab8b9bb63a762816329454 /tools/perf | |
| parent | 18408ddc01136f505ae357c03f0d8e50b10e0db6 (diff) | |
| parent | 39e6dd73502f64e2ae3236b304e160ae30de9384 (diff) | |
Merge branch 'perfcounters/urgent' into perfcounters/core
Conflicts:
kernel/perf_counter.c
Merge reason: update to latest upstream (-rc6) and resolve
the conflict with urgent fixes.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/Makefile | 29 | ||||
| -rw-r--r-- | tools/perf/builtin-list.c | 3 | ||||
| -rw-r--r-- | tools/perf/builtin-record.c | 95 | ||||
| -rw-r--r-- | tools/perf/builtin-report.c | 12 | ||||
| -rw-r--r-- | tools/perf/util/callchain.c | 5 | ||||
| -rw-r--r-- | tools/perf/util/parse-events.c | 10 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 17 | ||||
| -rw-r--r-- | tools/perf/util/symbol.h | 24 |
8 files changed, 124 insertions, 71 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index cb9033d3f72f..68218cfd38b3 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
| @@ -386,22 +386,29 @@ endif | |||
| 386 | ifdef NO_DEMANGLE | 386 | ifdef NO_DEMANGLE |
| 387 | BASIC_CFLAGS += -DNO_DEMANGLE | 387 | BASIC_CFLAGS += -DNO_DEMANGLE |
| 388 | else | 388 | else |
| 389 | |||
| 390 | has_bfd := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd > /dev/null 2>&1 && echo y") | 389 | has_bfd := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd > /dev/null 2>&1 && echo y") |
| 391 | 390 | ||
| 392 | has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty > /dev/null 2>&1 && echo y") | ||
| 393 | |||
| 394 | has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty -lz > /dev/null 2>&1 && echo y") | ||
| 395 | |||
| 396 | ifeq ($(has_bfd),y) | 391 | ifeq ($(has_bfd),y) |
| 397 | EXTLIBS += -lbfd | 392 | EXTLIBS += -lbfd |
| 398 | else ifeq ($(has_bfd_iberty),y) | ||
| 399 | EXTLIBS += -lbfd -liberty | ||
| 400 | else ifeq ($(has_bfd_iberty_z),y) | ||
| 401 | EXTLIBS += -lbfd -liberty -lz | ||
| 402 | else | 393 | else |
| 403 | msg := $(warning No bfd.h/libbfd found, install binutils-dev[el] to gain symbol demangling) | 394 | has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty > /dev/null 2>&1 && echo y") |
| 404 | BASIC_CFLAGS += -DNO_DEMANGLE | 395 | ifeq ($(has_bfd_iberty),y) |
| 396 | EXTLIBS += -lbfd -liberty | ||
| 397 | else | ||
| 398 | has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty -lz > /dev/null 2>&1 && echo y") | ||
| 399 | ifeq ($(has_bfd_iberty_z),y) | ||
| 400 | EXTLIBS += -lbfd -liberty -lz | ||
| 401 | else | ||
| 402 | has_cplus_demangle := $(shell sh -c "(echo 'extern char *cplus_demangle(const char *, int);'; echo 'int main(void) { cplus_demangle(0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -liberty > /dev/null 2>&1 && echo y") | ||
| 403 | ifeq ($(has_cplus_demangle),y) | ||
| 404 | EXTLIBS += -liberty | ||
| 405 | BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE | ||
| 406 | else | ||
| 407 | msg := $(warning No bfd.h/libbfd found, install binutils-dev[el] to gain symbol demangling) | ||
| 408 | BASIC_CFLAGS += -DNO_DEMANGLE | ||
| 409 | endif | ||
| 410 | endif | ||
| 411 | endif | ||
| 405 | endif | 412 | endif |
| 406 | endif | 413 | endif |
| 407 | 414 | ||
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index f990fa8a35c9..d88c6961274c 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c | |||
| @@ -10,11 +10,12 @@ | |||
| 10 | 10 | ||
| 11 | #include "perf.h" | 11 | #include "perf.h" |
| 12 | 12 | ||
| 13 | #include "util/parse-options.h" | ||
| 14 | #include "util/parse-events.h" | 13 | #include "util/parse-events.h" |
| 14 | #include "util/cache.h" | ||
| 15 | 15 | ||
| 16 | int cmd_list(int argc __used, const char **argv __used, const char *prefix __used) | 16 | int cmd_list(int argc __used, const char **argv __used, const char *prefix __used) |
| 17 | { | 17 | { |
| 18 | setup_pager(); | ||
| 18 | print_events(); | 19 | print_events(); |
| 19 | return 0; | 20 | return 0; |
| 20 | } | 21 | } |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 106c6abd1c38..65b4115e417d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -35,7 +35,9 @@ static int output; | |||
| 35 | static const char *output_name = "perf.data"; | 35 | static const char *output_name = "perf.data"; |
| 36 | static int group = 0; | 36 | static int group = 0; |
| 37 | static unsigned int realtime_prio = 0; | 37 | static unsigned int realtime_prio = 0; |
| 38 | static int raw_samples = 0; | ||
| 38 | static int system_wide = 0; | 39 | static int system_wide = 0; |
| 40 | static int profile_cpu = -1; | ||
| 39 | static pid_t target_pid = -1; | 41 | static pid_t target_pid = -1; |
| 40 | static int inherit = 1; | 42 | static int inherit = 1; |
| 41 | static int force = 0; | 43 | static int force = 0; |
| @@ -185,46 +187,48 @@ static void sig_atexit(void) | |||
| 185 | kill(getpid(), signr); | 187 | kill(getpid(), signr); |
| 186 | } | 188 | } |
| 187 | 189 | ||
| 188 | static void pid_synthesize_comm_event(pid_t pid, int full) | 190 | static pid_t pid_synthesize_comm_event(pid_t pid, int full) |
| 189 | { | 191 | { |
| 190 | struct comm_event comm_ev; | 192 | struct comm_event comm_ev; |
| 191 | char filename[PATH_MAX]; | 193 | char filename[PATH_MAX]; |
| 192 | char bf[BUFSIZ]; | 194 | char bf[BUFSIZ]; |
| 193 | int fd; | 195 | FILE *fp; |
| 194 | size_t size; | 196 | size_t size = 0; |
| 195 | char *field, *sep; | ||
| 196 | DIR *tasks; | 197 | DIR *tasks; |
| 197 | struct dirent dirent, *next; | 198 | struct dirent dirent, *next; |
| 199 | pid_t tgid = 0; | ||
| 198 | 200 | ||
| 199 | snprintf(filename, sizeof(filename), "/proc/%d/stat", pid); | 201 | snprintf(filename, sizeof(filename), "/proc/%d/status", pid); |
| 200 | 202 | ||
| 201 | fd = open(filename, O_RDONLY); | 203 | fp = fopen(filename, "r"); |
| 202 | if (fd < 0) { | 204 | if (fp == NULL) { |
| 203 | /* | 205 | /* |
| 204 | * We raced with a task exiting - just return: | 206 | * We raced with a task exiting - just return: |
| 205 | */ | 207 | */ |
| 206 | if (verbose) | 208 | if (verbose) |
| 207 | fprintf(stderr, "couldn't open %s\n", filename); | 209 | fprintf(stderr, "couldn't open %s\n", filename); |
| 208 | return; | 210 | return 0; |
| 209 | } | 211 | } |
| 210 | if (read(fd, bf, sizeof(bf)) < 0) { | ||
| 211 | fprintf(stderr, "couldn't read %s\n", filename); | ||
| 212 | exit(EXIT_FAILURE); | ||
| 213 | } | ||
| 214 | close(fd); | ||
| 215 | 212 | ||
| 216 | /* 9027 (cat) R 6747 9027 6747 34816 9027 ... */ | ||
| 217 | memset(&comm_ev, 0, sizeof(comm_ev)); | 213 | memset(&comm_ev, 0, sizeof(comm_ev)); |
| 218 | field = strchr(bf, '('); | 214 | while (!comm_ev.comm[0] || !comm_ev.pid) { |
| 219 | if (field == NULL) | 215 | if (fgets(bf, sizeof(bf), fp) == NULL) |
| 220 | goto out_failure; | 216 | goto out_failure; |
| 221 | sep = strchr(++field, ')'); | 217 | |
| 222 | if (sep == NULL) | 218 | if (memcmp(bf, "Name:", 5) == 0) { |
| 223 | goto out_failure; | 219 | char *name = bf + 5; |
| 224 | size = sep - field; | 220 | while (*name && isspace(*name)) |
| 225 | memcpy(comm_ev.comm, field, size++); | 221 | ++name; |
| 226 | 222 | size = strlen(name) - 1; | |
| 227 | comm_ev.pid = pid; | 223 | memcpy(comm_ev.comm, name, size++); |
| 224 | } else if (memcmp(bf, "Tgid:", 5) == 0) { | ||
| 225 | char *tgids = bf + 5; | ||
| 226 | while (*tgids && isspace(*tgids)) | ||
| 227 | ++tgids; | ||
| 228 | tgid = comm_ev.pid = atoi(tgids); | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 228 | comm_ev.header.type = PERF_EVENT_COMM; | 232 | comm_ev.header.type = PERF_EVENT_COMM; |
| 229 | size = ALIGN(size, sizeof(u64)); | 233 | size = ALIGN(size, sizeof(u64)); |
| 230 | comm_ev.header.size = sizeof(comm_ev) - (sizeof(comm_ev.comm) - size); | 234 | comm_ev.header.size = sizeof(comm_ev) - (sizeof(comm_ev.comm) - size); |
| @@ -233,7 +237,7 @@ static void pid_synthesize_comm_event(pid_t pid, int full) | |||
| 233 | comm_ev.tid = pid; | 237 | comm_ev.tid = pid; |
| 234 | 238 | ||
| 235 | write_output(&comm_ev, comm_ev.header.size); | 239 | write_output(&comm_ev, comm_ev.header.size); |
| 236 | return; | 240 | goto out_fclose; |
| 237 | } | 241 | } |
| 238 | 242 | ||
| 239 | snprintf(filename, sizeof(filename), "/proc/%d/task", pid); | 243 | snprintf(filename, sizeof(filename), "/proc/%d/task", pid); |
| @@ -250,7 +254,10 @@ static void pid_synthesize_comm_event(pid_t pid, int full) | |||
| 250 | write_output(&comm_ev, comm_ev.header.size); | 254 | write_output(&comm_ev, comm_ev.header.size); |
| 251 | } | 255 | } |
| 252 | closedir(tasks); | 256 | closedir(tasks); |
| 253 | return; | 257 | |
| 258 | out_fclose: | ||
| 259 | fclose(fp); | ||
| 260 | return tgid; | ||
| 254 | 261 | ||
| 255 | out_failure: | 262 | out_failure: |
| 256 | fprintf(stderr, "couldn't get COMM and pgid, malformed %s\n", | 263 | fprintf(stderr, "couldn't get COMM and pgid, malformed %s\n", |
| @@ -258,7 +265,7 @@ out_failure: | |||
| 258 | exit(EXIT_FAILURE); | 265 | exit(EXIT_FAILURE); |
| 259 | } | 266 | } |
| 260 | 267 | ||
| 261 | static void pid_synthesize_mmap_samples(pid_t pid) | 268 | static void pid_synthesize_mmap_samples(pid_t pid, pid_t tgid) |
| 262 | { | 269 | { |
| 263 | char filename[PATH_MAX]; | 270 | char filename[PATH_MAX]; |
| 264 | FILE *fp; | 271 | FILE *fp; |
| @@ -310,7 +317,7 @@ static void pid_synthesize_mmap_samples(pid_t pid) | |||
| 310 | mmap_ev.len -= mmap_ev.start; | 317 | mmap_ev.len -= mmap_ev.start; |
| 311 | mmap_ev.header.size = (sizeof(mmap_ev) - | 318 | mmap_ev.header.size = (sizeof(mmap_ev) - |
| 312 | (sizeof(mmap_ev.filename) - size)); | 319 | (sizeof(mmap_ev.filename) - size)); |
| 313 | mmap_ev.pid = pid; | 320 | mmap_ev.pid = tgid; |
| 314 | mmap_ev.tid = pid; | 321 | mmap_ev.tid = pid; |
| 315 | 322 | ||
| 316 | write_output(&mmap_ev, mmap_ev.header.size); | 323 | write_output(&mmap_ev, mmap_ev.header.size); |
| @@ -329,14 +336,14 @@ static void synthesize_all(void) | |||
| 329 | 336 | ||
| 330 | while (!readdir_r(proc, &dirent, &next) && next) { | 337 | while (!readdir_r(proc, &dirent, &next) && next) { |
| 331 | char *end; | 338 | char *end; |
| 332 | pid_t pid; | 339 | pid_t pid, tgid; |
| 333 | 340 | ||
| 334 | pid = strtol(dirent.d_name, &end, 10); | 341 | pid = strtol(dirent.d_name, &end, 10); |
| 335 | if (*end) /* only interested in proper numerical dirents */ | 342 | if (*end) /* only interested in proper numerical dirents */ |
| 336 | continue; | 343 | continue; |
| 337 | 344 | ||
| 338 | pid_synthesize_comm_event(pid, 1); | 345 | tgid = pid_synthesize_comm_event(pid, 1); |
| 339 | pid_synthesize_mmap_samples(pid); | 346 | pid_synthesize_mmap_samples(pid, tgid); |
| 340 | } | 347 | } |
| 341 | 348 | ||
| 342 | closedir(proc); | 349 | closedir(proc); |
| @@ -374,7 +381,7 @@ static void create_counter(int counter, int cpu, pid_t pid) | |||
| 374 | PERF_FORMAT_TOTAL_TIME_RUNNING | | 381 | PERF_FORMAT_TOTAL_TIME_RUNNING | |
| 375 | PERF_FORMAT_ID; | 382 | PERF_FORMAT_ID; |
| 376 | 383 | ||
| 377 | attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; | 384 | attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID; |
| 378 | 385 | ||
| 379 | if (freq) { | 386 | if (freq) { |
| 380 | attr->sample_type |= PERF_SAMPLE_PERIOD; | 387 | attr->sample_type |= PERF_SAMPLE_PERIOD; |
| @@ -394,6 +401,8 @@ static void create_counter(int counter, int cpu, pid_t pid) | |||
| 394 | if (call_graph) | 401 | if (call_graph) |
| 395 | attr->sample_type |= PERF_SAMPLE_CALLCHAIN; | 402 | attr->sample_type |= PERF_SAMPLE_CALLCHAIN; |
| 396 | 403 | ||
| 404 | if (raw_samples) | ||
| 405 | attr->sample_type |= PERF_SAMPLE_RAW; | ||
| 397 | 406 | ||
| 398 | attr->mmap = track; | 407 | attr->mmap = track; |
| 399 | attr->comm = track; | 408 | attr->comm = track; |
| @@ -408,6 +417,8 @@ try_again: | |||
| 408 | 417 | ||
| 409 | if (err == EPERM) | 418 | if (err == EPERM) |
| 410 | die("Permission error - are you root?\n"); | 419 | die("Permission error - are you root?\n"); |
| 420 | else if (err == ENODEV && profile_cpu != -1) | ||
| 421 | die("No such device - did you specify an out-of-range profile CPU?\n"); | ||
| 411 | 422 | ||
| 412 | /* | 423 | /* |
| 413 | * If it's cycles then fall back to hrtimer | 424 | * If it's cycles then fall back to hrtimer |
| @@ -541,16 +552,22 @@ static int __cmd_record(int argc, const char **argv) | |||
| 541 | if (pid == -1) | 552 | if (pid == -1) |
| 542 | pid = getpid(); | 553 | pid = getpid(); |
| 543 | 554 | ||
| 544 | open_counters(-1, pid); | 555 | open_counters(profile_cpu, pid); |
| 545 | } else for (i = 0; i < nr_cpus; i++) | 556 | } else { |
| 546 | open_counters(i, target_pid); | 557 | if (profile_cpu != -1) { |
| 558 | open_counters(profile_cpu, target_pid); | ||
| 559 | } else { | ||
| 560 | for (i = 0; i < nr_cpus; i++) | ||
| 561 | open_counters(i, target_pid); | ||
| 562 | } | ||
| 563 | } | ||
| 547 | 564 | ||
| 548 | if (file_new) | 565 | if (file_new) |
| 549 | perf_header__write(header, output); | 566 | perf_header__write(header, output); |
| 550 | 567 | ||
| 551 | if (!system_wide) { | 568 | if (!system_wide) { |
| 552 | pid_synthesize_comm_event(pid, 0); | 569 | pid_t tgid = pid_synthesize_comm_event(pid, 0); |
| 553 | pid_synthesize_mmap_samples(pid); | 570 | pid_synthesize_mmap_samples(pid, tgid); |
| 554 | } else | 571 | } else |
| 555 | synthesize_all(); | 572 | synthesize_all(); |
| 556 | 573 | ||
| @@ -618,10 +635,14 @@ static const struct option options[] = { | |||
| 618 | "record events on existing pid"), | 635 | "record events on existing pid"), |
| 619 | OPT_INTEGER('r', "realtime", &realtime_prio, | 636 | OPT_INTEGER('r', "realtime", &realtime_prio, |
| 620 | "collect data with this RT SCHED_FIFO priority"), | 637 | "collect data with this RT SCHED_FIFO priority"), |
| 638 | OPT_BOOLEAN('R', "raw-samples", &raw_samples, | ||
| 639 | "collect raw sample records from all opened counters"), | ||
| 621 | OPT_BOOLEAN('a', "all-cpus", &system_wide, | 640 | OPT_BOOLEAN('a', "all-cpus", &system_wide, |
| 622 | "system-wide collection from all CPUs"), | 641 | "system-wide collection from all CPUs"), |
| 623 | OPT_BOOLEAN('A', "append", &append_file, | 642 | OPT_BOOLEAN('A', "append", &append_file, |
| 624 | "append to the output file to do incremental profiling"), | 643 | "append to the output file to do incremental profiling"), |
| 644 | OPT_INTEGER('C', "profile_cpu", &profile_cpu, | ||
| 645 | "CPU to profile on"), | ||
| 625 | OPT_BOOLEAN('f', "force", &force, | 646 | OPT_BOOLEAN('f', "force", &force, |
| 626 | "overwrite existing data file"), | 647 | "overwrite existing data file"), |
| 627 | OPT_LONG('c', "count", &default_interval, | 648 | OPT_LONG('c', "count", &default_interval, |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 93945ecdac86..6321951fe1bf 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -1276,11 +1276,11 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
| 1276 | more_data += sizeof(u64); | 1276 | more_data += sizeof(u64); |
| 1277 | } | 1277 | } |
| 1278 | 1278 | ||
| 1279 | dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d: %p period: %Ld\n", | 1279 | dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n", |
| 1280 | (void *)(offset + head), | 1280 | (void *)(offset + head), |
| 1281 | (void *)(long)(event->header.size), | 1281 | (void *)(long)(event->header.size), |
| 1282 | event->header.misc, | 1282 | event->header.misc, |
| 1283 | event->ip.pid, | 1283 | event->ip.pid, event->ip.tid, |
| 1284 | (void *)(long)ip, | 1284 | (void *)(long)ip, |
| 1285 | (long long)period); | 1285 | (long long)period); |
| 1286 | 1286 | ||
| @@ -1340,10 +1340,11 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
| 1340 | if (show & show_mask) { | 1340 | if (show & show_mask) { |
| 1341 | struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip); | 1341 | struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip); |
| 1342 | 1342 | ||
| 1343 | if (dso_list && dso && dso->name && !strlist__has_entry(dso_list, dso->name)) | 1343 | if (dso_list && (!dso || !dso->name || |
| 1344 | !strlist__has_entry(dso_list, dso->name))) | ||
| 1344 | return 0; | 1345 | return 0; |
| 1345 | 1346 | ||
| 1346 | if (sym_list && sym && !strlist__has_entry(sym_list, sym->name)) | 1347 | if (sym_list && (!sym || !strlist__has_entry(sym_list, sym->name))) |
| 1347 | return 0; | 1348 | return 0; |
| 1348 | 1349 | ||
| 1349 | if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) { | 1350 | if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) { |
| @@ -1362,10 +1363,11 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head) | |||
| 1362 | struct thread *thread = threads__findnew(event->mmap.pid); | 1363 | struct thread *thread = threads__findnew(event->mmap.pid); |
| 1363 | struct map *map = map__new(&event->mmap, cwd, cwdlen); | 1364 | struct map *map = map__new(&event->mmap, cwd, cwdlen); |
| 1364 | 1365 | ||
| 1365 | dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n", | 1366 | dprintf("%p [%p]: PERF_EVENT_MMAP %d/%d: [%p(%p) @ %p]: %s\n", |
| 1366 | (void *)(offset + head), | 1367 | (void *)(offset + head), |
| 1367 | (void *)(long)(event->header.size), | 1368 | (void *)(long)(event->header.size), |
| 1368 | event->mmap.pid, | 1369 | event->mmap.pid, |
| 1370 | event->mmap.tid, | ||
| 1369 | (void *)(long)event->mmap.start, | 1371 | (void *)(long)event->mmap.start, |
| 1370 | (void *)(long)event->mmap.len, | 1372 | (void *)(long)event->mmap.len, |
| 1371 | (void *)(long)event->mmap.pgoff, | 1373 | (void *)(long)event->mmap.pgoff, |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index a8e67aa9ef49..011473411642 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <stdio.h> | 13 | #include <stdio.h> |
| 14 | #include <stdbool.h> | 14 | #include <stdbool.h> |
| 15 | #include <errno.h> | 15 | #include <errno.h> |
| 16 | #include <math.h> | ||
| 16 | 17 | ||
| 17 | #include "callchain.h" | 18 | #include "callchain.h" |
| 18 | 19 | ||
| @@ -112,7 +113,7 @@ static void __sort_chain_graph_rel(struct callchain_node *node, | |||
| 112 | u64 min_hit; | 113 | u64 min_hit; |
| 113 | 114 | ||
| 114 | node->rb_root = RB_ROOT; | 115 | node->rb_root = RB_ROOT; |
| 115 | min_hit = node->children_hit * min_percent / 100.0; | 116 | min_hit = ceil(node->children_hit * min_percent); |
| 116 | 117 | ||
| 117 | chain_for_each_child(child, node) { | 118 | chain_for_each_child(child, node) { |
| 118 | __sort_chain_graph_rel(child, min_percent); | 119 | __sort_chain_graph_rel(child, min_percent); |
| @@ -126,7 +127,7 @@ static void | |||
| 126 | sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_node *chain_root, | 127 | sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_node *chain_root, |
| 127 | u64 min_hit __used, struct callchain_param *param) | 128 | u64 min_hit __used, struct callchain_param *param) |
| 128 | { | 129 | { |
| 129 | __sort_chain_graph_rel(chain_root, param->min_percent); | 130 | __sort_chain_graph_rel(chain_root, param->min_percent / 100.0); |
| 130 | rb_root->rb_node = chain_root->rb_root.rb_node; | 131 | rb_root->rb_node = chain_root->rb_root.rb_node; |
| 131 | } | 132 | } |
| 132 | 133 | ||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 4858d83b3b67..044178408783 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
| @@ -379,6 +379,7 @@ static int parse_tracepoint_event(const char **strp, | |||
| 379 | struct perf_counter_attr *attr) | 379 | struct perf_counter_attr *attr) |
| 380 | { | 380 | { |
| 381 | const char *evt_name; | 381 | const char *evt_name; |
| 382 | char *flags; | ||
| 382 | char sys_name[MAX_EVENT_LENGTH]; | 383 | char sys_name[MAX_EVENT_LENGTH]; |
| 383 | char id_buf[4]; | 384 | char id_buf[4]; |
| 384 | int fd; | 385 | int fd; |
| @@ -400,6 +401,15 @@ static int parse_tracepoint_event(const char **strp, | |||
| 400 | strncpy(sys_name, *strp, sys_length); | 401 | strncpy(sys_name, *strp, sys_length); |
| 401 | sys_name[sys_length] = '\0'; | 402 | sys_name[sys_length] = '\0'; |
| 402 | evt_name = evt_name + 1; | 403 | evt_name = evt_name + 1; |
| 404 | |||
| 405 | flags = strchr(evt_name, ':'); | ||
| 406 | if (flags) { | ||
| 407 | *flags = '\0'; | ||
| 408 | flags++; | ||
| 409 | if (!strncmp(flags, "record", strlen(flags))) | ||
| 410 | attr->sample_type |= PERF_SAMPLE_RAW; | ||
| 411 | } | ||
| 412 | |||
| 403 | evt_length = strlen(evt_name); | 413 | evt_length = strlen(evt_name); |
| 404 | if (evt_length >= MAX_EVENT_LENGTH) | 414 | if (evt_length >= MAX_EVENT_LENGTH) |
| 405 | return 0; | 415 | return 0; |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e9b13b414955..0b9862351260 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -7,23 +7,8 @@ | |||
| 7 | #include <gelf.h> | 7 | #include <gelf.h> |
| 8 | #include <elf.h> | 8 | #include <elf.h> |
| 9 | 9 | ||
| 10 | #ifndef NO_DEMANGLE | ||
| 11 | #include <bfd.h> | ||
| 12 | #else | ||
| 13 | static inline | ||
| 14 | char *bfd_demangle(void __used *v, const char __used *c, int __used i) | ||
| 15 | { | ||
| 16 | return NULL; | ||
| 17 | } | ||
| 18 | #endif | ||
| 19 | |||
| 20 | const char *sym_hist_filter; | 10 | const char *sym_hist_filter; |
| 21 | 11 | ||
| 22 | #ifndef DMGL_PARAMS | ||
| 23 | #define DMGL_PARAMS (1 << 0) /* Include function args */ | ||
| 24 | #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ | ||
| 25 | #endif | ||
| 26 | |||
| 27 | enum dso_origin { | 12 | enum dso_origin { |
| 28 | DSO__ORIG_KERNEL = 0, | 13 | DSO__ORIG_KERNEL = 0, |
| 29 | DSO__ORIG_JAVA_JIT, | 14 | DSO__ORIG_JAVA_JIT, |
| @@ -816,6 +801,8 @@ more: | |||
| 816 | } | 801 | } |
| 817 | out: | 802 | out: |
| 818 | free(name); | 803 | free(name); |
| 804 | if (ret < 0 && strstr(self->name, " (deleted)") != NULL) | ||
| 805 | return 0; | ||
| 819 | return ret; | 806 | return ret; |
| 820 | } | 807 | } |
| 821 | 808 | ||
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 50f723571241..48b8e5759af9 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -8,6 +8,30 @@ | |||
| 8 | #include "module.h" | 8 | #include "module.h" |
| 9 | #include "event.h" | 9 | #include "event.h" |
| 10 | 10 | ||
| 11 | #ifdef HAVE_CPLUS_DEMANGLE | ||
| 12 | extern char *cplus_demangle(const char *, int); | ||
| 13 | |||
| 14 | static inline char *bfd_demangle(void __used *v, const char *c, int i) | ||
| 15 | { | ||
| 16 | return cplus_demangle(c, i); | ||
| 17 | } | ||
| 18 | #else | ||
| 19 | #ifdef NO_DEMANGLE | ||
| 20 | static inline char *bfd_demangle(void __used *v, const char __used *c, | ||
| 21 | int __used i) | ||
| 22 | { | ||
| 23 | return NULL; | ||
| 24 | } | ||
| 25 | #else | ||
| 26 | #include <bfd.h> | ||
| 27 | #endif | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #ifndef DMGL_PARAMS | ||
| 31 | #define DMGL_PARAMS (1 << 0) /* Include function args */ | ||
| 32 | #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ | ||
| 33 | #endif | ||
| 34 | |||
| 11 | struct symbol { | 35 | struct symbol { |
| 12 | struct rb_node rb_node; | 36 | struct rb_node rb_node; |
| 13 | u64 start; | 37 | u64 start; |
