diff options
| -rw-r--r-- | tools/perf/builtin-probe.c | 19 | ||||
| -rw-r--r-- | tools/perf/builtin-record.c | 4 | ||||
| -rw-r--r-- | tools/perf/util/build-id.c | 8 | ||||
| -rw-r--r-- | tools/perf/util/event.c | 31 | ||||
| -rw-r--r-- | tools/perf/util/evlist.c | 6 | ||||
| -rw-r--r-- | tools/perf/util/evlist.h | 9 | ||||
| -rw-r--r-- | tools/perf/util/header.c | 5 | ||||
| -rw-r--r-- | tools/perf/util/machine.c | 4 | ||||
| -rw-r--r-- | tools/perf/util/machine.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/probe-event.c | 5 | ||||
| -rw-r--r-- | tools/perf/util/probe-event.h | 6 |
11 files changed, 61 insertions, 37 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 921bb6942503..f7b1af67e9f6 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
| @@ -56,6 +56,7 @@ static struct { | |||
| 56 | bool mod_events; | 56 | bool mod_events; |
| 57 | bool uprobes; | 57 | bool uprobes; |
| 58 | bool quiet; | 58 | bool quiet; |
| 59 | bool target_used; | ||
| 59 | int nevents; | 60 | int nevents; |
| 60 | struct perf_probe_event events[MAX_PROBES]; | 61 | struct perf_probe_event events[MAX_PROBES]; |
| 61 | struct strlist *dellist; | 62 | struct strlist *dellist; |
| @@ -78,6 +79,12 @@ static int parse_probe_event(const char *str) | |||
| 78 | } | 79 | } |
| 79 | 80 | ||
| 80 | pev->uprobes = params.uprobes; | 81 | pev->uprobes = params.uprobes; |
| 82 | if (params.target) { | ||
| 83 | pev->target = strdup(params.target); | ||
| 84 | if (!pev->target) | ||
| 85 | return -ENOMEM; | ||
| 86 | params.target_used = true; | ||
| 87 | } | ||
| 81 | 88 | ||
| 82 | /* Parse a perf-probe command into event */ | 89 | /* Parse a perf-probe command into event */ |
| 83 | ret = parse_perf_probe_command(str, pev); | 90 | ret = parse_perf_probe_command(str, pev); |
| @@ -102,6 +109,7 @@ static int set_target(const char *ptr) | |||
| 102 | params.target = strdup(ptr); | 109 | params.target = strdup(ptr); |
| 103 | if (!params.target) | 110 | if (!params.target) |
| 104 | return -ENOMEM; | 111 | return -ENOMEM; |
| 112 | params.target_used = false; | ||
| 105 | 113 | ||
| 106 | found = 1; | 114 | found = 1; |
| 107 | buf = ptr + (strlen(ptr) - 3); | 115 | buf = ptr + (strlen(ptr) - 3); |
| @@ -178,7 +186,7 @@ static int opt_set_target(const struct option *opt, const char *str, | |||
| 178 | int ret = -ENOENT; | 186 | int ret = -ENOENT; |
| 179 | char *tmp; | 187 | char *tmp; |
| 180 | 188 | ||
| 181 | if (str && !params.target) { | 189 | if (str) { |
| 182 | if (!strcmp(opt->long_name, "exec")) | 190 | if (!strcmp(opt->long_name, "exec")) |
| 183 | params.uprobes = true; | 191 | params.uprobes = true; |
| 184 | #ifdef HAVE_DWARF_SUPPORT | 192 | #ifdef HAVE_DWARF_SUPPORT |
| @@ -200,7 +208,9 @@ static int opt_set_target(const struct option *opt, const char *str, | |||
| 200 | if (!tmp) | 208 | if (!tmp) |
| 201 | return -ENOMEM; | 209 | return -ENOMEM; |
| 202 | } | 210 | } |
| 211 | free(params.target); | ||
| 203 | params.target = tmp; | 212 | params.target = tmp; |
| 213 | params.target_used = false; | ||
| 204 | ret = 0; | 214 | ret = 0; |
| 205 | } | 215 | } |
| 206 | 216 | ||
| @@ -485,9 +495,14 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 485 | } | 495 | } |
| 486 | 496 | ||
| 487 | if (params.nevents) { | 497 | if (params.nevents) { |
| 498 | /* Ensure the last given target is used */ | ||
| 499 | if (params.target && !params.target_used) { | ||
| 500 | pr_warning(" Error: -x/-m must follow the probe definitions.\n"); | ||
| 501 | usage_with_options(probe_usage, options); | ||
| 502 | } | ||
| 503 | |||
| 488 | ret = add_perf_probe_events(params.events, params.nevents, | 504 | ret = add_perf_probe_events(params.events, params.nevents, |
| 489 | params.max_probe_points, | 505 | params.max_probe_points, |
| 490 | params.target, | ||
| 491 | params.force_add); | 506 | params.force_add); |
| 492 | if (ret < 0) { | 507 | if (ret < 0) { |
| 493 | pr_err_with_code(" Error: Failed to add events.", ret); | 508 | pr_err_with_code(" Error: Failed to add events.", ret); |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index ac610488d2e1..c3efdfb630b5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -70,8 +70,8 @@ static int process_synthesized_event(struct perf_tool *tool, | |||
| 70 | static int record__mmap_read(struct record *rec, int idx) | 70 | static int record__mmap_read(struct record *rec, int idx) |
| 71 | { | 71 | { |
| 72 | struct perf_mmap *md = &rec->evlist->mmap[idx]; | 72 | struct perf_mmap *md = &rec->evlist->mmap[idx]; |
| 73 | unsigned int head = perf_mmap__read_head(md); | 73 | u64 head = perf_mmap__read_head(md); |
| 74 | unsigned int old = md->prev; | 74 | u64 old = md->prev; |
| 75 | unsigned char *data = md->base + page_size; | 75 | unsigned char *data = md->base + page_size; |
| 76 | unsigned long size; | 76 | unsigned long size; |
| 77 | void *buf; | 77 | void *buf; |
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index f7fb2587df69..61867dff5d5a 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
| @@ -59,12 +59,8 @@ static int perf_event__exit_del_thread(struct perf_tool *tool __maybe_unused, | |||
| 59 | dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid, | 59 | dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid, |
| 60 | event->fork.ppid, event->fork.ptid); | 60 | event->fork.ppid, event->fork.ptid); |
| 61 | 61 | ||
| 62 | if (thread) { | 62 | if (thread) |
| 63 | rb_erase(&thread->rb_node, &machine->threads); | 63 | machine__remove_thread(machine, thread); |
| 64 | if (machine->last_match == thread) | ||
| 65 | thread__zput(machine->last_match); | ||
| 66 | thread__put(thread); | ||
| 67 | } | ||
| 68 | 64 | ||
| 69 | return 0; | 65 | return 0; |
| 70 | } | 66 | } |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 5516236df6ab..ff866c4d2e2f 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
| @@ -183,8 +183,18 @@ static int perf_event__synthesize_fork(struct perf_tool *tool, | |||
| 183 | { | 183 | { |
| 184 | memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); | 184 | memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); |
| 185 | 185 | ||
| 186 | event->fork.ppid = ppid; | 186 | /* |
| 187 | event->fork.ptid = ppid; | 187 | * for main thread set parent to ppid from status file. For other |
| 188 | * threads set parent pid to main thread. ie., assume main thread | ||
| 189 | * spawns all threads in a process | ||
| 190 | */ | ||
| 191 | if (tgid == pid) { | ||
| 192 | event->fork.ppid = ppid; | ||
| 193 | event->fork.ptid = ppid; | ||
| 194 | } else { | ||
| 195 | event->fork.ppid = tgid; | ||
| 196 | event->fork.ptid = tgid; | ||
| 197 | } | ||
| 188 | event->fork.pid = tgid; | 198 | event->fork.pid = tgid; |
| 189 | event->fork.tid = pid; | 199 | event->fork.tid = pid; |
| 190 | event->fork.header.type = PERF_RECORD_FORK; | 200 | event->fork.header.type = PERF_RECORD_FORK; |
| @@ -377,6 +387,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, | |||
| 377 | DIR *tasks; | 387 | DIR *tasks; |
| 378 | struct dirent dirent, *next; | 388 | struct dirent dirent, *next; |
| 379 | pid_t tgid, ppid; | 389 | pid_t tgid, ppid; |
| 390 | int rc = 0; | ||
| 380 | 391 | ||
| 381 | /* special case: only send one comm event using passed in pid */ | 392 | /* special case: only send one comm event using passed in pid */ |
| 382 | if (!full) { | 393 | if (!full) { |
| @@ -404,38 +415,38 @@ static int __event__synthesize_thread(union perf_event *comm_event, | |||
| 404 | 415 | ||
| 405 | while (!readdir_r(tasks, &dirent, &next) && next) { | 416 | while (!readdir_r(tasks, &dirent, &next) && next) { |
| 406 | char *end; | 417 | char *end; |
| 407 | int rc = 0; | ||
| 408 | pid_t _pid; | 418 | pid_t _pid; |
| 409 | 419 | ||
| 410 | _pid = strtol(dirent.d_name, &end, 10); | 420 | _pid = strtol(dirent.d_name, &end, 10); |
| 411 | if (*end) | 421 | if (*end) |
| 412 | continue; | 422 | continue; |
| 413 | 423 | ||
| 424 | rc = -1; | ||
| 414 | if (perf_event__prepare_comm(comm_event, _pid, machine, | 425 | if (perf_event__prepare_comm(comm_event, _pid, machine, |
| 415 | &tgid, &ppid) != 0) | 426 | &tgid, &ppid) != 0) |
| 416 | return -1; | 427 | break; |
| 417 | 428 | ||
| 418 | if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, | 429 | if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, |
| 419 | ppid, process, machine) < 0) | 430 | ppid, process, machine) < 0) |
| 420 | return -1; | 431 | break; |
| 421 | /* | 432 | /* |
| 422 | * Send the prepared comm event | 433 | * Send the prepared comm event |
| 423 | */ | 434 | */ |
| 424 | if (process(tool, comm_event, &synth_sample, machine) != 0) | 435 | if (process(tool, comm_event, &synth_sample, machine) != 0) |
| 425 | return -1; | 436 | break; |
| 426 | 437 | ||
| 438 | rc = 0; | ||
| 427 | if (_pid == pid) { | 439 | if (_pid == pid) { |
| 428 | /* process the parent's maps too */ | 440 | /* process the parent's maps too */ |
| 429 | rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, | 441 | rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, |
| 430 | process, machine, mmap_data); | 442 | process, machine, mmap_data); |
| 443 | if (rc) | ||
| 444 | break; | ||
| 431 | } | 445 | } |
| 432 | |||
| 433 | if (rc) | ||
| 434 | return rc; | ||
| 435 | } | 446 | } |
| 436 | 447 | ||
| 437 | closedir(tasks); | 448 | closedir(tasks); |
| 438 | return 0; | 449 | return rc; |
| 439 | } | 450 | } |
| 440 | 451 | ||
| 441 | int perf_event__synthesize_thread_map(struct perf_tool *tool, | 452 | int perf_event__synthesize_thread_map(struct perf_tool *tool, |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 76ef7ee62640..080be93eea96 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -634,8 +634,8 @@ static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, | |||
| 634 | union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) | 634 | union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) |
| 635 | { | 635 | { |
| 636 | struct perf_mmap *md = &evlist->mmap[idx]; | 636 | struct perf_mmap *md = &evlist->mmap[idx]; |
| 637 | unsigned int head = perf_mmap__read_head(md); | 637 | u64 head = perf_mmap__read_head(md); |
| 638 | unsigned int old = md->prev; | 638 | u64 old = md->prev; |
| 639 | unsigned char *data = md->base + page_size; | 639 | unsigned char *data = md->base + page_size; |
| 640 | union perf_event *event = NULL; | 640 | union perf_event *event = NULL; |
| 641 | 641 | ||
| @@ -716,7 +716,7 @@ void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) | |||
| 716 | struct perf_mmap *md = &evlist->mmap[idx]; | 716 | struct perf_mmap *md = &evlist->mmap[idx]; |
| 717 | 717 | ||
| 718 | if (!evlist->overwrite) { | 718 | if (!evlist->overwrite) { |
| 719 | unsigned int old = md->prev; | 719 | u64 old = md->prev; |
| 720 | 720 | ||
| 721 | perf_mmap__write_tail(md, old); | 721 | perf_mmap__write_tail(md, old); |
| 722 | } | 722 | } |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index fb19c47b8aac..b5cce95d644e 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
| @@ -27,7 +27,7 @@ struct perf_mmap { | |||
| 27 | void *base; | 27 | void *base; |
| 28 | int mask; | 28 | int mask; |
| 29 | int refcnt; | 29 | int refcnt; |
| 30 | unsigned int prev; | 30 | u64 prev; |
| 31 | char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8))); | 31 | char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8))); |
| 32 | }; | 32 | }; |
| 33 | 33 | ||
| @@ -189,16 +189,15 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp); | |||
| 189 | int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); | 189 | int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); |
| 190 | int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size); | 190 | int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size); |
| 191 | 191 | ||
| 192 | static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) | 192 | static inline u64 perf_mmap__read_head(struct perf_mmap *mm) |
| 193 | { | 193 | { |
| 194 | struct perf_event_mmap_page *pc = mm->base; | 194 | struct perf_event_mmap_page *pc = mm->base; |
| 195 | int head = ACCESS_ONCE(pc->data_head); | 195 | u64 head = ACCESS_ONCE(pc->data_head); |
| 196 | rmb(); | 196 | rmb(); |
| 197 | return head; | 197 | return head; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | static inline void perf_mmap__write_tail(struct perf_mmap *md, | 200 | static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) |
| 201 | unsigned long tail) | ||
| 202 | { | 201 | { |
| 203 | struct perf_event_mmap_page *pc = md->base; | 202 | struct perf_event_mmap_page *pc = md->base; |
| 204 | 203 | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index fff3b2a455ae..918fd8ae2d80 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -2504,8 +2504,11 @@ int perf_session__read_header(struct perf_session *session) | |||
| 2504 | if (read_attr(fd, header, &f_attr) < 0) | 2504 | if (read_attr(fd, header, &f_attr) < 0) |
| 2505 | goto out_errno; | 2505 | goto out_errno; |
| 2506 | 2506 | ||
| 2507 | if (header->needs_swap) | 2507 | if (header->needs_swap) { |
| 2508 | f_attr.ids.size = bswap_64(f_attr.ids.size); | ||
| 2509 | f_attr.ids.offset = bswap_64(f_attr.ids.offset); | ||
| 2508 | perf_event__attr_swap(&f_attr.attr); | 2510 | perf_event__attr_swap(&f_attr.attr); |
| 2511 | } | ||
| 2509 | 2512 | ||
| 2510 | tmp = lseek(fd, 0, SEEK_CUR); | 2513 | tmp = lseek(fd, 0, SEEK_CUR); |
| 2511 | evsel = perf_evsel__new(&f_attr.attr); | 2514 | evsel = perf_evsel__new(&f_attr.attr); |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 9c380a2caa54..527e032e24f6 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
| @@ -14,8 +14,6 @@ | |||
| 14 | #include "unwind.h" | 14 | #include "unwind.h" |
| 15 | #include "linux/hash.h" | 15 | #include "linux/hash.h" |
| 16 | 16 | ||
| 17 | static void machine__remove_thread(struct machine *machine, struct thread *th); | ||
| 18 | |||
| 19 | static void dsos__init(struct dsos *dsos) | 17 | static void dsos__init(struct dsos *dsos) |
| 20 | { | 18 | { |
| 21 | INIT_LIST_HEAD(&dsos->head); | 19 | INIT_LIST_HEAD(&dsos->head); |
| @@ -1256,7 +1254,7 @@ out_problem: | |||
| 1256 | return 0; | 1254 | return 0; |
| 1257 | } | 1255 | } |
| 1258 | 1256 | ||
| 1259 | static void machine__remove_thread(struct machine *machine, struct thread *th) | 1257 | void machine__remove_thread(struct machine *machine, struct thread *th) |
| 1260 | { | 1258 | { |
| 1261 | if (machine->last_match == th) | 1259 | if (machine->last_match == th) |
| 1262 | thread__zput(machine->last_match); | 1260 | thread__zput(machine->last_match); |
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index e2faf3b47e7b..6d64cedb9d1e 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h | |||
| @@ -120,6 +120,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid); | |||
| 120 | void machine__exit(struct machine *machine); | 120 | void machine__exit(struct machine *machine); |
| 121 | void machine__delete_threads(struct machine *machine); | 121 | void machine__delete_threads(struct machine *machine); |
| 122 | void machine__delete(struct machine *machine); | 122 | void machine__delete(struct machine *machine); |
| 123 | void machine__remove_thread(struct machine *machine, struct thread *th); | ||
| 123 | 124 | ||
| 124 | struct branch_info *sample__resolve_bstack(struct perf_sample *sample, | 125 | struct branch_info *sample__resolve_bstack(struct perf_sample *sample, |
| 125 | struct addr_location *al); | 126 | struct addr_location *al); |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index b78851732a71..30545ce2c712 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
| @@ -1906,6 +1906,7 @@ void clear_perf_probe_event(struct perf_probe_event *pev) | |||
| 1906 | 1906 | ||
| 1907 | free(pev->event); | 1907 | free(pev->event); |
| 1908 | free(pev->group); | 1908 | free(pev->group); |
| 1909 | free(pev->target); | ||
| 1909 | clear_perf_probe_point(&pev->point); | 1910 | clear_perf_probe_point(&pev->point); |
| 1910 | 1911 | ||
| 1911 | for (i = 0; i < pev->nargs; i++) { | 1912 | for (i = 0; i < pev->nargs; i++) { |
| @@ -2654,7 +2655,7 @@ struct __event_package { | |||
| 2654 | }; | 2655 | }; |
| 2655 | 2656 | ||
| 2656 | int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | 2657 | int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, |
| 2657 | int max_tevs, const char *target, bool force_add) | 2658 | int max_tevs, bool force_add) |
| 2658 | { | 2659 | { |
| 2659 | int i, j, ret; | 2660 | int i, j, ret; |
| 2660 | struct __event_package *pkgs; | 2661 | struct __event_package *pkgs; |
| @@ -2678,7 +2679,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | |||
| 2678 | ret = convert_to_probe_trace_events(pkgs[i].pev, | 2679 | ret = convert_to_probe_trace_events(pkgs[i].pev, |
| 2679 | &pkgs[i].tevs, | 2680 | &pkgs[i].tevs, |
| 2680 | max_tevs, | 2681 | max_tevs, |
| 2681 | target); | 2682 | pkgs[i].pev->target); |
| 2682 | if (ret < 0) | 2683 | if (ret < 0) |
| 2683 | goto end; | 2684 | goto end; |
| 2684 | pkgs[i].ntevs = ret; | 2685 | pkgs[i].ntevs = ret; |
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index e01e9943139f..d6b783447be9 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h | |||
| @@ -73,7 +73,8 @@ struct perf_probe_event { | |||
| 73 | char *group; /* Group name */ | 73 | char *group; /* Group name */ |
| 74 | struct perf_probe_point point; /* Probe point */ | 74 | struct perf_probe_point point; /* Probe point */ |
| 75 | int nargs; /* Number of arguments */ | 75 | int nargs; /* Number of arguments */ |
| 76 | bool uprobes; | 76 | bool uprobes; /* Uprobe event flag */ |
| 77 | char *target; /* Target binary */ | ||
| 77 | struct perf_probe_arg *args; /* Arguments */ | 78 | struct perf_probe_arg *args; /* Arguments */ |
| 78 | }; | 79 | }; |
| 79 | 80 | ||
| @@ -124,8 +125,7 @@ extern int line_range__init(struct line_range *lr); | |||
| 124 | extern const char *kernel_get_module_path(const char *module); | 125 | extern const char *kernel_get_module_path(const char *module); |
| 125 | 126 | ||
| 126 | extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | 127 | extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, |
| 127 | int max_probe_points, const char *module, | 128 | int max_probe_points, bool force_add); |
| 128 | bool force_add); | ||
| 129 | extern int del_perf_probe_events(struct strlist *dellist); | 129 | extern int del_perf_probe_events(struct strlist *dellist); |
| 130 | extern int show_perf_probe_events(void); | 130 | extern int show_perf_probe_events(void); |
| 131 | extern int show_line_range(struct line_range *lr, const char *module, | 131 | extern int show_line_range(struct line_range *lr, const char *module, |
