diff options
| -rw-r--r-- | arch/powerpc/kernel/misc.S | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 54 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_amd.c | 80 | ||||
| -rw-r--r-- | arch/x86/kernel/dumpstack.h | 5 | ||||
| -rw-r--r-- | arch/x86/kernel/kgdb.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 4 | ||||
| -rw-r--r-- | include/linux/perf_event.h | 21 | ||||
| -rw-r--r-- | kernel/perf_event.c | 22 | ||||
| -rw-r--r-- | kernel/trace/trace_event_perf.c | 11 | ||||
| -rw-r--r-- | tools/perf/Makefile | 10 | ||||
| -rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 17 |
11 files changed, 153 insertions, 75 deletions
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S index b485a87c94e1..22e507c8a556 100644 --- a/arch/powerpc/kernel/misc.S +++ b/arch/powerpc/kernel/misc.S | |||
| @@ -128,7 +128,6 @@ _GLOBAL(__restore_cpu_power7) | |||
| 128 | /* place holder */ | 128 | /* place holder */ |
| 129 | blr | 129 | blr |
| 130 | 130 | ||
| 131 | #ifdef CONFIG_EVENT_TRACING | ||
| 132 | /* | 131 | /* |
| 133 | * Get a minimal set of registers for our caller's nth caller. | 132 | * Get a minimal set of registers for our caller's nth caller. |
| 134 | * r3 = regs pointer, r5 = n. | 133 | * r3 = regs pointer, r5 = n. |
| @@ -154,4 +153,3 @@ _GLOBAL(perf_arch_fetch_caller_regs) | |||
| 154 | PPC_STL r4,_NIP-STACK_FRAME_OVERHEAD(r3) | 153 | PPC_STL r4,_NIP-STACK_FRAME_OVERHEAD(r3) |
| 155 | PPC_STL r7,_LINK-STACK_FRAME_OVERHEAD(r3) | 154 | PPC_STL r7,_LINK-STACK_FRAME_OVERHEAD(r3) |
| 156 | blr | 155 | blr |
| 157 | #endif /* CONFIG_EVENT_TRACING */ | ||
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 60398a0d947c..53ea4cf1a878 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <asm/apic.h> | 28 | #include <asm/apic.h> |
| 29 | #include <asm/stacktrace.h> | 29 | #include <asm/stacktrace.h> |
| 30 | #include <asm/nmi.h> | 30 | #include <asm/nmi.h> |
| 31 | #include <asm/compat.h> | ||
| 31 | 32 | ||
| 32 | static u64 perf_event_mask __read_mostly; | 33 | static u64 perf_event_mask __read_mostly; |
| 33 | 34 | ||
| @@ -158,7 +159,7 @@ struct x86_pmu { | |||
| 158 | struct perf_event *event); | 159 | struct perf_event *event); |
| 159 | struct event_constraint *event_constraints; | 160 | struct event_constraint *event_constraints; |
| 160 | 161 | ||
| 161 | void (*cpu_prepare)(int cpu); | 162 | int (*cpu_prepare)(int cpu); |
| 162 | void (*cpu_starting)(int cpu); | 163 | void (*cpu_starting)(int cpu); |
| 163 | void (*cpu_dying)(int cpu); | 164 | void (*cpu_dying)(int cpu); |
| 164 | void (*cpu_dead)(int cpu); | 165 | void (*cpu_dead)(int cpu); |
| @@ -1333,11 +1334,12 @@ static int __cpuinit | |||
| 1333 | x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) | 1334 | x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) |
| 1334 | { | 1335 | { |
| 1335 | unsigned int cpu = (long)hcpu; | 1336 | unsigned int cpu = (long)hcpu; |
| 1337 | int ret = NOTIFY_OK; | ||
| 1336 | 1338 | ||
| 1337 | switch (action & ~CPU_TASKS_FROZEN) { | 1339 | switch (action & ~CPU_TASKS_FROZEN) { |
| 1338 | case CPU_UP_PREPARE: | 1340 | case CPU_UP_PREPARE: |
| 1339 | if (x86_pmu.cpu_prepare) | 1341 | if (x86_pmu.cpu_prepare) |
| 1340 | x86_pmu.cpu_prepare(cpu); | 1342 | ret = x86_pmu.cpu_prepare(cpu); |
| 1341 | break; | 1343 | break; |
| 1342 | 1344 | ||
| 1343 | case CPU_STARTING: | 1345 | case CPU_STARTING: |
| @@ -1350,6 +1352,7 @@ x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) | |||
| 1350 | x86_pmu.cpu_dying(cpu); | 1352 | x86_pmu.cpu_dying(cpu); |
| 1351 | break; | 1353 | break; |
| 1352 | 1354 | ||
| 1355 | case CPU_UP_CANCELED: | ||
| 1353 | case CPU_DEAD: | 1356 | case CPU_DEAD: |
| 1354 | if (x86_pmu.cpu_dead) | 1357 | if (x86_pmu.cpu_dead) |
| 1355 | x86_pmu.cpu_dead(cpu); | 1358 | x86_pmu.cpu_dead(cpu); |
| @@ -1359,7 +1362,7 @@ x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) | |||
| 1359 | break; | 1362 | break; |
| 1360 | } | 1363 | } |
| 1361 | 1364 | ||
| 1362 | return NOTIFY_OK; | 1365 | return ret; |
| 1363 | } | 1366 | } |
| 1364 | 1367 | ||
| 1365 | static void __init pmu_check_apic(void) | 1368 | static void __init pmu_check_apic(void) |
| @@ -1628,14 +1631,42 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) | |||
| 1628 | return len; | 1631 | return len; |
| 1629 | } | 1632 | } |
| 1630 | 1633 | ||
| 1631 | static int copy_stack_frame(const void __user *fp, struct stack_frame *frame) | 1634 | #ifdef CONFIG_COMPAT |
| 1635 | static inline int | ||
| 1636 | perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) | ||
| 1632 | { | 1637 | { |
| 1633 | unsigned long bytes; | 1638 | /* 32-bit process in 64-bit kernel. */ |
| 1639 | struct stack_frame_ia32 frame; | ||
| 1640 | const void __user *fp; | ||
| 1634 | 1641 | ||
| 1635 | bytes = copy_from_user_nmi(frame, fp, sizeof(*frame)); | 1642 | if (!test_thread_flag(TIF_IA32)) |
| 1643 | return 0; | ||
| 1644 | |||
| 1645 | fp = compat_ptr(regs->bp); | ||
| 1646 | while (entry->nr < PERF_MAX_STACK_DEPTH) { | ||
| 1647 | unsigned long bytes; | ||
| 1648 | frame.next_frame = 0; | ||
| 1649 | frame.return_address = 0; | ||
| 1650 | |||
| 1651 | bytes = copy_from_user_nmi(&frame, fp, sizeof(frame)); | ||
| 1652 | if (bytes != sizeof(frame)) | ||
| 1653 | break; | ||
| 1654 | |||
| 1655 | if (fp < compat_ptr(regs->sp)) | ||
| 1656 | break; | ||
| 1636 | 1657 | ||
| 1637 | return bytes == sizeof(*frame); | 1658 | callchain_store(entry, frame.return_address); |
| 1659 | fp = compat_ptr(frame.next_frame); | ||
| 1660 | } | ||
| 1661 | return 1; | ||
| 1662 | } | ||
| 1663 | #else | ||
| 1664 | static inline int | ||
| 1665 | perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) | ||
| 1666 | { | ||
| 1667 | return 0; | ||
| 1638 | } | 1668 | } |
| 1669 | #endif | ||
| 1639 | 1670 | ||
| 1640 | static void | 1671 | static void |
| 1641 | perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) | 1672 | perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) |
| @@ -1651,11 +1682,16 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
| 1651 | callchain_store(entry, PERF_CONTEXT_USER); | 1682 | callchain_store(entry, PERF_CONTEXT_USER); |
| 1652 | callchain_store(entry, regs->ip); | 1683 | callchain_store(entry, regs->ip); |
| 1653 | 1684 | ||
| 1685 | if (perf_callchain_user32(regs, entry)) | ||
| 1686 | return; | ||
| 1687 | |||
| 1654 | while (entry->nr < PERF_MAX_STACK_DEPTH) { | 1688 | while (entry->nr < PERF_MAX_STACK_DEPTH) { |
| 1689 | unsigned long bytes; | ||
| 1655 | frame.next_frame = NULL; | 1690 | frame.next_frame = NULL; |
| 1656 | frame.return_address = 0; | 1691 | frame.return_address = 0; |
| 1657 | 1692 | ||
| 1658 | if (!copy_stack_frame(fp, &frame)) | 1693 | bytes = copy_from_user_nmi(&frame, fp, sizeof(frame)); |
| 1694 | if (bytes != sizeof(frame)) | ||
| 1659 | break; | 1695 | break; |
| 1660 | 1696 | ||
| 1661 | if ((unsigned long)fp < regs->sp) | 1697 | if ((unsigned long)fp < regs->sp) |
| @@ -1702,7 +1738,6 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | |||
| 1702 | return entry; | 1738 | return entry; |
| 1703 | } | 1739 | } |
| 1704 | 1740 | ||
| 1705 | #ifdef CONFIG_EVENT_TRACING | ||
| 1706 | void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) | 1741 | void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) |
| 1707 | { | 1742 | { |
| 1708 | regs->ip = ip; | 1743 | regs->ip = ip; |
| @@ -1714,4 +1749,3 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski | |||
| 1714 | regs->cs = __KERNEL_CS; | 1749 | regs->cs = __KERNEL_CS; |
| 1715 | local_save_flags(regs->flags); | 1750 | local_save_flags(regs->flags); |
| 1716 | } | 1751 | } |
| 1717 | #endif | ||
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index b87e0b6970cb..db6f7d4056e1 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c | |||
| @@ -137,6 +137,13 @@ static inline int amd_is_nb_event(struct hw_perf_event *hwc) | |||
| 137 | return (hwc->config & 0xe0) == 0xe0; | 137 | return (hwc->config & 0xe0) == 0xe0; |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | static inline int amd_has_nb(struct cpu_hw_events *cpuc) | ||
| 141 | { | ||
