aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_event.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 23:47:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 23:47:30 -0500
commit6f696eb17be741668810fe1f798135c7cf6733e2 (patch)
treef9bcfe5831dfcaaad50ca68d7f04d80d8236fa56 /kernel/perf_event.c
parentc4e194e3b71ff4fed01d727c32ee1071921d28a3 (diff)
parent125580380f418000b1a06d9a54700f1191b6e561 (diff)
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (57 commits) x86, perf events: Check if we have APIC enabled perf_event: Fix variable initialization in other codepaths perf kmem: Fix unused argument build warning perf symbols: perf_header__read_build_ids() offset'n'size should be u64 perf symbols: dsos__read_build_ids() should read both user and kernel buildids perf tools: Align long options which have no short forms perf kmem: Show usage if no option is specified sched: Mark sched_clock() as notrace perf sched: Add max delay time snapshot perf tools: Correct size given to memset perf_event: Fix perf_swevent_hrtimer() variable initialization perf sched: Fix for getting task's execution time tracing/kprobes: Fix field creation's bad error handling perf_event: Cleanup for cpu_clock_perf_event_update() perf_event: Allocate children's perf_event_ctxp at the right time perf_event: Clean up __perf_event_init_context() hw-breakpoints: Modify breakpoints without unregistering them perf probe: Update perf-probe document perf probe: Support --del option trace-kprobe: Support delete probe syntax ...
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r--kernel/perf_event.c75
1 files changed, 38 insertions, 37 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 40a996ec39fa..e73e53c7582f 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -36,7 +36,7 @@
36/* 36/*
37 * Each CPU has a list of per CPU events: 37 * Each CPU has a list of per CPU events:
38 */ 38 */
39DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context); 39static DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context);
40 40
41int perf_max_events __read_mostly = 1; 41int perf_max_events __read_mostly = 1;
42static int perf_reserved_percpu __read_mostly; 42static int perf_reserved_percpu __read_mostly;
@@ -567,7 +567,7 @@ static void __perf_event_disable(void *info)
567 * is the current context on this CPU and preemption is disabled, 567 * is the current context on this CPU and preemption is disabled,
568 * hence we can't get into perf_event_task_sched_out for this context. 568 * hence we can't get into perf_event_task_sched_out for this context.
569 */ 569 */
570static void perf_event_disable(struct perf_event *event) 570void perf_event_disable(struct perf_event *event)
571{ 571{
572 struct perf_event_context *ctx = event->ctx; 572 struct perf_event_context *ctx = event->ctx;
573 struct task_struct *task = ctx->task; 573 struct task_struct *task = ctx->task;
@@ -971,7 +971,7 @@ static void __perf_event_enable(void *info)
971 * perf_event_for_each_child or perf_event_for_each as described 971 * perf_event_for_each_child or perf_event_for_each as described
972 * for perf_event_disable. 972 * for perf_event_disable.
973 */ 973 */
974static void perf_event_enable(struct perf_event *event) 974void perf_event_enable(struct perf_event *event)
975{ 975{
976 struct perf_event_context *ctx = event->ctx; 976 struct perf_event_context *ctx = event->ctx;
977 struct task_struct *task = ctx->task; 977 struct task_struct *task = ctx->task;
@@ -1579,7 +1579,6 @@ static void
1579__perf_event_init_context(struct perf_event_context *ctx, 1579__perf_event_init_context(struct perf_event_context *ctx,
1580 struct task_struct *task) 1580 struct task_struct *task)
1581{ 1581{
1582 memset(ctx, 0, sizeof(*ctx));
1583 spin_lock_init(&ctx->lock); 1582 spin_lock_init(&ctx->lock);
1584 mutex_init(&ctx->mutex); 1583 mutex_init(&ctx->mutex);
1585 INIT_LIST_HEAD(&ctx->group_list); 1584 INIT_LIST_HEAD(&ctx->group_list);
@@ -1654,7 +1653,7 @@ static struct perf_event_context *find_get_context(pid_t pid, int cpu)
1654 } 1653 }
1655 1654
1656 if (!ctx) { 1655 if (!ctx) {
1657 ctx = kmalloc(sizeof(struct perf_event_context), GFP_KERNEL); 1656 ctx = kzalloc(sizeof(struct perf_event_context), GFP_KERNEL);
1658 err = -ENOMEM; 1657 err = -ENOMEM;
1659 if (!ctx) 1658 if (!ctx)
1660 goto errout; 1659 goto errout;
@@ -4011,6 +4010,7 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
4011 event->pmu->read(event); 4010 event->pmu->read(event);
4012 4011
4013 data.addr = 0; 4012 data.addr = 0;
4013 data.raw = NULL;
4014 data.period = event->hw.last_period; 4014 data.period = event->hw.last_period;
4015 regs = get_irq_regs(); 4015 regs = get_irq_regs();
4016 /* 4016 /*
@@ -4080,8 +4080,7 @@ static void cpu_clock_perf_event_update(struct perf_event *event)
4080 u64 now; 4080 u64 now;
4081 4081
4082 now = cpu_clock(cpu); 4082 now = cpu_clock(cpu);
4083 prev = atomic64_read(&event->hw.prev_count); 4083 prev = atomic64_xchg(&event->hw.prev_count, now);
4084 atomic64_set(&event->hw.prev_count, now);
4085 atomic64_add(now - prev, &event->count); 4084 atomic64_add(now - prev, &event->count);
4086} 4085}
4087 4086
@@ -4286,15 +4285,8 @@ static void bp_perf_event_destroy(struct perf_event *event)
4286static const struct pmu *bp_perf_event_init(struct perf_event *bp) 4285static const struct pmu *bp_perf_event_init(struct perf_event *bp)
4287{ 4286{
4288 int err; 4287 int err;
4289 /* 4288
4290 * The breakpoint is already filled if we haven't created the counter 4289 err = register_perf_hw_breakpoint(bp);
4291 * through perf syscall
4292 * FIXME: manage to get trigerred to NULL if it comes from syscalls
4293 */
4294 if (!bp->callback)
4295 err = register_perf_hw_breakpoint(bp);
4296 else
4297 err = __register_perf_hw_breakpoint(bp);
4298 if (err) 4290 if (err)
4299 return ERR_PTR(err); 4291 return ERR_PTR(err);
4300 4292
@@ -4308,6 +4300,7 @@ void perf_bp_event(struct perf_event *bp, void *data)
4308 struct perf_sample_data sample; 4300 struct perf_sample_data sample;
4309 struct pt_regs *regs = data; 4301 struct pt_regs *regs = data;
4310 4302
4303 sample.raw = NULL;
4311 sample.addr = bp->attr.bp_addr; 4304 sample.addr = bp->attr.bp_addr;
4312 4305
4313 if (!perf_exclude_event(bp, regs)) 4306 if (!perf_exclude_event(bp, regs))
@@ -4390,7 +4383,7 @@ perf_event_alloc(struct perf_event_attr *attr,
4390 struct perf_event_context *ctx, 4383 struct perf_event_context *ctx,
4391 struct perf_event *group_leader, 4384 struct perf_event *group_leader,
4392 struct perf_event *parent_event, 4385 struct perf_event *parent_event,
4393 perf_callback_t callback, 4386 perf_overflow_handler_t overflow_handler,
4394 gfp_t gfpflags) 4387 gfp_t gfpflags)
4395{ 4388{
4396 const struct pmu *pmu; 4389 const struct pmu *pmu;
@@ -4433,10 +4426,10 @@ perf_event_alloc(struct perf_event_attr *attr,
4433 4426
4434 event->state = PERF_EVENT_STATE_INACTIVE; 4427 event->state = PERF_EVENT_STATE_INACTIVE;
4435 4428
4436 if (!callback && parent_event) 4429 if (!overflow_handler && parent_event)
4437 callback = parent_event->callback; 4430 overflow_handler = parent_event->overflow_handler;
4438 4431
4439 event->callback = callback; 4432 event->overflow_handler = overflow_handler;
4440 4433
4441 if (attr->disabled) 4434 if (attr->disabled)
4442 event->state = PERF_EVENT_STATE_OFF; 4435 event->state = PERF_EVENT_STATE_OFF;
@@ -4776,7 +4769,8 @@ err_put_context:
4776 */ 4769 */
4777struct perf_event * 4770struct perf_event *
4778perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, 4771perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
4779 pid_t pid, perf_callback_t callback) 4772 pid_t pid,
4773 perf_overflow_handler_t overflow_handler)
4780{ 4774{
4781 struct perf_event *event; 4775 struct perf_event *event;
4782 struct perf_event_context *ctx; 4776 struct perf_event_context *ctx;
@@ -4793,7 +4787,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
4793 } 4787 }
4794 4788
4795 event = perf_event_alloc(attr, cpu, ctx, NULL, 4789 event = perf_event_alloc(attr, cpu, ctx, NULL,
4796 NULL, callback, GFP_KERNEL); 4790 NULL, overflow_handler, GFP_KERNEL);
4797 if (IS_ERR(event)) { 4791 if (IS_ERR(event)) {
4798 err = PTR_ERR(event); 4792 err = PTR_ERR(event);
4799 goto err_put_context; 4793 goto err_put_context;
@@ -5090,7 +5084,7 @@ again:
5090 */ 5084 */
5091int perf_event_init_task(struct task_struct *child) 5085int perf_event_init_task(struct task_struct *child)
5092{ 5086{
5093 struct perf_event_context *child_ctx, *parent_ctx; 5087 struct perf_event_context *child_ctx = NULL, *parent_ctx;
5094 struct perf_event_context *cloned_ctx; 5088 struct perf_event_context *cloned_ctx;
5095 struct perf_event *event; 5089 struct perf_event *event;
5096 struct task_struct *parent = current; 5090 struct task_struct *parent = current;
@@ -5106,20 +5100,6 @@ int perf_event_init_task(struct task_struct *child)
5106 return 0; 5100 return 0;
5107 5101
5108 /* 5102 /*
5109 * This is executed from the parent task context, so inherit
5110 * events that have been marked for cloning.
5111 * First allocate and initialize a context for the child.
5112 */
5113
5114 child_ctx = kmalloc(sizeof(struct perf_event_context), GFP_KERNEL);
5115 if (!child_ctx)
5116 return -ENOMEM;
5117
5118 __perf_event_init_context(child_ctx, child);
5119 child->perf_event_ctxp = child_ctx;
5120 get_task_struct(child);
5121
5122 /*
5123 * If the parent's context is a clone, pin it so it won't get 5103 * If the parent's context is a clone, pin it so it won't get
5124 * swapped under us. 5104 * swapped under us.
5125 */ 5105 */
@@ -5149,6 +5129,26 @@ int perf_event_init_task(struct task_struct *child)
5149 continue; 5129 continue;
5150 } 5130 }
5151 5131
5132 if (!child->perf_event_ctxp) {
5133 /*
5134 * This is executed from the parent task context, so
5135 * inherit events that have been marked for cloning.
5136 * First allocate and initialize a context for the
5137 * child.
5138 */
5139
5140 child_ctx = kzalloc(sizeof(struct perf_event_context),
5141 GFP_KERNEL);
5142 if (!child_ctx) {
5143 ret = -ENOMEM;
5144 goto exit;
5145 }
5146
5147 __perf_event_init_context(child_ctx, child);
5148 child->perf_event_ctxp = child_ctx;
5149 get_task_struct(child);
5150 }
5151
5152 ret = inherit_group(event, parent, parent_ctx, 5152 ret = inherit_group(event, parent, parent_ctx,
5153 child, child_ctx); 5153 child, child_ctx);
5154 if (ret) { 5154 if (ret) {
@@ -5177,6 +5177,7 @@ int perf_event_init_task(struct task_struct *child)
5177 get_ctx(child_ctx->parent_ctx); 5177 get_ctx(child_ctx->parent_ctx);
5178 } 5178 }
5179 5179
5180exit:
5180 mutex_unlock(&parent_ctx->mutex); 5181 mutex_unlock(&parent_ctx->mutex);
5181 5182
5182 perf_unpin_context(parent_ctx); 5183 perf_unpin_context(parent_ctx);