diff options
-rw-r--r-- | arch/x86/kernel/cpu/perf_counter.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 09d8cb69c3f3..6d5e7cfd97e7 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c | |||
@@ -1575,8 +1575,8 @@ static void backtrace_warning(void *data, char *msg) | |||
1575 | 1575 | ||
1576 | static int backtrace_stack(void *data, char *name) | 1576 | static int backtrace_stack(void *data, char *name) |
1577 | { | 1577 | { |
1578 | /* Don't bother with IRQ stacks for now */ | 1578 | /* Process all stacks: */ |
1579 | return -1; | 1579 | return 0; |
1580 | } | 1580 | } |
1581 | 1581 | ||
1582 | static void backtrace_address(void *data, unsigned long addr, int reliable) | 1582 | static void backtrace_address(void *data, unsigned long addr, int reliable) |
@@ -1594,6 +1594,8 @@ static const struct stacktrace_ops backtrace_ops = { | |||
1594 | .address = backtrace_address, | 1594 | .address = backtrace_address, |
1595 | }; | 1595 | }; |
1596 | 1596 | ||
1597 | #include "../dumpstack.h" | ||
1598 | |||
1597 | static void | 1599 | static void |
1598 | perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) | 1600 | perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) |
1599 | { | 1601 | { |
@@ -1601,26 +1603,20 @@ perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
1601 | char *stack; | 1603 | char *stack; |
1602 | int nr = entry->nr; | 1604 | int nr = entry->nr; |
1603 | 1605 | ||
1604 | callchain_store(entry, instruction_pointer(regs)); | 1606 | callchain_store(entry, regs->ip); |
1605 | 1607 | ||
1606 | stack = ((char *)regs + sizeof(struct pt_regs)); | 1608 | stack = ((char *)regs + sizeof(struct pt_regs)); |
1607 | #ifdef CONFIG_FRAME_POINTER | 1609 | #ifdef CONFIG_FRAME_POINTER |
1608 | bp = frame_pointer(regs); | 1610 | get_bp(bp); |
1609 | #else | 1611 | #else |
1610 | bp = 0; | 1612 | bp = 0; |
1611 | #endif | 1613 | #endif |
1612 | 1614 | ||
1613 | dump_trace(NULL, regs, (void *)stack, bp, &backtrace_ops, entry); | 1615 | dump_trace(NULL, regs, (void *)&stack, bp, &backtrace_ops, entry); |
1614 | 1616 | ||
1615 | entry->kernel = entry->nr - nr; | 1617 | entry->kernel = entry->nr - nr; |
1616 | } | 1618 | } |
1617 | 1619 | ||
1618 | |||
1619 | struct stack_frame { | ||
1620 | const void __user *next_fp; | ||
1621 | unsigned long return_address; | ||
1622 | }; | ||
1623 | |||
1624 | static int copy_stack_frame(const void __user *fp, struct stack_frame *frame) | 1620 | static int copy_stack_frame(const void __user *fp, struct stack_frame *frame) |
1625 | { | 1621 | { |
1626 | int ret; | 1622 | int ret; |
@@ -1652,7 +1648,7 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
1652 | callchain_store(entry, regs->ip); | 1648 | callchain_store(entry, regs->ip); |
1653 | 1649 | ||
1654 | while (entry->nr < MAX_STACK_DEPTH) { | 1650 | while (entry->nr < MAX_STACK_DEPTH) { |
1655 | frame.next_fp = NULL; | 1651 | frame.next_frame = NULL; |
1656 | frame.return_address = 0; | 1652 | frame.return_address = 0; |
1657 | 1653 | ||
1658 | if (!copy_stack_frame(fp, &frame)) | 1654 | if (!copy_stack_frame(fp, &frame)) |
@@ -1662,7 +1658,7 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
1662 | break; | 1658 | break; |
1663 | 1659 | ||
1664 | callchain_store(entry, frame.return_address); | 1660 | callchain_store(entry, frame.return_address); |
1665 | fp = frame.next_fp; | 1661 | fp = frame.next_frame; |
1666 | } | 1662 | } |
1667 | 1663 | ||
1668 | entry->user = entry->nr - nr; | 1664 | entry->user = entry->nr - nr; |