aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r--kernel/perf_event.c105
1 files changed, 55 insertions, 50 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 4393b9e73740..3d1552d3c12b 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -15,6 +15,7 @@
15#include <linux/smp.h> 15#include <linux/smp.h>
16#include <linux/file.h> 16#include <linux/file.h>
17#include <linux/poll.h> 17#include <linux/poll.h>
18#include <linux/slab.h>
18#include <linux/sysfs.h> 19#include <linux/sysfs.h>
19#include <linux/dcache.h> 20#include <linux/dcache.h>
20#include <linux/percpu.h> 21#include <linux/percpu.h>
@@ -81,10 +82,6 @@ extern __weak const struct pmu *hw_perf_event_init(struct perf_event *event)
81void __weak hw_perf_disable(void) { barrier(); } 82void __weak hw_perf_disable(void) { barrier(); }
82void __weak hw_perf_enable(void) { barrier(); } 83void __weak hw_perf_enable(void) { barrier(); }
83 84
84void __weak hw_perf_event_setup(int cpu) { barrier(); }
85void __weak hw_perf_event_setup_online(int cpu) { barrier(); }
86void __weak hw_perf_event_setup_offline(int cpu) { barrier(); }
87
88int __weak 85int __weak
89hw_perf_group_sched_in(struct perf_event *group_leader, 86hw_perf_group_sched_in(struct perf_event *group_leader,
90 struct perf_cpu_context *cpuctx, 87 struct perf_cpu_context *cpuctx,
@@ -97,25 +94,15 @@ void __weak perf_event_print_debug(void) { }
97 94
98static DEFINE_PER_CPU(int, perf_disable_count); 95static DEFINE_PER_CPU(int, perf_disable_count);
99 96
100void __perf_disable(void)
101{
102 __get_cpu_var(perf_disable_count)++;
103}
104
105bool __perf_enable(void)
106{
107 return !--__get_cpu_var(perf_disable_count);
108}
109
110void perf_disable(void) 97void perf_disable(void)
111{ 98{
112 __perf_disable(); 99 if (!__get_cpu_var(perf_disable_count)++)
113 hw_perf_disable(); 100 hw_perf_disable();
114} 101}
115 102
116void perf_enable(void) 103void perf_enable(void)
117{ 104{
118 if (__perf_enable()) 105 if (!--__get_cpu_var(perf_disable_count))
119 hw_perf_enable(); 106 hw_perf_enable();
120} 107}
121 108
@@ -1178,11 +1165,9 @@ void perf_event_task_sched_out(struct task_struct *task,
1178 struct perf_event_context *ctx = task->perf_event_ctxp; 1165 struct perf_event_context *ctx = task->perf_event_ctxp;
1179 struct perf_event_context *next_ctx; 1166 struct perf_event_context *next_ctx;
1180 struct perf_event_context *parent; 1167 struct perf_event_context *parent;
1181 struct pt_regs *regs;
1182 int do_switch = 1; 1168 int do_switch = 1;
1183 1169
1184 regs = task_pt_regs(task); 1170 perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);
1185 perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, regs, 0);
1186 1171
1187 if (likely(!ctx || !cpuctx->task_ctx)) 1172 if (likely(!ctx || !cpuctx->task_ctx))
1188 return; 1173 return;
@@ -1538,12 +1523,15 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
1538 */ 1523 */
1539 if (interrupts == MAX_INTERRUPTS) { 1524 if (interrupts == MAX_INTERRUPTS) {
1540 perf_log_throttle(event, 1); 1525 perf_log_throttle(event, 1);
1526 perf_disable();
1541 event->pmu->unthrottle(event); 1527 event->pmu->unthrottle(event);
1528 perf_enable();
1542 } 1529 }
1543 1530
1544 if (!event->attr.freq || !event->attr.sample_freq) 1531 if (!event->attr.freq || !event->attr.sample_freq)
1545 continue; 1532 continue;
1546 1533
1534 perf_disable();
1547 event->pmu->read(event); 1535 event->pmu->read(event);
1548 now = atomic64_read(&event->count); 1536 now = atomic64_read(&event->count);
1549 delta = now - hwc->freq_count_stamp; 1537 delta = now - hwc->freq_count_stamp;
@@ -1551,6 +1539,7 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
1551 1539
1552 if (delta > 0) 1540 if (delta > 0)
1553 perf_adjust_period(event, TICK_NSEC, delta); 1541 perf_adjust_period(event, TICK_NSEC, delta);
1542 perf_enable();
1554 } 1543 }
1555 raw_spin_unlock(&ctx->lock); 1544 raw_spin_unlock(&ctx->lock);
1556} 1545}
@@ -1560,9 +1549,6 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
1560 */ 1549 */
1561static void rotate_ctx(struct perf_event_context *ctx) 1550static void rotate_ctx(struct perf_event_context *ctx)
1562{ 1551{
1563 if (!ctx->nr_events)
1564 return;
1565
1566 raw_spin_lock(&ctx->lock); 1552 raw_spin_lock(&ctx->lock);
1567 1553
1568 /* Rotate the first entry last of non-pinned groups */ 1554 /* Rotate the first entry last of non-pinned groups */
@@ -1575,19 +1561,28 @@ void perf_event_task_tick(struct task_struct *curr)
1575{ 1561{
1576 struct perf_cpu_context *cpuctx; 1562 struct perf_cpu_context *cpuctx;
1577 struct perf_event_context *ctx; 1563 struct perf_event_context *ctx;
1564 int rotate = 0;
1578 1565
1579 if (!atomic_read(&nr_events)) 1566 if (!atomic_read(&nr_events))
1580 return; 1567 return;
1581 1568
1582 cpuctx = &__get_cpu_var(perf_cpu_context); 1569 cpuctx = &__get_cpu_var(perf_cpu_context);
1583 ctx = curr->perf_event_ctxp; 1570 if (cpuctx->ctx.nr_events &&
1571 cpuctx->ctx.nr_events != cpuctx->ctx.nr_active)
1572 rotate = 1;
1584 1573
1585 perf_disable(); 1574 ctx = curr->perf_event_ctxp;
1575 if (ctx && ctx->nr_events && ctx->nr_events != ctx->nr_active)
1576 rotate = 1;
1586 1577
1587 perf_ctx_adjust_freq(&cpuctx->ctx); 1578 perf_ctx_adjust_freq(&cpuctx->ctx);
1588 if (ctx) 1579 if (ctx)
1589 perf_ctx_adjust_freq(ctx); 1580 perf_ctx_adjust_freq(ctx);
1590 1581
1582 if (!rotate)
1583 return;
1584
1585 perf_disable();
1591 cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); 1586 cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE);
1592 if (ctx) 1587 if (ctx)
1593 task_ctx_sched_out(ctx, EVENT_FLEXIBLE); 1588 task_ctx_sched_out(ctx, EVENT_FLEXIBLE);
@@ -1599,7 +1594,6 @@ void perf_event_task_tick(struct task_struct *curr)
1599 cpu_ctx_sched_in(cpuctx, EVENT_FLEXIBLE); 1594 cpu_ctx_sched_in(cpuctx, EVENT_FLEXIBLE);
1600 if (ctx) 1595 if (ctx)
1601 task_ctx_sched_in(curr, EVENT_FLEXIBLE); 1596 task_ctx_sched_in(curr, EVENT_FLEXIBLE);
1602
1603 perf_enable(); 1597 perf_enable();
1604} 1598}
1605 1599
@@ -2791,6 +2785,12 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
2791 return NULL; 2785 return NULL;
2792} 2786}
2793 2787
2788__weak
2789void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
2790{
2791}
2792
2793
2794/* 2794/*
2795 * Output 2795 * Output
2796 */ 2796 */
@@ -3376,15 +3376,23 @@ static void perf_event_task_output(struct perf_event *event,
3376 struct perf_task_event *task_event) 3376 struct perf_task_event *task_event)
3377{ 3377{
3378 struct perf_output_handle handle; 3378 struct perf_output_handle handle;
3379 int size;
3380 struct task_struct *task = task_event->task; 3379 struct task_struct *task = task_event->task;
3381 int ret; 3380 unsigned long flags;
3381 int size, ret;
3382
3383 /*
3384 * If this CPU attempts to acquire an rq lock held by a CPU spinning
3385 * in perf_output_lock() from interrupt context, it's game over.
3386 */
3387 local_irq_save(flags);
3382 3388
3383 size = task_event->event_id.header.size; 3389 size = task_event->event_id.header.size;
3384 ret = perf_output_begin(&handle, event, size, 0, 0); 3390 ret = perf_output_begin(&handle, event, size, 0, 0);
3385 3391
3386 if (ret) 3392 if (ret) {
3393 local_irq_restore(flags);
3387 return; 3394 return;
3395 }
3388 3396
3389 task_event->event_id.pid = perf_event_pid(event, task); 3397 task_event->event_id.pid = perf_event_pid(event, task);
3390 task_event->event_id.ppid = perf_event_pid(event, current); 3398 task_event->event_id.ppid = perf_event_pid(event, current);
@@ -3395,6 +3403,7 @@ static void perf_event_task_output(struct perf_event *event,
3395 perf_output_put(&handle, task_event->event_id); 3403 perf_output_put(&handle, task_event->event_id);
3396 3404
3397 perf_output_end(&handle); 3405 perf_output_end(&handle);
3406 local_irq_restore(flags);
3398} 3407}
3399 3408
3400static int perf_event_task_match(struct perf_event *event) 3409static int perf_event_task_match(struct perf_event *event)
@@ -4318,9 +4327,8 @@ static const struct pmu perf_ops_task_clock = {
4318#ifdef CONFIG_EVENT_TRACING 4327#ifdef CONFIG_EVENT_TRACING
4319 4328
4320void perf_tp_event(int event_id, u64 addr, u64 count, void *record, 4329void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
4321 int entry_size) 4330 int entry_size, struct pt_regs *regs)
4322{ 4331{
4323 struct pt_regs *regs = get_irq_regs();
4324 struct perf_sample_data data; 4332 struct perf_sample_data data;
4325 struct perf_raw_record raw = { 4333 struct perf_raw_record raw = {
4326 .size = entry_size, 4334 .size = entry_size,
@@ -4330,12 +4338,9 @@ void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
4330 perf_sample_data_init(&data, addr); 4338 perf_sample_data_init(&data, addr);
4331 data.raw = &raw; 4339 data.raw = &raw;
4332 4340
4333 if (!regs)
4334 regs = task_pt_regs(current);
4335
4336 /* Trace events already protected against recursion */ 4341 /* Trace events already protected against recursion */
4337 do_perf_sw_event(PERF_TYPE_TRACEPOINT, event_id, count, 1, 4342 do_perf_sw_event(PERF_TYPE_TRACEPOINT, event_id, count, 1,
4338 &data, regs); 4343 &data, regs);
4339} 4344}
4340EXPORT_SYMBOL_GPL(perf_tp_event); 4345EXPORT_SYMBOL_GPL(perf_tp_event);
4341 4346
@@ -4351,7 +4356,7 @@ static int perf_tp_event_match(struct perf_event *event,
4351 4356
4352static void tp_perf_event_destroy(struct perf_event *event) 4357static void tp_perf_event_destroy(struct perf_event *event)
4353{ 4358{
4354 ftrace_profile_disable(event->attr.config); 4359 perf_trace_disable(event->attr.config);
4355} 4360}
4356 4361
4357static const struct pmu *tp_perf_event_init(struct perf_event *event) 4362static const struct pmu *tp_perf_event_init(struct perf_event *event)
@@ -4365,7 +4370,7 @@ static const struct pmu *tp_perf_event_init(struct perf_event *event)
4365 !capable(CAP_SYS_ADMIN)) 4370 !capable(CAP_SYS_ADMIN))
4366 return ERR_PTR(-EPERM); 4371 return ERR_PTR(-EPERM);
4367 4372
4368 if (ftrace_profile_enable(event->attr.config)) 4373 if (perf_trace_enable(event->attr.config))
4369 return NULL; 4374 return NULL;
4370 4375
4371 event->destroy = tp_perf_event_destroy; 4376 event->destroy = tp_perf_event_destroy;
@@ -4892,7 +4897,7 @@ err_fput_free_put_context:
4892 4897
4893err_free_put_context: 4898err_free_put_context:
4894 if (err < 0) 4899 if (err < 0)
4895 kfree(event); 4900 free_event(event);
4896 4901
4897err_put_context: 4902err_put_context:
4898 if (err < 0) 4903 if (err < 0)
@@ -5372,18 +5377,26 @@ int perf_event_init_task(struct task_struct *child)
5372 return ret; 5377 return ret;
5373} 5378}
5374 5379
5380static void __init perf_event_init_all_cpus(void)
5381{
5382 int cpu;
5383 struct perf_cpu_context *cpuctx;
5384
5385 for_each_possible_cpu(cpu) {
5386 cpuctx = &per_cpu(perf_cpu_context, cpu);
5387 __perf_event_init_context(&cpuctx->ctx, NULL);
5388 }
5389}
5390
5375static void __cpuinit perf_event_init_cpu(int cpu) 5391static void __cpuinit perf_event_init_cpu(int cpu)
5376{ 5392{
5377 struct perf_cpu_context *cpuctx; 5393 struct perf_cpu_context *cpuctx;
5378 5394
5379 cpuctx = &per_cpu(perf_cpu_context, cpu); 5395 cpuctx = &per_cpu(perf_cpu_context, cpu);
5380 __perf_event_init_context(&cpuctx->ctx, NULL);
5381 5396
5382 spin_lock(&perf_resource_lock); 5397 spin_lock(&perf_resource_lock);
5383 cpuctx->max_pertask = perf_max_events - perf_reserved_percpu; 5398 cpuctx->max_pertask = perf_max_events - perf_reserved_percpu;
5384 spin_unlock(&perf_resource_lock); 5399 spin_unlock(&perf_resource_lock);
5385
5386 hw_perf_event_setup(cpu);
5387} 5400}
5388 5401
5389#ifdef CONFIG_HOTPLUG_CPU 5402#ifdef CONFIG_HOTPLUG_CPU
@@ -5423,20 +5436,11 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
5423 perf_event_init_cpu(cpu); 5436 perf_event_init_cpu(cpu);
5424 break; 5437 break;
5425 5438
5426 case CPU_ONLINE:
5427 case CPU_ONLINE_FROZEN:
5428 hw_perf_event_setup_online(cpu);
5429 break;
5430
5431 case CPU_DOWN_PREPARE: 5439 case CPU_DOWN_PREPARE:
5432 case CPU_DOWN_PREPARE_FROZEN: 5440 case CPU_DOWN_PREPARE_FROZEN:
5433 perf_event_exit_cpu(cpu); 5441 perf_event_exit_cpu(cpu);
5434 break; 5442 break;
5435 5443
5436 case CPU_DEAD:
5437 hw_perf_event_setup_offline(cpu);
5438 break;
5439
5440 default: 5444 default:
5441 break; 5445 break;
5442 } 5446 }
@@ -5454,6 +5458,7 @@ static struct notifier_block __cpuinitdata perf_cpu_nb = {
5454 5458
5455void __init perf_event_init(void) 5459void __init perf_event_init(void)
5456{ 5460{
5461 perf_event_init_all_cpus();
5457 perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE, 5462 perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE,
5458 (void *)(long)smp_processor_id()); 5463 (void *)(long)smp_processor_id());
5459 perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE, 5464 perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE,