diff options
| -rw-r--r-- | tools/perf/util/thread-stack.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c index e3f7dfecafa9..c091635bf7dc 100644 --- a/tools/perf/util/thread-stack.c +++ b/tools/perf/util/thread-stack.c | |||
| @@ -357,7 +357,7 @@ void call_return_processor__free(struct call_return_processor *crp) | |||
| 357 | 357 | ||
| 358 | static int thread_stack__push_cp(struct thread_stack *ts, u64 ret_addr, | 358 | static int thread_stack__push_cp(struct thread_stack *ts, u64 ret_addr, |
| 359 | u64 timestamp, u64 ref, struct call_path *cp, | 359 | u64 timestamp, u64 ref, struct call_path *cp, |
| 360 | bool no_call) | 360 | bool no_call, bool trace_end) |
| 361 | { | 361 | { |
| 362 | struct thread_stack_entry *tse; | 362 | struct thread_stack_entry *tse; |
| 363 | int err; | 363 | int err; |
| @@ -375,6 +375,7 @@ static int thread_stack__push_cp(struct thread_stack *ts, u64 ret_addr, | |||
| 375 | tse->branch_count = ts->branch_count; | 375 | tse->branch_count = ts->branch_count; |
| 376 | tse->cp = cp; | 376 | tse->cp = cp; |
| 377 | tse->no_call = no_call; | 377 | tse->no_call = no_call; |
| 378 | tse->trace_end = trace_end; | ||
| 378 | 379 | ||
| 379 | return 0; | 380 | return 0; |
| 380 | } | 381 | } |
| @@ -448,7 +449,7 @@ static int thread_stack__bottom(struct thread *thread, struct thread_stack *ts, | |||
| 448 | return -ENOMEM; | 449 | return -ENOMEM; |
| 449 | 450 | ||
| 450 | return thread_stack__push_cp(thread->ts, ip, sample->time, ref, cp, | 451 | return thread_stack__push_cp(thread->ts, ip, sample->time, ref, cp, |
| 451 | true); | 452 | true, false); |
| 452 | } | 453 | } |
| 453 | 454 | ||
| 454 | static int thread_stack__no_call_return(struct thread *thread, | 455 | static int thread_stack__no_call_return(struct thread *thread, |
| @@ -480,7 +481,7 @@ static int thread_stack__no_call_return(struct thread *thread, | |||
| 480 | if (!cp) | 481 | if (!cp) |
| 481 | return -ENOMEM; | 482 | return -ENOMEM; |
| 482 | return thread_stack__push_cp(ts, 0, sample->time, ref, | 483 | return thread_stack__push_cp(ts, 0, sample->time, ref, |
| 483 | cp, true); | 484 | cp, true, false); |
| 484 | } | 485 | } |
| 485 | } else if (thread_stack__in_kernel(ts) && sample->ip < ks) { | 486 | } else if (thread_stack__in_kernel(ts) && sample->ip < ks) { |
| 486 | /* Return to userspace, so pop all kernel addresses */ | 487 | /* Return to userspace, so pop all kernel addresses */ |
| @@ -505,7 +506,7 @@ static int thread_stack__no_call_return(struct thread *thread, | |||
| 505 | return -ENOMEM; | 506 | return -ENOMEM; |
| 506 | 507 | ||
| 507 | err = thread_stack__push_cp(ts, sample->addr, sample->time, ref, cp, | 508 | err = thread_stack__push_cp(ts, sample->addr, sample->time, ref, cp, |
| 508 | true); | 509 | true, false); |
| 509 | if (err) | 510 | if (err) |
| 510 | return err; | 511 | return err; |
| 511 | 512 | ||
| @@ -525,7 +526,7 @@ static int thread_stack__trace_begin(struct thread *thread, | |||
| 525 | 526 | ||
| 526 | /* Pop trace end */ | 527 | /* Pop trace end */ |
| 527 | tse = &ts->stack[ts->cnt - 1]; | 528 | tse = &ts->stack[ts->cnt - 1]; |
| 528 | if (tse->cp->sym == NULL && tse->cp->ip == 0) { | 529 | if (tse->trace_end) { |
| 529 | err = thread_stack__call_return(thread, ts, --ts->cnt, | 530 | err = thread_stack__call_return(thread, ts, --ts->cnt, |
| 530 | timestamp, ref, false); | 531 | timestamp, ref, false); |
| 531 | if (err) | 532 | if (err) |
| @@ -554,7 +555,7 @@ static int thread_stack__trace_end(struct thread_stack *ts, | |||
| 554 | ret_addr = sample->ip + sample->insn_len; | 555 | ret_addr = sample->ip + sample->insn_len; |
| 555 | 556 | ||
| 556 | return thread_stack__push_cp(ts, ret_addr, sample->time, ref, cp, | 557 | return thread_stack__push_cp(ts, ret_addr, sample->time, ref, cp, |
| 557 | false); | 558 | false, true); |
| 558 | } | 559 | } |
| 559 | 560 | ||
| 560 | int thread_stack__process(struct thread *thread, struct comm *comm, | 561 | int thread_stack__process(struct thread *thread, struct comm *comm, |
| @@ -604,6 +605,7 @@ int thread_stack__process(struct thread *thread, struct comm *comm, | |||
| 604 | ts->last_time = sample->time; | 605 | ts->last_time = sample->time; |
| 605 | 606 | ||
| 606 | if (sample->flags & PERF_IP_FLAG_CALL) { | 607 | if (sample->flags & PERF_IP_FLAG_CALL) { |
| 608 | bool trace_end = sample->flags & PERF_IP_FLAG_TRACE_END; | ||
| 607 | struct call_path_root *cpr = ts->crp->cpr; | 609 | struct call_path_root *cpr = ts->crp->cpr; |
| 608 | struct call_path *cp; | 610 | struct call_path *cp; |
| 609 | u64 ret_addr; | 611 | u64 ret_addr; |
| @@ -621,7 +623,7 @@ int thread_stack__process(struct thread *thread, struct comm *comm, | |||
| 621 | if (!cp) | 623 | if (!cp) |
| 622 | return -ENOMEM; | 624 | return -ENOMEM; |
| 623 | err = thread_stack__push_cp(ts, ret_addr, sample->time, ref, | 625 | err = thread_stack__push_cp(ts, ret_addr, sample->time, ref, |
| 624 | cp, false); | 626 | cp, false, trace_end); |
| 625 | } else if (sample->flags & PERF_IP_FLAG_RETURN) { | 627 | } else if (sample->flags & PERF_IP_FLAG_RETURN) { |
| 626 | if (!sample->ip || !sample->addr) | 628 | if (!sample->ip || !sample->addr) |
| 627 | return 0; | 629 | return 0; |
