diff options
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r-- | kernel/perf_event.c | 231 |
1 files changed, 117 insertions, 114 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 087025fe3ba1..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> |
@@ -56,21 +57,6 @@ static atomic_t nr_task_events __read_mostly; | |||
56 | */ | 57 | */ |
57 | int sysctl_perf_event_paranoid __read_mostly = 1; | 58 | int sysctl_perf_event_paranoid __read_mostly = 1; |
58 | 59 | ||
59 | static inline bool perf_paranoid_tracepoint_raw(void) | ||
60 | { | ||
61 | return sysctl_perf_event_paranoid > -1; | ||
62 | } | ||
63 | |||
64 | static inline bool perf_paranoid_cpu(void) | ||
65 | { | ||
66 | return sysctl_perf_event_paranoid > 0; | ||
67 | } | ||
68 | |||
69 | static inline bool perf_paranoid_kernel(void) | ||
70 | { | ||
71 | return sysctl_perf_event_paranoid > 1; | ||
72 | } | ||
73 | |||
74 | int sysctl_perf_event_mlock __read_mostly = 512; /* 'free' kb per user */ | 60 | int sysctl_perf_event_mlock __read_mostly = 512; /* 'free' kb per user */ |
75 | 61 | ||
76 | /* | 62 | /* |
@@ -96,13 +82,10 @@ extern __weak const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
96 | void __weak hw_perf_disable(void) { barrier(); } | 82 | void __weak hw_perf_disable(void) { barrier(); } |
97 | void __weak hw_perf_enable(void) { barrier(); } | 83 | void __weak hw_perf_enable(void) { barrier(); } |
98 | 84 | ||
99 | void __weak hw_perf_event_setup(int cpu) { barrier(); } | ||
100 | void __weak hw_perf_event_setup_online(int cpu) { barrier(); } | ||
101 | |||
102 | int __weak | 85 | int __weak |
103 | hw_perf_group_sched_in(struct perf_event *group_leader, | 86 | hw_perf_group_sched_in(struct perf_event *group_leader, |
104 | struct perf_cpu_context *cpuctx, | 87 | struct perf_cpu_context *cpuctx, |
105 | struct perf_event_context *ctx, int cpu) | 88 | struct perf_event_context *ctx) |
106 | { | 89 | { |
107 | return 0; | 90 | return 0; |
108 | } | 91 | } |
@@ -111,25 +94,15 @@ void __weak perf_event_print_debug(void) { } | |||
111 | 94 | ||
112 | static DEFINE_PER_CPU(int, perf_disable_count); | 95 | static DEFINE_PER_CPU(int, perf_disable_count); |
113 | 96 | ||
114 | void __perf_disable(void) | ||
115 | { | ||
116 | __get_cpu_var(perf_disable_count)++; | ||
117 | } | ||
118 | |||
119 | bool __perf_enable(void) | ||
120 | { | ||
121 | return !--__get_cpu_var(perf_disable_count); | ||
122 | } | ||
123 | |||
124 | void perf_disable(void) | 97 | void perf_disable(void) |
125 | { | 98 | { |
126 | __perf_disable(); | 99 | if (!__get_cpu_var(perf_disable_count)++) |
127 | hw_perf_disable(); | 100 | hw_perf_disable(); |
128 | } | 101 | } |
129 | 102 | ||
130 | void perf_enable(void) | 103 | void perf_enable(void) |
131 | { | 104 | { |
132 | if (__perf_enable()) | 105 | if (!--__get_cpu_var(perf_disable_count)) |
133 | hw_perf_enable(); | 106 | hw_perf_enable(); |
134 | } | 107 | } |
135 | 108 | ||
@@ -248,7 +221,7 @@ static void perf_unpin_context(struct perf_event_context *ctx) | |||
248 | 221 | ||
249 | static inline u64 perf_clock(void) | 222 | static inline u64 perf_clock(void) |
250 | { | 223 | { |
251 | return cpu_clock(smp_processor_id()); | 224 | return cpu_clock(raw_smp_processor_id()); |
252 | } | 225 | } |
253 | 226 | ||
254 | /* | 227 | /* |
@@ -632,14 +605,13 @@ void perf_event_disable(struct perf_event *event) | |||
632 | static int | 605 | static int |
633 | event_sched_in(struct perf_event *event, | 606 | event_sched_in(struct perf_event *event, |
634 | struct perf_cpu_context *cpuctx, | 607 | struct perf_cpu_context *cpuctx, |
635 | struct perf_event_context *ctx, | 608 | struct perf_event_context *ctx) |
636 | int cpu) | ||
637 | { | 609 | { |
638 | if (event->state <= PERF_EVENT_STATE_OFF) | 610 | if (event->state <= PERF_EVENT_STATE_OFF) |
639 | return 0; | 611 | return 0; |
640 | 612 | ||
641 | event->state = PERF_EVENT_STATE_ACTIVE; | 613 | event->state = PERF_EVENT_STATE_ACTIVE; |
642 | event->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ | 614 | event->oncpu = smp_processor_id(); |
643 | /* | 615 | /* |
644 | * The new state must be visible before we turn it on in the hardware: | 616 | * The new state must be visible before we turn it on in the hardware: |
645 | */ | 617 | */ |
@@ -666,8 +638,7 @@ event_sched_in(struct perf_event *event, | |||
666 | static int | 638 | static int |
667 | group_sched_in(struct perf_event *group_event, | 639 | group_sched_in(struct perf_event *group_event, |
668 | struct perf_cpu_context *cpuctx, | 640 | struct perf_cpu_context *cpuctx, |
669 | struct perf_event_context *ctx, | 641 | struct perf_event_context *ctx) |
670 | int cpu) | ||
671 | { | 642 | { |
672 | struct perf_event *event, *partial_group; | 643 | struct perf_event *event, *partial_group; |
673 | int ret; | 644 | int ret; |
@@ -675,18 +646,18 @@ group_sched_in(struct perf_event *group_event, | |||
675 | if (group_event->state == PERF_EVENT_STATE_OFF) | 646 | if (group_event->state == PERF_EVENT_STATE_OFF) |
676 | return 0; | 647 | return 0; |
677 | 648 | ||
678 | ret = hw_perf_group_sched_in(group_event, cpuctx, ctx, cpu); | 649 | ret = hw_perf_group_sched_in(group_event, cpuctx, ctx); |
679 | if (ret) | 650 | if (ret) |
680 | return ret < 0 ? ret : 0; | 651 | return ret < 0 ? ret : 0; |
681 | 652 | ||
682 | if (event_sched_in(group_event, cpuctx, ctx, cpu)) | 653 | if (event_sched_in(group_event, cpuctx, ctx)) |
683 | return -EAGAIN; | 654 | return -EAGAIN; |
684 | 655 | ||
685 | /* | 656 | /* |
686 | * Schedule in siblings as one group (if any): | 657 | * Schedule in siblings as one group (if any): |
687 | */ | 658 | */ |
688 | list_for_each_entry(event, &group_event->sibling_list, group_entry) { | 659 | list_for_each_entry(event, &group_event->sibling_list, group_entry) { |
689 | if (event_sched_in(event, cpuctx, ctx, cpu)) { | 660 | if (event_sched_in(event, cpuctx, ctx)) { |
690 | partial_group = event; | 661 | partial_group = event; |
691 | goto group_error; | 662 | goto group_error; |
692 | } | 663 | } |
@@ -760,7 +731,6 @@ static void __perf_install_in_context(void *info) | |||
760 | struct perf_event *event = info; | 731 | struct perf_event *event = info; |
761 | struct perf_event_context *ctx = event->ctx; | 732 | struct perf_event_context *ctx = event->ctx; |
762 | struct perf_event *leader = event->group_leader; | 733 | struct perf_event *leader = event->group_leader; |
763 | int cpu = smp_processor_id(); | ||
764 | int err; | 734 | int err; |
765 | 735 | ||
766 | /* | 736 | /* |
@@ -807,7 +777,7 @@ static void __perf_install_in_context(void *info) | |||
807 | if (!group_can_go_on(event, cpuctx, 1)) | 777 | if (!group_can_go_on(event, cpuctx, 1)) |
808 | err = -EEXIST; | 778 | err = -EEXIST; |
809 | else | 779 | else |
810 | err = event_sched_in(event, cpuctx, ctx, cpu); | 780 | err = event_sched_in(event, cpuctx, ctx); |
811 | 781 | ||
812 | if (err) { | 782 | if (err) { |
813 | /* | 783 | /* |
@@ -949,11 +919,9 @@ static void __perf_event_enable(void *info) | |||
949 | } else { | 919 | } else { |
950 | perf_disable(); | 920 | perf_disable(); |
951 | if (event == leader) | 921 | if (event == leader) |
952 | err = group_sched_in(event, cpuctx, ctx, | 922 | err = group_sched_in(event, cpuctx, ctx); |
953 | smp_processor_id()); | ||
954 | else | 923 | else |
955 | err = event_sched_in(event, cpuctx, ctx, | 924 | err = event_sched_in(event, cpuctx, ctx); |
956 | smp_processor_id()); | ||
957 | perf_enable(); | 925 | perf_enable(); |
958 | } | 926 | } |
959 | 927 | ||
@@ -1197,11 +1165,9 @@ void perf_event_task_sched_out(struct task_struct *task, | |||
1197 | struct perf_event_context *ctx = task->perf_event_ctxp; | 1165 | struct perf_event_context *ctx = task->perf_event_ctxp; |
1198 | struct perf_event_context *next_ctx; | 1166 | struct perf_event_context *next_ctx; |
1199 | struct perf_event_context *parent; | 1167 | struct perf_event_context *parent; |
1200 | struct pt_regs *regs; | ||
1201 | int do_switch = 1; | 1168 | int do_switch = 1; |
1202 | 1169 | ||
1203 | regs = task_pt_regs(task); | 1170 | perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); |
1204 | perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, regs, 0); | ||
1205 | 1171 | ||
1206 | if (likely(!ctx || !cpuctx->task_ctx)) | 1172 | if (likely(!ctx || !cpuctx->task_ctx)) |
1207 | return; | 1173 | return; |
@@ -1280,19 +1246,18 @@ static void cpu_ctx_sched_out(struct perf_cpu_context *cpuctx, | |||
1280 | 1246 | ||
1281 | static void | 1247 | static void |
1282 | ctx_pinned_sched_in(struct perf_event_context *ctx, | 1248 | ctx_pinned_sched_in(struct perf_event_context *ctx, |
1283 | struct perf_cpu_context *cpuctx, | 1249 | struct perf_cpu_context *cpuctx) |
1284 | int cpu) | ||
1285 | { | 1250 | { |
1286 | struct perf_event *event; | 1251 | struct perf_event *event; |
1287 | 1252 | ||
1288 | list_for_each_entry(event, &ctx->pinned_groups, group_entry) { | 1253 | list_for_each_entry(event, &ctx->pinned_groups, group_entry) { |
1289 | if (event->state <= PERF_EVENT_STATE_OFF) | 1254 | if (event->state <= PERF_EVENT_STATE_OFF) |
1290 | continue; | 1255 | continue; |
1291 | if (event->cpu != -1 && event->cpu != cpu) | 1256 | if (event->cpu != -1 && event->cpu != smp_processor_id()) |
1292 | continue; | 1257 | continue; |
1293 | 1258 | ||
1294 | if (group_can_go_on(event, cpuctx, 1)) | 1259 | if (group_can_go_on(event, cpuctx, 1)) |
1295 | group_sched_in(event, cpuctx, ctx, cpu); | 1260 | group_sched_in(event, cpuctx, ctx); |
1296 | 1261 | ||
1297 | /* | 1262 | /* |
1298 | * If this pinned group hasn't been scheduled, | 1263 | * If this pinned group hasn't been scheduled, |
@@ -1307,8 +1272,7 @@ ctx_pinned_sched_in(struct perf_event_context *ctx, | |||
1307 | 1272 | ||
1308 | static void | 1273 | static void |
1309 | ctx_flexible_sched_in(struct perf_event_context *ctx, | 1274 | ctx_flexible_sched_in(struct perf_event_context *ctx, |
1310 | struct perf_cpu_context *cpuctx, | 1275 | struct perf_cpu_context *cpuctx) |
1311 | int cpu) | ||
1312 | { | 1276 | { |
1313 | struct perf_event *event; | 1277 | struct perf_event *event; |
1314 | int can_add_hw = 1; | 1278 | int can_add_hw = 1; |
@@ -1321,11 +1285,11 @@ ctx_flexible_sched_in(struct perf_event_context *ctx, | |||
1321 | * Listen to the 'cpu' scheduling filter constraint | 1285 | * Listen to the 'cpu' scheduling filter constraint |
1322 | * of events: | 1286 | * of events: |
1323 | */ | 1287 | */ |
1324 | if (event->cpu != -1 && event->cpu != cpu) | 1288 | if (event->cpu != -1 && event->cpu != smp_processor_id()) |
1325 | continue; | 1289 | continue; |
1326 | 1290 | ||
1327 | if (group_can_go_on(event, cpuctx, can_add_hw)) | 1291 | if (group_can_go_on(event, cpuctx, can_add_hw)) |
1328 | if (group_sched_in(event, cpuctx, ctx, cpu)) | 1292 | if (group_sched_in(event, cpuctx, ctx)) |
1329 | can_add_hw = 0; | 1293 | can_add_hw = 0; |
1330 | } | 1294 | } |
1331 | } | 1295 | } |
@@ -1335,8 +1299,6 @@ ctx_sched_in(struct perf_event_context *ctx, | |||
1335 | struct perf_cpu_context *cpuctx, | 1299 | struct perf_cpu_context *cpuctx, |
1336 | enum event_type_t event_type) | 1300 | enum event_type_t event_type) |
1337 | { | 1301 | { |
1338 | int cpu = smp_processor_id(); | ||
1339 | |||
1340 | raw_spin_lock(&ctx->lock); | 1302 | raw_spin_lock(&ctx->lock); |
1341 | ctx->is_active = 1; | 1303 | ctx->is_active = 1; |
1342 | if (likely(!ctx->nr_events)) | 1304 | if (likely(!ctx->nr_events)) |
@@ -1351,11 +1313,11 @@ ctx_sched_in(struct perf_event_context *ctx, | |||
1351 | * in order to give them the best chance of going on. | 1313 | * in order to give them the best chance of going on. |
1352 | */ | 1314 | */ |
1353 | if (event_type & EVENT_PINNED) | 1315 | if (event_type & EVENT_PINNED) |
1354 | ctx_pinned_sched_in(ctx, cpuctx, cpu); | 1316 | ctx_pinned_sched_in(ctx, cpuctx); |
1355 | 1317 | ||
1356 | /* Then walk through the lower prio flexible groups */ | 1318 | /* Then walk through the lower prio flexible groups */ |
1357 | if (event_type & EVENT_FLEXIBLE) | 1319 | if (event_type & EVENT_FLEXIBLE) |
1358 | ctx_flexible_sched_in(ctx, cpuctx, cpu); | 1320 | ctx_flexible_sched_in(ctx, cpuctx); |
1359 | 1321 | ||
1360 | perf_enable(); | 1322 | perf_enable(); |
1361 | out: | 1323 | out: |
@@ -1493,6 +1455,22 @@ do { \ | |||
1493 | return div64_u64(dividend, divisor); | 1455 | return div64_u64(dividend, divisor); |
1494 | } | 1456 | } |
1495 | 1457 | ||
1458 | static void perf_event_stop(struct perf_event *event) | ||
1459 | { | ||
1460 | if (!event->pmu->stop) | ||
1461 | return event->pmu->disable(event); | ||
1462 | |||
1463 | return event->pmu->stop(event); | ||
1464 | } | ||
1465 | |||
1466 | static int perf_event_start(struct perf_event *event) | ||
1467 | { | ||
1468 | if (!event->pmu->start) | ||
1469 | return event->pmu->enable(event); | ||
1470 | |||
1471 | return event->pmu->start(event); | ||
1472 | } | ||
1473 | |||
1496 | static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) | 1474 | static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) |
1497 | { | 1475 | { |
1498 | struct hw_perf_event *hwc = &event->hw; | 1476 | struct hw_perf_event *hwc = &event->hw; |
@@ -1513,9 +1491,9 @@ static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) | |||
1513 | 1491 | ||
1514 | if (atomic64_read(&hwc->period_left) > 8*sample_period) { | 1492 | if (atomic64_read(&hwc->period_left) > 8*sample_period) { |
1515 | perf_disable(); | 1493 | perf_disable(); |
1516 | event->pmu->disable(event); | 1494 | perf_event_stop(event); |
1517 | atomic64_set(&hwc->period_left, 0); | 1495 | atomic64_set(&hwc->period_left, 0); |
1518 | event->pmu->enable(event); | 1496 | perf_event_start(event); |
1519 | perf_enable(); | 1497 | perf_enable(); |
1520 | } | 1498 | } |
1521 | } | 1499 | } |
@@ -1545,12 +1523,15 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) | |||
1545 | */ | 1523 | */ |
1546 | if (interrupts == MAX_INTERRUPTS) { | 1524 | if (interrupts == MAX_INTERRUPTS) { |
1547 | perf_log_throttle(event, 1); | 1525 | perf_log_throttle(event, 1); |
1526 | perf_disable(); | ||
1548 | event->pmu->unthrottle(event); | 1527 | event->pmu->unthrottle(event); |
1528 | perf_enable(); | ||
1549 | } | 1529 | } |
1550 | 1530 | ||
1551 | if (!event->attr.freq || !event->attr.sample_freq) | 1531 | if (!event->attr.freq || !event->attr.sample_freq) |
1552 | continue; | 1532 | continue; |
1553 | 1533 | ||
1534 | perf_disable(); | ||
1554 | event->pmu->read(event); | 1535 | event->pmu->read(event); |
1555 | now = atomic64_read(&event->count); | 1536 | now = atomic64_read(&event->count); |
1556 | delta = now - hwc->freq_count_stamp; | 1537 | delta = now - hwc->freq_count_stamp; |
@@ -1558,6 +1539,7 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) | |||
1558 | 1539 | ||
1559 | if (delta > 0) | 1540 | if (delta > 0) |
1560 | perf_adjust_period(event, TICK_NSEC, delta); | 1541 | perf_adjust_period(event, TICK_NSEC, delta); |
1542 | perf_enable(); | ||
1561 | } | 1543 | } |
1562 | raw_spin_unlock(&ctx->lock); | 1544 | raw_spin_unlock(&ctx->lock); |
1563 | } | 1545 | } |
@@ -1567,9 +1549,6 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) | |||
1567 | */ | 1549 | */ |
1568 | static void rotate_ctx(struct perf_event_context *ctx) | 1550 | static void rotate_ctx(struct perf_event_context *ctx) |
1569 | { | 1551 | { |
1570 | if (!ctx->nr_events) | ||
1571 | return; | ||
1572 | |||
1573 | raw_spin_lock(&ctx->lock); | 1552 | raw_spin_lock(&ctx->lock); |
1574 | 1553 | ||
1575 | /* Rotate the first entry last of non-pinned groups */ | 1554 | /* Rotate the first entry last of non-pinned groups */ |
@@ -1582,19 +1561,28 @@ void perf_event_task_tick(struct task_struct *curr) | |||
1582 | { | 1561 | { |
1583 | struct perf_cpu_context *cpuctx; | 1562 | struct perf_cpu_context *cpuctx; |
1584 | struct perf_event_context *ctx; | 1563 | struct perf_event_context *ctx; |
1564 | int rotate = 0; | ||
1585 | 1565 | ||
1586 | if (!atomic_read(&nr_events)) | 1566 | if (!atomic_read(&nr_events)) |
1587 | return; | 1567 | return; |
1588 | 1568 | ||
1589 | cpuctx = &__get_cpu_var(perf_cpu_context); | 1569 | cpuctx = &__get_cpu_var(perf_cpu_context); |
1590 | ctx = curr->perf_event_ctxp; | 1570 | if (cpuctx->ctx.nr_events && |
1571 | cpuctx->ctx.nr_events != cpuctx->ctx.nr_active) | ||
1572 | rotate = 1; | ||
1591 | 1573 | ||
1592 | perf_disable(); | 1574 | ctx = curr->perf_event_ctxp; |
1575 | if (ctx && ctx->nr_events && ctx->nr_events != ctx->nr_active) | ||
1576 | rotate = 1; | ||
1593 | 1577 | ||
1594 | perf_ctx_adjust_freq(&cpuctx->ctx); | 1578 | perf_ctx_adjust_freq(&cpuctx->ctx); |
1595 | if (ctx) | 1579 | if (ctx) |
1596 | perf_ctx_adjust_freq(ctx); | 1580 | perf_ctx_adjust_freq(ctx); |
1597 | 1581 | ||
1582 | if (!rotate) | ||
1583 | return; | ||
1584 | |||
1585 | perf_disable(); | ||
1598 | cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); | 1586 | cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); |
1599 | if (ctx) | 1587 | if (ctx) |
1600 | task_ctx_sched_out(ctx, EVENT_FLEXIBLE); | 1588 | task_ctx_sched_out(ctx, EVENT_FLEXIBLE); |
@@ -1606,7 +1594,6 @@ void perf_event_task_tick(struct task_struct *curr) | |||
1606 | cpu_ctx_sched_in(cpuctx, EVENT_FLEXIBLE); | 1594 | cpu_ctx_sched_in(cpuctx, EVENT_FLEXIBLE); |
1607 | if (ctx) | 1595 | if (ctx) |
1608 | task_ctx_sched_in(curr, EVENT_FLEXIBLE); | 1596 | task_ctx_sched_in(curr, EVENT_FLEXIBLE); |
1609 | |||
1610 | perf_enable(); | 1597 | perf_enable(); |
1611 | } | 1598 | } |
1612 | 1599 | ||
@@ -2602,7 +2589,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) | |||
2602 | if (user_locked > user_lock_limit) | 2589 | if (user_locked > user_lock_limit) |
2603 | extra = user_locked - user_lock_limit; | 2590 | extra = user_locked - user_lock_limit; |
2604 | 2591 | ||
2605 | lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; | 2592 | lock_limit = rlimit(RLIMIT_MEMLOCK); |
2606 | lock_limit >>= PAGE_SHIFT; | 2593 | lock_limit >>= PAGE_SHIFT; |
2607 | locked = vma->vm_mm->locked_vm + extra; | 2594 | locked = vma->vm_mm->locked_vm + extra; |
2608 | 2595 | ||
@@ -2798,6 +2785,12 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | |||
2798 | return NULL; | 2785 | return NULL; |
2799 | } | 2786 | } |
2800 | 2787 | ||
2788 | __weak | ||
2789 | void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) | ||
2790 | { | ||
2791 | } | ||
2792 | |||
2793 | |||
2801 | /* | 2794 | /* |
2802 | * Output | 2795 | * Output |
2803 | */ | 2796 | */ |
@@ -3383,15 +3376,23 @@ static void perf_event_task_output(struct perf_event *event, | |||
3383 | struct perf_task_event *task_event) | 3376 | struct perf_task_event *task_event) |
3384 | { | 3377 | { |
3385 | struct perf_output_handle handle; | 3378 | struct perf_output_handle handle; |
3386 | int size; | ||
3387 | struct task_struct *task = task_event->task; | 3379 | struct task_struct *task = task_event->task; |
3388 | 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); | ||
3389 | 3388 | ||
3390 | size = task_event->event_id.header.size; | 3389 | size = task_event->event_id.header.size; |
3391 | ret = perf_output_begin(&handle, event, size, 0, 0); | 3390 | ret = perf_output_begin(&handle, event, size, 0, 0); |
3392 | 3391 | ||
3393 | if (ret) | 3392 | if (ret) { |
3393 | local_irq_restore(flags); | ||
3394 | return; | 3394 | return; |
3395 | } | ||
3395 | 3396 | ||
3396 | task_event->event_id.pid = perf_event_pid(event, task); | 3397 | task_event->event_id.pid = perf_event_pid(event, task); |
3397 | task_event->event_id.ppid = perf_event_pid(event, current); | 3398 | task_event->event_id.ppid = perf_event_pid(event, current); |
@@ -3399,16 +3400,15 @@ static void perf_event_task_output(struct perf_event *event, | |||
3399 | task_event->event_id.tid = perf_event_tid(event, task); | 3400 | task_event->event_id.tid = perf_event_tid(event, task); |
3400 | task_event->event_id.ptid = perf_event_tid(event, current); | 3401 | task_event->event_id.ptid = perf_event_tid(event, current); |
3401 | 3402 | ||
3402 | task_event->event_id.time = perf_clock(); | ||
3403 | |||
3404 | perf_output_put(&handle, task_event->event_id); | 3403 | perf_output_put(&handle, task_event->event_id); |
3405 | 3404 | ||
3406 | perf_output_end(&handle); | 3405 | perf_output_end(&handle); |
3406 | local_irq_restore(flags); | ||
3407 | } | 3407 | } |
3408 | 3408 | ||
3409 | static int perf_event_task_match(struct perf_event *event) | 3409 | static int perf_event_task_match(struct perf_event *event) |
3410 | { | 3410 | { |
3411 | if (event->state != PERF_EVENT_STATE_ACTIVE) | 3411 | if (event->state < PERF_EVENT_STATE_INACTIVE) |
3412 | return 0; | 3412 | return 0; |
3413 | 3413 | ||
3414 | if (event->cpu != -1 && event->cpu != smp_processor_id()) | 3414 | if (event->cpu != -1 && event->cpu != smp_processor_id()) |
@@ -3440,7 +3440,7 @@ static void perf_event_task_event(struct perf_task_event *task_event) | |||
3440 | cpuctx = &get_cpu_var(perf_cpu_context); | 3440 | cpuctx = &get_cpu_var(perf_cpu_context); |
3441 | perf_event_task_ctx(&cpuctx->ctx, task_event); | 3441 | perf_event_task_ctx(&cpuctx->ctx, task_event); |
3442 | if (!ctx) | 3442 | if (!ctx) |
3443 | ctx = rcu_dereference(task_event->task->perf_event_ctxp); | 3443 | ctx = rcu_dereference(current->perf_event_ctxp); |
3444 | if (ctx) | 3444 | if (ctx) |
3445 | perf_event_task_ctx(ctx, task_event); | 3445 | perf_event_task_ctx(ctx, task_event); |
3446 | put_cpu_var(perf_cpu_context); | 3446 | put_cpu_var(perf_cpu_context); |
@@ -3471,6 +3471,7 @@ static void perf_event_task(struct task_struct *task, | |||
3471 | /* .ppid */ | 3471 | /* .ppid */ |
3472 | /* .tid */ | 3472 | /* .tid */ |
3473 | /* .ptid */ | 3473 | /* .ptid */ |
3474 | .time = perf_clock(), | ||
3474 | }, | 3475 | }, |
3475 | }; | 3476 | }; |
3476 | 3477 | ||
@@ -3520,7 +3521,7 @@ static void perf_event_comm_output(struct perf_event *event, | |||
3520 | 3521 | ||
3521 | static int perf_event_comm_match(struct perf_event *event) | 3522 | static int perf_event_comm_match(struct perf_event *event) |
3522 | { | 3523 | { |
3523 | if (event->state != PERF_EVENT_STATE_ACTIVE) | 3524 | if (event->state < PERF_EVENT_STATE_INACTIVE) |
3524 | return 0; | 3525 | return 0; |
3525 | 3526 | ||
3526 | if (event->cpu != -1 && event->cpu != smp_processor_id()) | 3527 | if (event->cpu != -1 && event->cpu != smp_processor_id()) |
@@ -3640,7 +3641,7 @@ static void perf_event_mmap_output(struct perf_event *event, | |||
3640 | static int perf_event_mmap_match(struct perf_event *event, | 3641 | static int perf_event_mmap_match(struct perf_event *event, |
3641 | struct perf_mmap_event *mmap_event) | 3642 | struct perf_mmap_event *mmap_event) |
3642 | { | 3643 | { |
3643 | if (event->state != PERF_EVENT_STATE_ACTIVE) | 3644 | if (event->state < PERF_EVENT_STATE_INACTIVE) |
3644 | return 0; | 3645 | return 0; |
3645 | 3646 | ||
3646 | if (event->cpu != -1 && event->cpu != smp_processor_id()) | 3647 | if (event->cpu != -1 && event->cpu != smp_processor_id()) |
@@ -3749,7 +3750,7 @@ void __perf_event_mmap(struct vm_area_struct *vma) | |||
3749 | /* .tid */ | 3750 | /* .tid */ |
3750 | .start = vma->vm_start, | 3751 | .start = vma->vm_start, |
3751 | .len = vma->vm_end - vma->vm_start, | 3752 | .len = vma->vm_end - vma->vm_start, |
3752 | .pgoff = vma->vm_pgoff, | 3753 | .pgoff = (u64)vma->vm_pgoff << PAGE_SHIFT, |
3753 | }, | 3754 | }, |
3754 | }; | 3755 | }; |
3755 | 3756 | ||
@@ -4116,8 +4117,7 @@ void __perf_sw_event(u32 event_id, u64 nr, int nmi, | |||
4116 | if (rctx < 0) | 4117 | if (rctx < 0) |
4117 | return; | 4118 | return; |
4118 | 4119 | ||
4119 | data.addr = addr; | 4120 | perf_sample_data_init(&data, addr); |
4120 | data.raw = NULL; | ||
4121 | 4121 | ||
4122 | do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, nmi, &data, regs); | 4122 | do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, nmi, &data, regs); |
4123 | 4123 | ||
@@ -4162,11 +4162,10 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) | |||
4162 | struct perf_event *event; | 4162 | struct perf_event *event; |
4163 | u64 period; | 4163 | u64 period; |
4164 | 4164 | ||
4165 | event = container_of(hrtimer, struct perf_event, hw.hrtimer); | 4165 | event = container_of(hrtimer, struct perf_event, hw.hrtimer); |
4166 | event->pmu->read(event); | 4166 | event->pmu->read(event); |
4167 | 4167 | ||
4168 | data.addr = 0; | 4168 | perf_sample_data_init(&data, 0); |
4169 | data.raw = NULL; | ||
4170 | data.period = event->hw.last_period; | 4169 | data.period = event->hw.last_period; |
4171 | regs = get_irq_regs(); | 4170 | regs = get_irq_regs(); |
4172 | /* | 4171 | /* |
@@ -4328,26 +4327,20 @@ static const struct pmu perf_ops_task_clock = { | |||
4328 | #ifdef CONFIG_EVENT_TRACING | 4327 | #ifdef CONFIG_EVENT_TRACING |
4329 | 4328 | ||
4330 | void perf_tp_event(int event_id, u64 addr, u64 count, void *record, | 4329 | void perf_tp_event(int event_id, u64 addr, u64 count, void *record, |
4331 | int entry_size) | 4330 | int entry_size, struct pt_regs *regs) |
4332 | { | 4331 | { |
4332 | struct perf_sample_data data; | ||
4333 | struct perf_raw_record raw = { | 4333 | struct perf_raw_record raw = { |
4334 | .size = entry_size, | 4334 | .size = entry_size, |
4335 | .data = record, | 4335 | .data = record, |
4336 | }; | 4336 | }; |
4337 | 4337 | ||
4338 | struct perf_sample_data data = { | 4338 | perf_sample_data_init(&data, addr); |
4339 | .addr = addr, | 4339 | data.raw = &raw; |
4340 | .raw = &raw, | ||
4341 | }; | ||
4342 | |||
4343 | struct pt_regs *regs = get_irq_regs(); | ||
4344 | |||
4345 | if (!regs) | ||
4346 | regs = task_pt_regs(current); | ||
4347 | 4340 | ||
4348 | /* Trace events already protected against recursion */ | 4341 | /* Trace events already protected against recursion */ |
4349 | do_perf_sw_event(PERF_TYPE_TRACEPOINT, event_id, count, 1, | 4342 | do_perf_sw_event(PERF_TYPE_TRACEPOINT, event_id, count, 1, |
4350 | &data, regs); | 4343 | &data, regs); |
4351 | } | 4344 | } |
4352 | EXPORT_SYMBOL_GPL(perf_tp_event); | 4345 | EXPORT_SYMBOL_GPL(perf_tp_event); |
4353 | 4346 | ||
@@ -4363,7 +4356,7 @@ static int perf_tp_event_match(struct perf_event *event, | |||
4363 | 4356 | ||
4364 | static void tp_perf_event_destroy(struct perf_event *event) | 4357 | static void tp_perf_event_destroy(struct perf_event *event) |
4365 | { | 4358 | { |
4366 | ftrace_profile_disable(event->attr.config); | 4359 | perf_trace_disable(event->attr.config); |
4367 | } | 4360 | } |
4368 | 4361 | ||
4369 | static const struct pmu *tp_perf_event_init(struct perf_event *event) | 4362 | static const struct pmu *tp_perf_event_init(struct perf_event *event) |
@@ -4377,7 +4370,7 @@ static const struct pmu *tp_perf_event_init(struct perf_event *event) | |||
4377 | !capable(CAP_SYS_ADMIN)) | 4370 | !capable(CAP_SYS_ADMIN)) |
4378 | return ERR_PTR(-EPERM); | 4371 | return ERR_PTR(-EPERM); |
4379 | 4372 | ||
4380 | if (ftrace_profile_enable(event->attr.config)) | 4373 | if (perf_trace_enable(event->attr.config)) |
4381 | return NULL; | 4374 | return NULL; |
4382 | 4375 | ||
4383 | event->destroy = tp_perf_event_destroy; | 4376 | event->destroy = tp_perf_event_destroy; |
@@ -4456,8 +4449,7 @@ void perf_bp_event(struct perf_event *bp, void *data) | |||
4456 | struct perf_sample_data sample; | 4449 | struct perf_sample_data sample; |
4457 | struct pt_regs *regs = data; | 4450 | struct pt_regs *regs = data; |
4458 | 4451 | ||
4459 | sample.raw = NULL; | 4452 | perf_sample_data_init(&sample, bp->attr.bp_addr); |
4460 | sample.addr = bp->attr.bp_addr; | ||
4461 | 4453 | ||
4462 | if (!perf_exclude_event(bp, regs)) | 4454 | if (!perf_exclude_event(bp, regs)) |
4463 | perf_swevent_add(bp, 1, 1, &sample, regs); | 4455 | perf_swevent_add(bp, 1, 1, &sample, regs); |
@@ -4720,7 +4712,7 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, | |||
4720 | if (attr->type >= PERF_TYPE_MAX) | 4712 | if (attr->type >= PERF_TYPE_MAX) |
4721 | return -EINVAL; | 4713 | return -EINVAL; |
4722 | 4714 | ||
4723 | if (attr->__reserved_1 || attr->__reserved_2) | 4715 | if (attr->__reserved_1) |
4724 | return -EINVAL; | 4716 | return -EINVAL; |
4725 | 4717 | ||
4726 | if (attr->sample_type & ~(PERF_SAMPLE_MAX-1)) | 4718 | if (attr->sample_type & ~(PERF_SAMPLE_MAX-1)) |
@@ -4905,7 +4897,7 @@ err_fput_free_put_context: | |||
4905 | 4897 | ||
4906 | err_free_put_context: | 4898 | err_free_put_context: |
4907 | if (err < 0) | 4899 | if (err < 0) |
4908 | kfree(event); | 4900 | free_event(event); |
4909 | 4901 | ||
4910 | err_put_context: | 4902 | err_put_context: |
4911 | if (err < 0) | 4903 | if (err < 0) |
@@ -5385,18 +5377,26 @@ int perf_event_init_task(struct task_struct *child) | |||
5385 | return ret; | 5377 | return ret; |
5386 | } | 5378 | } |
5387 | 5379 | ||
5380 | static 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 | |||
5388 | static void __cpuinit perf_event_init_cpu(int cpu) | 5391 | static void __cpuinit perf_event_init_cpu(int cpu) |
5389 | { | 5392 | { |
5390 | struct perf_cpu_context *cpuctx; | 5393 | struct perf_cpu_context *cpuctx; |
5391 | 5394 | ||
5392 | cpuctx = &per_cpu(perf_cpu_context, cpu); | 5395 | cpuctx = &per_cpu(perf_cpu_context, cpu); |
5393 | __perf_event_init_context(&cpuctx->ctx, NULL); | ||
5394 | 5396 | ||
5395 | spin_lock(&perf_resource_lock); | 5397 | spin_lock(&perf_resource_lock); |
5396 | cpuctx->max_pertask = perf_max_events - perf_reserved_percpu; | 5398 | cpuctx->max_pertask = perf_max_events - perf_reserved_percpu; |
5397 | spin_unlock(&perf_resource_lock); | 5399 | spin_unlock(&perf_resource_lock); |
5398 | |||
5399 | hw_perf_event_setup(cpu); | ||
5400 | } | 5400 | } |
5401 | 5401 | ||
5402 | #ifdef CONFIG_HOTPLUG_CPU | 5402 | #ifdef CONFIG_HOTPLUG_CPU |
@@ -5436,11 +5436,6 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) | |||
5436 | perf_event_init_cpu(cpu); | 5436 | perf_event_init_cpu(cpu); |
5437 | break; | 5437 | break; |
5438 | 5438 | ||
5439 | case CPU_ONLINE: | ||
5440 | case CPU_ONLINE_FROZEN: | ||
5441 | hw_perf_event_setup_online(cpu); | ||
5442 | break; | ||
5443 | |||
5444 | case CPU_DOWN_PREPARE: | 5439 | case CPU_DOWN_PREPARE: |
5445 | case CPU_DOWN_PREPARE_FROZEN: | 5440 | case CPU_DOWN_PREPARE_FROZEN: |
5446 | perf_event_exit_cpu(cpu); | 5441 | perf_event_exit_cpu(cpu); |
@@ -5463,6 +5458,7 @@ static struct notifier_block __cpuinitdata perf_cpu_nb = { | |||
5463 | 5458 | ||
5464 | void __init perf_event_init(void) | 5459 | void __init perf_event_init(void) |
5465 | { | 5460 | { |
5461 | perf_event_init_all_cpus(); | ||
5466 | perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE, | 5462 | perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE, |
5467 | (void *)(long)smp_processor_id()); | 5463 | (void *)(long)smp_processor_id()); |
5468 | perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE, | 5464 | perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE, |
@@ -5470,13 +5466,16 @@ void __init perf_event_init(void) | |||
5470 | register_cpu_notifier(&perf_cpu_nb); | 5466 | register_cpu_notifier(&perf_cpu_nb); |
5471 | } | 5467 | } |
5472 | 5468 | ||
5473 | static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, char *buf) | 5469 | static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, |
5470 | struct sysdev_class_attribute *attr, | ||
5471 | char *buf) | ||
5474 | { | 5472 | { |
5475 | return sprintf(buf, "%d\n", perf_reserved_percpu); | 5473 | return sprintf(buf, "%d\n", perf_reserved_percpu); |
5476 | } | 5474 | } |
5477 | 5475 | ||
5478 | static ssize_t | 5476 | static ssize_t |
5479 | perf_set_reserve_percpu(struct sysdev_class *class, | 5477 | perf_set_reserve_percpu(struct sysdev_class *class, |
5478 | struct sysdev_class_attribute *attr, | ||
5480 | const char *buf, | 5479 | const char *buf, |
5481 | size_t count) | 5480 | size_t count) |
5482 | { | 5481 | { |
@@ -5505,13 +5504,17 @@ perf_set_reserve_percpu(struct sysdev_class *class, | |||
5505 | return count; | 5504 | return count; |
5506 | } | 5505 | } |
5507 | 5506 | ||
5508 | static ssize_t perf_show_overcommit(struct sysdev_class *class, char *buf) | 5507 | static ssize_t perf_show_overcommit(struct sysdev_class *class, |
5508 | struct sysdev_class_attribute *attr, | ||
5509 | char *buf) | ||
5509 | { | 5510 | { |
5510 | return sprintf(buf, "%d\n", perf_overcommit); | 5511 | return sprintf(buf, "%d\n", perf_overcommit); |
5511 | } | 5512 | } |
5512 | 5513 | ||
5513 | static ssize_t | 5514 | static ssize_t |
5514 | perf_set_overcommit(struct sysdev_class *class, const char *buf, size_t count) | 5515 | perf_set_overcommit(struct sysdev_class *class, |
5516 | struct sysdev_class_attribute *attr, | ||
5517 | const char *buf, size_t count) | ||
5515 | { | 5518 | { |
5516 | unsigned long val; | 5519 | unsigned long val; |
5517 | int err; | 5520 | int err; |