diff options
Diffstat (limited to 'kernel/events/core.c')
-rw-r--r-- | kernel/events/core.c | 174 |
1 files changed, 123 insertions, 51 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index a19550d80ab1..3cfabdf7b942 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -242,18 +242,6 @@ unlock: | |||
242 | return ret; | 242 | return ret; |
243 | } | 243 | } |
244 | 244 | ||
245 | static void event_function_local(struct perf_event *event, event_f func, void *data) | ||
246 | { | ||
247 | struct event_function_struct efs = { | ||
248 | .event = event, | ||
249 | .func = func, | ||
250 | .data = data, | ||
251 | }; | ||
252 | |||
253 | int ret = event_function(&efs); | ||
254 | WARN_ON_ONCE(ret); | ||
255 | } | ||
256 | |||
257 | static void event_function_call(struct perf_event *event, event_f func, void *data) | 245 | static void event_function_call(struct perf_event *event, event_f func, void *data) |
258 | { | 246 | { |
259 | struct perf_event_context *ctx = event->ctx; | 247 | struct perf_event_context *ctx = event->ctx; |
@@ -303,6 +291,54 @@ again: | |||
303 | raw_spin_unlock_irq(&ctx->lock); | 291 | raw_spin_unlock_irq(&ctx->lock); |
304 | } | 292 | } |
305 | 293 | ||
294 | /* | ||
295 | * Similar to event_function_call() + event_function(), but hard assumes IRQs | ||
296 | * are already disabled and we're on the right CPU. | ||
297 | */ | ||
298 | static void event_function_local(struct perf_event *event, event_f func, void *data) | ||
299 | { | ||
300 | struct perf_event_context *ctx = event->ctx; | ||
301 | struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); | ||
302 | struct task_struct *task = READ_ONCE(ctx->task); | ||
303 | struct perf_event_context *task_ctx = NULL; | ||
304 | |||
305 | WARN_ON_ONCE(!irqs_disabled()); | ||
306 | |||
307 | if (task) { | ||
308 | if (task == TASK_TOMBSTONE) | ||
309 | return; | ||
310 | |||
311 | task_ctx = ctx; | ||
312 | } | ||
313 | |||
314 | perf_ctx_lock(cpuctx, task_ctx); | ||
315 | |||
316 | task = ctx->task; | ||
317 | if (task == TASK_TOMBSTONE) | ||
318 | goto unlock; | ||
319 | |||
320 | if (task) { | ||
321 | /* | ||
322 | * We must be either inactive or active and the right task, | ||
323 | * otherwise we're screwed, since we cannot IPI to somewhere | ||
324 | * else. | ||
325 | */ | ||
326 | if (ctx->is_active) { | ||
327 | if (WARN_ON_ONCE(task != current)) | ||
328 | goto unlock; | ||
329 | |||
330 | if (WARN_ON_ONCE(cpuctx->task_ctx != ctx)) | ||
331 | goto unlock; | ||
332 | } | ||
333 | } else { | ||
334 | WARN_ON_ONCE(&cpuctx->ctx != ctx); | ||
335 | } | ||
336 | |||
337 | func(event, cpuctx, ctx, data); | ||
338 | unlock: | ||
339 | perf_ctx_unlock(cpuctx, task_ctx); | ||
340 | } | ||
341 | |||
306 | #define PERF_FLAG_ALL (PERF_FLAG_FD_NO_GROUP |\ | 342 | #define PERF_FLAG_ALL (PERF_FLAG_FD_NO_GROUP |\ |
307 | PERF_FLAG_FD_OUTPUT |\ | 343 | PERF_FLAG_FD_OUTPUT |\ |
308 | PERF_FLAG_PID_CGROUP |\ | 344 | PERF_FLAG_PID_CGROUP |\ |
@@ -843,6 +879,32 @@ perf_cgroup_mark_enabled(struct perf_event *event, | |||
843 | } | 879 | } |
844 | } | 880 | } |
845 | } | 881 | } |
882 | |||
883 | /* | ||
884 | * Update cpuctx->cgrp so that it is set when first cgroup event is added and | ||
885 | * cleared when last cgroup event is removed. | ||
886 | */ | ||
887 | static inline void | ||
888 | list_update_cgroup_event(struct perf_event *event, | ||
889 | struct perf_event_context *ctx, bool add) | ||
890 | { | ||
891 | struct perf_cpu_context *cpuctx; | ||
892 | |||
893 | if (!is_cgroup_event(event)) | ||
894 | return; | ||
895 | |||
896 | if (add && ctx->nr_cgroups++) | ||
897 | return; | ||
898 | else if (!add && --ctx->nr_cgroups) | ||
899 | return; | ||
900 | /* | ||
901 | * Because cgroup events are always per-cpu events, | ||
902 | * this will always be called from the right CPU. | ||
903 | */ | ||
904 | cpuctx = __get_cpu_context(ctx); | ||
905 | cpuctx->cgrp = add ? event->cgrp : NULL; | ||
906 | } | ||
907 | |||
846 | #else /* !CONFIG_CGROUP_PERF */ | 908 | #else /* !CONFIG_CGROUP_PERF */ |
847 | 909 | ||
848 | static inline bool | 910 | static inline bool |
@@ -920,6 +982,13 @@ perf_cgroup_mark_enabled(struct perf_event *event, | |||
920 | struct perf_event_context *ctx) | 982 | struct perf_event_context *ctx) |
921 | { | 983 | { |
922 | } | 984 | } |
985 | |||
986 | static inline void | ||
987 | list_update_cgroup_event(struct perf_event *event, | ||
988 | struct perf_event_context *ctx, bool add) | ||
989 | { | ||
990 | } | ||
991 | |||
923 | #endif | 992 | #endif |
924 | 993 | ||
925 | /* | 994 | /* |
@@ -1392,6 +1461,7 @@ ctx_group_list(struct perf_event *event, struct perf_event_context *ctx) | |||
1392 | static void | 1461 | static void |
1393 | list_add_event(struct perf_event *event, struct perf_event_context *ctx) | 1462 | list_add_event(struct perf_event *event, struct perf_event_context *ctx) |
1394 | { | 1463 | { |
1464 | |||
1395 | lockdep_assert_held(&ctx->lock); | 1465 | lockdep_assert_held(&ctx->lock); |
1396 | 1466 | ||
1397 | WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT); | 1467 | WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT); |
@@ -1412,8 +1482,7 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx) | |||
1412 | list_add_tail(&event->group_entry, list); | 1482 | list_add_tail(&event->group_entry, list); |
1413 | } | 1483 | } |
1414 | 1484 | ||
1415 | if (is_cgroup_event(event)) | 1485 | list_update_cgroup_event(event, ctx, true); |
1416 | ctx->nr_cgroups++; | ||
1417 | 1486 | ||
1418 | list_add_rcu(&event->event_entry, &ctx->event_list); | 1487 | list_add_rcu(&event->event_entry, &ctx->event_list); |
1419 | ctx->nr_events++; | 1488 | ctx->nr_events++; |
@@ -1581,8 +1650,6 @@ static void perf_group_attach(struct perf_event *event) | |||
1581 | static void | 1650 | static void |
1582 | list_del_event(struct perf_event *event, struct perf_event_context *ctx) | 1651 | list_del_event(struct perf_event *event, struct perf_event_context *ctx) |
1583 | { | 1652 | { |
1584 | struct perf_cpu_context *cpuctx; | ||
1585 | |||
1586 | WARN_ON_ONCE(event->ctx != ctx); | 1653 | WARN_ON_ONCE(event->ctx != ctx); |
1587 | lockdep_assert_held(&ctx->lock); | 1654 | lockdep_assert_held(&ctx->lock); |
1588 | 1655 | ||
@@ -1594,20 +1661,7 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx) | |||
1594 | 1661 | ||
1595 | event->attach_state &= ~PERF_ATTACH_CONTEXT; | 1662 | event->attach_state &= ~PERF_ATTACH_CONTEXT; |
1596 | 1663 | ||
1597 | if (is_cgroup_event(event)) { | 1664 | list_update_cgroup_event(event, ctx, false); |
1598 | ctx->nr_cgroups--; | ||
1599 | /* | ||
1600 | * Because cgroup events are always per-cpu events, this will | ||
1601 | * always be called from the right CPU. | ||
1602 | */ | ||
1603 | cpuctx = __get_cpu_context(ctx); | ||
1604 | /* | ||
1605 | * If there are no more cgroup events then clear cgrp to avoid | ||
1606 | * stale pointer in update_cgrp_time_from_cpuctx(). | ||
1607 | */ | ||
1608 | if (!ctx->nr_cgroups) | ||
1609 | cpuctx->cgrp = NULL; | ||
1610 | } | ||
1611 | 1665 | ||
1612 | ctx->nr_events--; | 1666 | ctx->nr_events--; |
1613 | if (event->attr.inherit_stat) | 1667 | if (event->attr.inherit_stat) |
@@ -1716,8 +1770,8 @@ static inline int pmu_filter_match(struct perf_event *event) | |||
1716 | static inline int | 1770 | static inline int |
1717 | event_filter_match(struct perf_event *event) | 1771 | event_filter_match(struct perf_event *event) |
1718 | { | 1772 | { |
1719 | return (event->cpu == -1 || event->cpu == smp_processor_id()) | 1773 | return (event->cpu == -1 || event->cpu == smp_processor_id()) && |
1720 | && perf_cgroup_match(event) && pmu_filter_match(event); | 1774 | perf_cgroup_match(event) && pmu_filter_match(event); |
1721 | } | 1775 | } |
1722 | 1776 | ||
1723 | static void | 1777 | static void |
@@ -1737,8 +1791,8 @@ event_sched_out(struct perf_event *event, | |||
1737 | * maintained, otherwise bogus information is return | 1791 | * maintained, otherwise bogus information is return |
1738 | * via read() for time_enabled, time_running: | 1792 | * via read() for time_enabled, time_running: |
1739 | */ | 1793 | */ |
1740 | if (event->state == PERF_EVENT_STATE_INACTIVE | 1794 | if (event->state == PERF_EVENT_STATE_INACTIVE && |
1741 | && !event_filter_match(event)) { | 1795 | !event_filter_match(event)) { |
1742 | delta = tstamp - event->tstamp_stopped; | 1796 | delta = tstamp - event->tstamp_stopped; |
1743 | event->tstamp_running += delta; | 1797 | event->tstamp_running += delta; |
1744 | event->tstamp_stopped = tstamp; | 1798 | event->tstamp_stopped = tstamp; |
@@ -2236,10 +2290,15 @@ perf_install_in_context(struct perf_event_context *ctx, | |||
2236 | 2290 | ||
2237 | lockdep_assert_held(&ctx->mutex); | 2291 | lockdep_assert_held(&ctx->mutex); |
2238 | 2292 | ||
2239 | event->ctx = ctx; | ||
2240 | if (event->cpu != -1) | 2293 | if (event->cpu != -1) |
2241 | event->cpu = cpu; | 2294 | event->cpu = cpu; |
2242 | 2295 | ||
2296 | /* | ||
2297 | * Ensures that if we can observe event->ctx, both the event and ctx | ||
2298 | * will be 'complete'. See perf_iterate_sb_cpu(). | ||
2299 | */ | ||
2300 | smp_store_release(&event->ctx, ctx); | ||
2301 | |||
2243 | if (!task) { | 2302 | if (!task) { |
2244 | cpu_function_call(cpu, __perf_install_in_context, event); | 2303 | cpu_function_call(cpu, __perf_install_in_context, event); |
2245 | return; | 2304 | return; |
@@ -3490,9 +3549,10 @@ static int perf_event_read(struct perf_event *event, bool group) | |||
3490 | .group = group, | 3549 | .group = group, |
3491 | .ret = 0, | 3550 | .ret = 0, |
3492 | }; | 3551 | }; |
3493 | smp_call_function_single(event->oncpu, | 3552 | ret = smp_call_function_single(event->oncpu, __perf_event_read, &data, 1); |
3494 | __perf_event_read, &data, 1); | 3553 | /* The event must have been read from an online CPU: */ |
3495 | ret = data.ret; | 3554 | WARN_ON_ONCE(ret); |
3555 | ret = ret ? : data.ret; | ||
3496 | } else if (event->state == PERF_EVENT_STATE_INACTIVE) { | 3556 | } else if (event->state == PERF_EVENT_STATE_INACTIVE) { |
3497 | struct perf_event_context *ctx = event->ctx; | 3557 | struct perf_event_context *ctx = event->ctx; |
3498 | unsigned long flags; | 3558 | unsigned long flags; |
@@ -5969,6 +6029,14 @@ static void perf_iterate_sb_cpu(perf_iterate_f output, void *data) | |||
5969 | struct perf_event *event; | 6029 | struct perf_event *event; |
5970 | 6030 | ||
5971 | list_for_each_entry_rcu(event, &pel->list, sb_list) { | 6031 | list_for_each_entry_rcu(event, &pel->list, sb_list) { |
6032 | /* | ||
6033 | * Skip events that are not fully formed yet; ensure that | ||
6034 | * if we observe event->ctx, both event and ctx will be | ||
6035 | * complete enough. See perf_install_in_context(). | ||
6036 | */ | ||
6037 | if (!smp_load_acquire(&event->ctx)) | ||
6038 | continue; | ||
6039 | |||
5972 | if (event->state < PERF_EVENT_STATE_INACTIVE) | 6040 | if (event->state < PERF_EVENT_STATE_INACTIVE) |
5973 | continue; | 6041 | continue; |
5974 | if (!event_filter_match(event)) | 6042 | if (!event_filter_match(event)) |
@@ -6098,7 +6166,7 @@ static int __perf_pmu_output_stop(void *info) | |||
6098 | { | 6166 | { |
6099 | struct perf_event *event = info; | 6167 | struct perf_event *event = info; |
6100 | struct pmu *pmu = event->pmu; | 6168 | struct pmu *pmu = event->pmu; |
6101 | struct perf_cpu_context *cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | 6169 | struct perf_cpu_context *cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); |
6102 | struct remote_output ro = { | 6170 | struct remote_output ro = { |
6103 | .rb = event->rb, | 6171 | .rb = event->rb, |
6104 | }; | 6172 | }; |
@@ -6553,15 +6621,6 @@ got_name: | |||
6553 | } | 6621 | } |
6554 | 6622 | ||
6555 | /* | 6623 | /* |
6556 | * Whether this @filter depends on a dynamic object which is not loaded | ||
6557 | * yet or its load addresses are not known. | ||
6558 | */ | ||
6559 | static bool perf_addr_filter_needs_mmap(struct perf_addr_filter *filter) | ||
6560 | { | ||
6561 | return filter->filter && filter->inode; | ||
6562 | } | ||
6563 | |||
6564 | /* | ||
6565 | * Check whether inode and address range match filter criteria. | 6624 | * Check whether inode and address range match filter criteria. |
6566 | */ | 6625 | */ |
6567 | static bool perf_addr_filter_match(struct perf_addr_filter *filter, | 6626 | static bool perf_addr_filter_match(struct perf_addr_filter *filter, |
@@ -6622,6 +6681,13 @@ static void perf_addr_filters_adjust(struct vm_area_struct *vma) | |||
6622 | struct perf_event_context *ctx; | 6681 | struct perf_event_context *ctx; |
6623 | int ctxn; | 6682 | int ctxn; |
6624 | 6683 | ||
6684 | /* | ||
6685 | * Data tracing isn't supported yet and as such there is no need | ||
6686 | * to keep track of anything that isn't related to executable code: | ||
6687 | */ | ||
6688 | if (!(vma->vm_flags & VM_EXEC)) | ||
6689 | return; | ||
6690 | |||
6625 | rcu_read_lock(); | 6691 | rcu_read_lock(); |
6626 | for_each_task_context_nr(ctxn) { | 6692 | for_each_task_context_nr(ctxn) { |
6627 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); | 6693 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); |
@@ -7774,7 +7840,11 @@ static void perf_event_addr_filters_apply(struct perf_event *event) | |||
7774 | list_for_each_entry(filter, &ifh->list, entry) { | 7840 | list_for_each_entry(filter, &ifh->list, entry) { |
7775 | event->addr_filters_offs[count] = 0; | 7841 | event->addr_filters_offs[count] = 0; |
7776 | 7842 | ||
7777 | if (perf_addr_filter_needs_mmap(filter)) | 7843 | /* |
7844 | * Adjust base offset if the filter is associated to a binary | ||
7845 | * that needs to be mapped: | ||
7846 | */ | ||
7847 | if (filter->inode) | ||
7778 | event->addr_filters_offs[count] = | 7848 | event->addr_filters_offs[count] = |
7779 | perf_addr_filter_apply(filter, mm); | 7849 | perf_addr_filter_apply(filter, mm); |
7780 | 7850 | ||
@@ -7905,8 +7975,10 @@ perf_event_parse_addr_filter(struct perf_event *event, char *fstr, | |||
7905 | goto fail; | 7975 | goto fail; |
7906 | } | 7976 | } |
7907 | 7977 | ||
7908 | if (token == IF_SRC_FILE) { | 7978 | if (token == IF_SRC_FILE || token == IF_SRC_FILEADDR) { |
7909 | filename = match_strdup(&args[2]); | 7979 | int fpos = filter->range ? 2 : 1; |
7980 | |||
7981 | filename = match_strdup(&args[fpos]); | ||
7910 | if (!filename) { | 7982 | if (!filename) { |
7911 | ret = -ENOMEM; | 7983 | ret = -ENOMEM; |
7912 | goto fail; | 7984 | goto fail; |