diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-21 15:54:49 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-21 15:54:49 -0400 |
| commit | 5d70f79b5ef6ea2de4f72a37b2d96e2601e40a22 (patch) | |
| tree | a0d6de0930ba83ecf4629c2e2e261f5eaa2d8f33 /kernel | |
| parent | 888a6f77e0418b049f83d37547c209b904d30af4 (diff) | |
| parent | 750ed158bf6c782d2813da1bca2c824365a0b777 (diff) | |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (163 commits)
tracing: Fix compile issue for trace_sched_wakeup.c
[S390] hardirq: remove pointless header file includes
[IA64] Move local_softirq_pending() definition
perf, powerpc: Fix power_pmu_event_init to not use event->ctx
ftrace: Remove recursion between recordmcount and scripts/mod/empty
jump_label: Add COND_STMT(), reducer wrappery
perf: Optimize sw events
perf: Use jump_labels to optimize the scheduler hooks
jump_label: Add atomic_t interface
jump_label: Use more consistent naming
perf, hw_breakpoint: Fix crash in hw_breakpoint creation
perf: Find task before event alloc
perf: Fix task refcount bugs
perf: Fix group moving
irq_work: Add generic hardirq context callbacks
perf_events: Fix transaction recovery in group_sched_in()
perf_events: Fix bogus AMD64 generic TLB events
perf_events: Fix bogus context time tracking
tracing: Remove parent recording in latency tracer graph options
tracing: Use one prologue for the preempt irqs off tracer function tracers
...
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/Makefile | 4 | ||||
| -rw-r--r-- | kernel/exit.c | 4 | ||||
| -rw-r--r-- | kernel/hw_breakpoint.c | 75 | ||||
| -rw-r--r-- | kernel/irq_work.c | 164 | ||||
| -rw-r--r-- | kernel/jump_label.c | 429 | ||||
| -rw-r--r-- | kernel/kprobes.c | 26 | ||||
| -rw-r--r-- | kernel/module.c | 6 | ||||
| -rw-r--r-- | kernel/perf_event.c | 2592 | ||||
| -rw-r--r-- | kernel/sched.c | 2 | ||||
| -rw-r--r-- | kernel/test_kprobes.c | 12 | ||||
| -rw-r--r-- | kernel/timer.c | 7 | ||||
| -rw-r--r-- | kernel/trace/Kconfig | 5 | ||||
| -rw-r--r-- | kernel/trace/ftrace.c | 127 | ||||
| -rw-r--r-- | kernel/trace/ring_buffer.c | 21 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_event_perf.c | 28 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 55 | ||||
| -rw-r--r-- | kernel/trace/trace_functions_graph.c | 209 | ||||
| -rw-r--r-- | kernel/trace/trace_irqsoff.c | 152 | ||||
| -rw-r--r-- | kernel/trace/trace_sched_wakeup.c | 256 | ||||
| -rw-r--r-- | kernel/trace/trace_workqueue.c | 10 | ||||
| -rw-r--r-- | kernel/tracepoint.c | 14 | ||||
| -rw-r--r-- | kernel/watchdog.c | 41 |
24 files changed, 2876 insertions, 1369 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 17046b6e7c9..e2c9d52cfe9 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
| @@ -10,7 +10,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ | |||
| 10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ | 10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ |
| 11 | hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ | 11 | hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ |
| 12 | notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ | 12 | notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ |
| 13 | async.o range.o | 13 | async.o range.o jump_label.o |
| 14 | obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o | 14 | obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o |
| 15 | obj-y += groups.o | 15 | obj-y += groups.o |
| 16 | 16 | ||
| @@ -23,6 +23,7 @@ CFLAGS_REMOVE_rtmutex-debug.o = -pg | |||
| 23 | CFLAGS_REMOVE_cgroup-debug.o = -pg | 23 | CFLAGS_REMOVE_cgroup-debug.o = -pg |
| 24 | CFLAGS_REMOVE_sched_clock.o = -pg | 24 | CFLAGS_REMOVE_sched_clock.o = -pg |
| 25 | CFLAGS_REMOVE_perf_event.o = -pg | 25 | CFLAGS_REMOVE_perf_event.o = -pg |
| 26 | CFLAGS_REMOVE_irq_work.o = -pg | ||
| 26 | endif | 27 | endif |
| 27 | 28 | ||
| 28 | obj-$(CONFIG_FREEZER) += freezer.o | 29 | obj-$(CONFIG_FREEZER) += freezer.o |
| @@ -101,6 +102,7 @@ obj-$(CONFIG_TRACING) += trace/ | |||
| 101 | obj-$(CONFIG_X86_DS) += trace/ | 102 | obj-$(CONFIG_X86_DS) += trace/ |
| 102 | obj-$(CONFIG_RING_BUFFER) += trace/ | 103 | obj-$(CONFIG_RING_BUFFER) += trace/ |
| 103 | obj-$(CONFIG_SMP) += sched_cpupri.o | 104 | obj-$(CONFIG_SMP) += sched_cpupri.o |
| 105 | obj-$(CONFIG_IRQ_WORK) += irq_work.o | ||
| 104 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o | 106 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o |
| 105 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o | 107 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o |
| 106 | obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o | 108 | obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o |
diff --git a/kernel/exit.c b/kernel/exit.c index 03120229db2..e2bdf37f9fd 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -149,9 +149,7 @@ static void delayed_put_task_struct(struct rcu_head *rhp) | |||
| 149 | { | 149 | { |
| 150 | struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); | 150 | struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); |
| 151 | 151 | ||
| 152 | #ifdef CONFIG_PERF_EVENTS | 152 | perf_event_delayed_put(tsk); |
| 153 | WARN_ON_ONCE(tsk->perf_event_ctxp); | ||
| 154 | #endif | ||
| 155 | trace_sched_process_free(tsk); | 153 | trace_sched_process_free(tsk); |
| 156 | put_task_struct(tsk); | 154 | put_task_struct(tsk); |
| 157 | } | 155 | } |
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index c7c2aed9e2d..2c9120f0afc 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c | |||
| @@ -113,12 +113,12 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type) | |||
| 113 | */ | 113 | */ |
| 114 | static int task_bp_pinned(struct perf_event *bp, enum bp_type_idx type) | 114 | static int task_bp_pinned(struct perf_event *bp, enum bp_type_idx type) |
| 115 | { | 115 | { |
| 116 | struct perf_event_context *ctx = bp->ctx; | 116 | struct task_struct *tsk = bp->hw.bp_target; |
| 117 | struct perf_event *iter; | 117 | struct perf_event *iter; |
| 118 | int count = 0; | 118 | int count = 0; |
| 119 | 119 | ||
| 120 | list_for_each_entry(iter, &bp_task_head, hw.bp_list) { | 120 | list_for_each_entry(iter, &bp_task_head, hw.bp_list) { |
| 121 | if (iter->ctx == ctx && find_slot_idx(iter) == type) | 121 | if (iter->hw.bp_target == tsk && find_slot_idx(iter) == type) |
| 122 | count += hw_breakpoint_weight(iter); | 122 | count += hw_breakpoint_weight(iter); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| @@ -134,7 +134,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, | |||
| 134 | enum bp_type_idx type) | 134 | enum bp_type_idx type) |
| 135 | { | 135 | { |
| 136 | int cpu = bp->cpu; | 136 | int cpu = bp->cpu; |
| 137 | struct task_struct *tsk = bp->ctx->task; | 137 | struct task_struct *tsk = bp->hw.bp_target; |
| 138 | 138 | ||
| 139 | if (cpu >= 0) { | 139 | if (cpu >= 0) { |
| 140 | slots->pinned = per_cpu(nr_cpu_bp_pinned[type], cpu); | 140 | slots->pinned = per_cpu(nr_cpu_bp_pinned[type], cpu); |
| @@ -213,7 +213,7 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type, | |||
| 213 | int weight) | 213 | int weight) |
| 214 | { | 214 | { |
| 215 | int cpu = bp->cpu; | 215 | int cpu = bp->cpu; |
| 216 | struct task_struct *tsk = bp->ctx->task; | 216 | struct task_struct *tsk = bp->hw.bp_target; |
| 217 | 217 | ||
| 218 | /* Pinned counter cpu profiling */ | 218 | /* Pinned counter cpu profiling */ |
| 219 | if (!tsk) { | 219 | if (!tsk) { |
| @@ -433,8 +433,7 @@ register_user_hw_breakpoint(struct perf_event_attr *attr, | |||
| 433 | perf_overflow_handler_t triggered, | 433 | perf_overflow_handler_t triggered, |
| 434 | struct task_struct *tsk) | 434 | struct task_struct *tsk) |
| 435 | { | 435 | { |
| 436 | return perf_event_create_kernel_counter(attr, -1, task_pid_vnr(tsk), | 436 | return perf_event_create_kernel_counter(attr, -1, tsk, triggered); |
| 437 | triggered); | ||
| 438 | } | 437 | } |
| 439 | EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); | 438 | EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); |
| 440 | 439 | ||
| @@ -516,7 +515,7 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr, | |||
| 516 | get_online_cpus(); | 515 | get_online_cpus(); |
| 517 | for_each_online_cpu(cpu) { | 516 | for_each_online_cpu(cpu) { |
| 518 | pevent = per_cpu_ptr(cpu_events, cpu); | 517 | pevent = per_cpu_ptr(cpu_events, cpu); |
| 519 | bp = perf_event_create_kernel_counter(attr, cpu, -1, triggered); | 518 | bp = perf_event_create_kernel_counter(attr, cpu, NULL, triggered); |
| 520 | 519 | ||
| 521 | *pevent = bp; | 520 | *pevent = bp; |
| 522 | 521 | ||
| @@ -566,6 +565,61 @@ static struct notifier_block hw_breakpoint_exceptions_nb = { | |||
| 566 | .priority = 0x7fffffff | 565 | .priority = 0x7fffffff |
| 567 | }; | 566 | }; |
| 568 | 567 | ||
| 568 | static void bp_perf_event_destroy(struct perf_event *event) | ||
| 569 | { | ||
| 570 | release_bp_slot(event); | ||
| 571 | } | ||
| 572 | |||
| 573 | static int hw_breakpoint_event_init(struct perf_event *bp) | ||
| 574 | { | ||
| 575 | int err; | ||
| 576 | |||
| 577 | if (bp->attr.type != PERF_TYPE_BREAKPOINT) | ||
| 578 | return -ENOENT; | ||
| 579 | |||
| 580 | err = register_perf_hw_breakpoint(bp); | ||
| 581 | if (err) | ||
| 582 | return err; | ||
| 583 | |||
| 584 | bp->destroy = bp_perf_event_destroy; | ||
| 585 | |||
| 586 | return 0; | ||
| 587 | } | ||
| 588 | |||
| 589 | static int hw_breakpoint_add(struct perf_event *bp, int flags) | ||
| 590 | { | ||
| 591 | if (!(flags & PERF_EF_START)) | ||
| 592 | bp->hw.state = PERF_HES_STOPPED; | ||
| 593 | |||
| 594 | return arch_install_hw_breakpoint(bp); | ||
| 595 | } | ||
| 596 | |||
| 597 | static void hw_breakpoint_del(struct perf_event *bp, int flags) | ||
| 598 | { | ||
| 599 | arch_uninstall_hw_breakpoint(bp); | ||
| 600 | } | ||
| 601 | |||
| 602 | static void hw_breakpoint_start(struct perf_event *bp, int flags) | ||
| 603 | { | ||
| 604 | bp->hw.state = 0; | ||
| 605 | } | ||
| 606 | |||
| 607 | static void hw_breakpoint_stop(struct perf_event *bp, int flags) | ||
| 608 | { | ||
| 609 | bp->hw.state = PERF_HES_STOPPED; | ||
| 610 | } | ||
| 611 | |||
| 612 | static struct pmu perf_breakpoint = { | ||
| 613 | .task_ctx_nr = perf_sw_context, /* could eventually get its own */ | ||
| 614 | |||
| 615 | |||
