diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-06-18 16:20:52 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-19 07:42:34 -0400 |
commit | f9188e023c248d73f5b4a589b480e065c1864068 (patch) | |
tree | 86efe8c89c318fdf9b9db8471680ba225ec8f4e2 /arch | |
parent | b8e6d829729d1a5991a9f628205b671cac2ec06f (diff) |
perf_counter: Make callchain samples extensible
Before exposing upstream tools to a callchain-samples ABI, tidy it
up to make it more extensible in the future:
Use markers in the IP chain to denote context, use (u64)-1..-4095 range
for these context markers because we use them for ERR_PTR(), so these
addresses are unlikely to be mapped.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/cpu/perf_counter.c | 29 |
1 files changed, 6 insertions, 23 deletions
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index ce1ae3f1f86c..76dfef23f789 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c | |||
@@ -1555,9 +1555,9 @@ const struct pmu *hw_perf_counter_init(struct perf_counter *counter) | |||
1555 | */ | 1555 | */ |
1556 | 1556 | ||
1557 | static inline | 1557 | static inline |
1558 | void callchain_store(struct perf_callchain_entry *entry, unsigned long ip) | 1558 | void callchain_store(struct perf_callchain_entry *entry, u64 ip) |
1559 | { | 1559 | { |
1560 | if (entry->nr < MAX_STACK_DEPTH) | 1560 | if (entry->nr < PERF_MAX_STACK_DEPTH) |
1561 | entry->ip[entry->nr++] = ip; | 1561 | entry->ip[entry->nr++] = ip; |
1562 | } | 1562 | } |
1563 | 1563 | ||
@@ -1602,22 +1602,10 @@ static const struct stacktrace_ops backtrace_ops = { | |||
1602 | static void | 1602 | static void |
1603 | perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) | 1603 | perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) |
1604 | { | 1604 | { |
1605 | unsigned long bp; | 1605 | callchain_store(entry, PERF_CONTEXT_KERNEL); |
1606 | char *stack; | ||
1607 | int nr = entry->nr; | ||
1608 | |||
1609 | callchain_store(entry, regs->ip); | 1606 | callchain_store(entry, regs->ip); |
1610 | 1607 | ||
1611 | stack = ((char *)regs + sizeof(struct pt_regs)); | 1608 | dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry); |
1612 | #ifdef CONFIG_FRAME_POINTER | ||
1613 | get_bp(bp); | ||
1614 | #else | ||
1615 | bp = 0; | ||
1616 | #endif | ||
1617 | |||
1618 | dump_trace(NULL, regs, (void *)&stack, bp, &backtrace_ops, entry); | ||
1619 | |||
1620 | entry->kernel = entry->nr - nr; | ||
1621 | } | 1609 | } |
1622 | 1610 | ||
1623 | /* | 1611 | /* |
@@ -1669,16 +1657,16 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
1669 | { | 1657 | { |
1670 | struct stack_frame frame; | 1658 | struct stack_frame frame; |
1671 | const void __user *fp; | 1659 | const void __user *fp; |
1672 | int nr = entry->nr; | ||
1673 | 1660 | ||
1674 | if (!user_mode(regs)) | 1661 | if (!user_mode(regs)) |
1675 | regs = task_pt_regs(current); | 1662 | regs = task_pt_regs(current); |
1676 | 1663 | ||
1677 | fp = (void __user *)regs->bp; | 1664 | fp = (void __user *)regs->bp; |
1678 | 1665 | ||
1666 | callchain_store(entry, PERF_CONTEXT_USER); | ||
1679 | callchain_store(entry, regs->ip); | 1667 | callchain_store(entry, regs->ip); |
1680 | 1668 | ||
1681 | while (entry->nr < MAX_STACK_DEPTH) { | 1669 | while (entry->nr < PERF_MAX_STACK_DEPTH) { |
1682 | frame.next_frame = NULL; | 1670 | frame.next_frame = NULL; |
1683 | frame.return_address = 0; | 1671 | frame.return_address = 0; |
1684 | 1672 | ||
@@ -1691,8 +1679,6 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
1691 | callchain_store(entry, frame.return_address); | 1679 | callchain_store(entry, frame.return_address); |
1692 | fp = frame.next_frame; | 1680 | fp = frame.next_frame; |
1693 | } | 1681 | } |
1694 | |||
1695 | entry->user = entry->nr - nr; | ||
1696 | } | 1682 | } |
1697 | 1683 | ||
1698 | static void | 1684 | static void |
@@ -1728,9 +1714,6 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | |||
1728 | entry = &__get_cpu_var(irq_entry); | 1714 | entry = &__get_cpu_var(irq_entry); |
1729 | 1715 | ||
1730 | entry->nr = 0; | 1716 | entry->nr = 0; |
1731 | entry->hv = 0; | ||
1732 | entry->kernel = 0; | ||
1733 | entry->user = 0; | ||
1734 | 1717 | ||
1735 | perf_do_callchain(regs, entry); | 1718 | perf_do_callchain(regs, entry); |
1736 | 1719 | ||