diff options
Diffstat (limited to 'kernel/events/core.c')
-rw-r--r-- | kernel/events/core.c | 416 |
1 files changed, 261 insertions, 155 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index eba8fb5834ae..2207efc941d1 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -145,6 +145,7 @@ static DEFINE_PER_CPU(atomic_t, perf_branch_stack_events); | |||
145 | static atomic_t nr_mmap_events __read_mostly; | 145 | static atomic_t nr_mmap_events __read_mostly; |
146 | static atomic_t nr_comm_events __read_mostly; | 146 | static atomic_t nr_comm_events __read_mostly; |
147 | static atomic_t nr_task_events __read_mostly; | 147 | static atomic_t nr_task_events __read_mostly; |
148 | static atomic_t nr_freq_events __read_mostly; | ||
148 | 149 | ||
149 | static LIST_HEAD(pmus); | 150 | static LIST_HEAD(pmus); |
150 | static DEFINE_MUTEX(pmus_lock); | 151 | static DEFINE_MUTEX(pmus_lock); |
@@ -340,8 +341,8 @@ struct perf_cgroup { | |||
340 | static inline struct perf_cgroup * | 341 | static inline struct perf_cgroup * |
341 | perf_cgroup_from_task(struct task_struct *task) | 342 | perf_cgroup_from_task(struct task_struct *task) |
342 | { | 343 | { |
343 | return container_of(task_subsys_state(task, perf_subsys_id), | 344 | return container_of(task_css(task, perf_subsys_id), |
344 | struct perf_cgroup, css); | 345 | struct perf_cgroup, css); |
345 | } | 346 | } |
346 | 347 | ||
347 | static inline bool | 348 | static inline bool |
@@ -591,7 +592,9 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, | |||
591 | if (!f.file) | 592 | if (!f.file) |
592 | return -EBADF; | 593 | return -EBADF; |
593 | 594 | ||
594 | css = cgroup_css_from_dir(f.file, perf_subsys_id); | 595 | rcu_read_lock(); |
596 | |||
597 | css = css_from_dir(f.file->f_dentry, &perf_subsys); | ||
595 | if (IS_ERR(css)) { | 598 | if (IS_ERR(css)) { |
596 | ret = PTR_ERR(css); | 599 | ret = PTR_ERR(css); |
597 | goto out; | 600 | goto out; |
@@ -617,6 +620,7 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, | |||
617 | ret = -EINVAL; | 620 | ret = -EINVAL; |
618 | } | 621 | } |
619 | out: | 622 | out: |
623 | rcu_read_unlock(); | ||
620 | fdput(f); | 624 | fdput(f); |
621 | return ret; | 625 | return ret; |
622 | } | 626 | } |
@@ -869,12 +873,8 @@ static void perf_pmu_rotate_start(struct pmu *pmu) | |||
869 | 873 | ||
870 | WARN_ON(!irqs_disabled()); | 874 | WARN_ON(!irqs_disabled()); |
871 | 875 | ||
872 | if (list_empty(&cpuctx->rotation_list)) { | 876 | if (list_empty(&cpuctx->rotation_list)) |
873 | int was_empty = list_empty(head); | ||
874 | list_add(&cpuctx->rotation_list, head); | 877 | list_add(&cpuctx->rotation_list, head); |
875 | if (was_empty) | ||
876 | tick_nohz_full_kick(); | ||
877 | } | ||
878 | } | 878 | } |
879 | 879 | ||
880 | static void get_ctx(struct perf_event_context *ctx) | 880 | static void get_ctx(struct perf_event_context *ctx) |
@@ -1216,6 +1216,9 @@ static void perf_event__id_header_size(struct perf_event *event) | |||
1216 | if (sample_type & PERF_SAMPLE_TIME) | 1216 | if (sample_type & PERF_SAMPLE_TIME) |
1217 | size += sizeof(data->time); | 1217 | size += sizeof(data->time); |
1218 | 1218 | ||
1219 | if (sample_type & PERF_SAMPLE_IDENTIFIER) | ||
1220 | size += sizeof(data->id); | ||
1221 | |||
1219 | if (sample_type & PERF_SAMPLE_ID) | 1222 | if (sample_type & PERF_SAMPLE_ID) |
1220 | size += sizeof(data->id); | 1223 | size += sizeof(data->id); |
1221 | 1224 | ||
@@ -2712,7 +2715,7 @@ static void perf_adjust_freq_unthr_context(struct perf_event_context *ctx, | |||
2712 | 2715 | ||
2713 | hwc = &event->hw; | 2716 | hwc = &event->hw; |
2714 | 2717 | ||
2715 | if (needs_unthr && hwc->interrupts == MAX_INTERRUPTS) { | 2718 | if (hwc->interrupts == MAX_INTERRUPTS) { |
2716 | hwc->interrupts = 0; | 2719 | hwc->interrupts = 0; |
2717 | perf_log_throttle(event, 1); | 2720 | perf_log_throttle(event, 1); |
2718 | event->pmu->start(event, 0); | 2721 | event->pmu->start(event, 0); |
@@ -2811,10 +2814,11 @@ done: | |||
2811 | #ifdef CONFIG_NO_HZ_FULL | 2814 | #ifdef CONFIG_NO_HZ_FULL |
2812 | bool perf_event_can_stop_tick(void) | 2815 | bool perf_event_can_stop_tick(void) |
2813 | { | 2816 | { |
2814 | if (list_empty(&__get_cpu_var(rotation_list))) | 2817 | if (atomic_read(&nr_freq_events) || |
2815 | return true; | 2818 | __this_cpu_read(perf_throttled_count)) |
2816 | else | ||
2817 | return false; | 2819 | return false; |
2820 | else | ||
2821 | return true; | ||
2818 | } | 2822 | } |
2819 | #endif | 2823 | #endif |
2820 | 2824 | ||
@@ -3128,36 +3132,63 @@ static void free_event_rcu(struct rcu_head *head) | |||
3128 | static void ring_buffer_put(struct ring_buffer *rb); | 3132 | static void ring_buffer_put(struct ring_buffer *rb); |
3129 | static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb); | 3133 | static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb); |
3130 | 3134 | ||
3131 | static void free_event(struct perf_event *event) | 3135 | static void unaccount_event_cpu(struct perf_event *event, int cpu) |
3132 | { | 3136 | { |
3133 | irq_work_sync(&event->pending); | 3137 | if (event->parent) |
3138 | return; | ||
3139 | |||
3140 | if (has_branch_stack(event)) { | ||
3141 | if (!(event->attach_state & PERF_ATTACH_TASK)) | ||
3142 | atomic_dec(&per_cpu(perf_branch_stack_events, cpu)); | ||
3143 | } | ||
3144 | if (is_cgroup_event(event)) | ||
3145 | atomic_dec(&per_cpu(perf_cgroup_events, cpu)); | ||
3146 | } | ||
3147 | |||
3148 | static void unaccount_event(struct perf_event *event) | ||
3149 | { | ||
3150 | if (event->parent) | ||
3151 | return; | ||
3152 | |||
3153 | if (event->attach_state & PERF_ATTACH_TASK) | ||
3154 | static_key_slow_dec_deferred(&perf_sched_events); | ||
3155 | if (event->attr.mmap || event->attr.mmap_data) | ||
3156 | atomic_dec(&nr_mmap_events); | ||
3157 | if (event->attr.comm) | ||
3158 | atomic_dec(&nr_comm_events); | ||
3159 | if (event->attr.task) | ||
3160 | atomic_dec(&nr_task_events); | ||
3161 | if (event->attr.freq) | ||
3162 | atomic_dec(&nr_freq_events); | ||
3163 | if (is_cgroup_event(event)) | ||
3164 | static_key_slow_dec_deferred(&perf_sched_events); | ||
3165 | if (has_branch_stack(event)) | ||
3166 | static_key_slow_dec_deferred(&perf_sched_events); | ||
3167 | |||
3168 | unaccount_event_cpu(event, event->cpu); | ||
3169 | } | ||
3134 | 3170 | ||
3171 | static void __free_event(struct perf_event *event) | ||
3172 | { | ||
3135 | if (!event->parent) { | 3173 | if (!event->parent) { |
3136 | if (event->attach_state & PERF_ATTACH_TASK) | ||
3137 | static_key_slow_dec_deferred(&perf_sched_events); | ||
3138 | if (event->attr.mmap || event->attr.mmap_data) | ||
3139 | atomic_dec(&nr_mmap_events); | ||
3140 | if (event->attr.comm) | ||
3141 | atomic_dec(&nr_comm_events); | ||
3142 | if (event->attr.task) | ||
3143 | atomic_dec(&nr_task_events); | ||
3144 | if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) | 3174 | if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) |
3145 | put_callchain_buffers(); | 3175 | put_callchain_buffers(); |
3146 | if (is_cgroup_event(event)) { | ||
3147 | atomic_dec(&per_cpu(perf_cgroup_events, event->cpu)); | ||
3148 | static_key_slow_dec_deferred(&perf_sched_events); | ||
3149 | } | ||
3150 | |||
3151 | if (has_branch_stack(event)) { | ||
3152 | static_key_slow_dec_deferred(&perf_sched_events); | ||
3153 | /* is system-wide event */ | ||
3154 | if (!(event->attach_state & PERF_ATTACH_TASK)) { | ||
3155 | atomic_dec(&per_cpu(perf_branch_stack_events, | ||
3156 | event->cpu)); | ||
3157 | } | ||
3158 | } | ||
3159 | } | 3176 | } |
3160 | 3177 | ||
3178 | if (event->destroy) | ||
3179 | event->destroy(event); | ||
3180 | |||
3181 | if (event->ctx) | ||
3182 | put_ctx(event->ctx); | ||
3183 | |||
3184 | call_rcu(&event->rcu_head, free_event_rcu); | ||
3185 | } | ||
3186 | static void free_event(struct perf_event *event) | ||
3187 | { | ||
3188 | irq_work_sync(&event->pending); | ||
3189 | |||
3190 | unaccount_event(event); | ||
3191 | |||
3161 | if (event->rb) { | 3192 | if (event->rb) { |
3162 | struct ring_buffer *rb; | 3193 | struct ring_buffer *rb; |
3163 | 3194 | ||
@@ -3180,13 +3211,8 @@ static void free_event(struct perf_event *event) | |||
3180 | if (is_cgroup_event(event)) | 3211 | if (is_cgroup_event(event)) |
3181 | perf_detach_cgroup(event); | 3212 | perf_detach_cgroup(event); |
3182 | 3213 | ||
3183 | if (event->destroy) | ||
3184 | event->destroy(event); | ||
3185 | 3214 | ||
3186 | if (event->ctx) | 3215 | __free_event(event); |
3187 | put_ctx(event->ctx); | ||
3188 | |||
3189 | call_rcu(&event->rcu_head, free_event_rcu); | ||
3190 | } | 3216 | } |
3191 | 3217 | ||
3192 | int perf_event_release_kernel(struct perf_event *event) | 3218 | int perf_event_release_kernel(struct perf_event *event) |
@@ -3544,6 +3570,15 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3544 | case PERF_EVENT_IOC_PERIOD: | 3570 | case PERF_EVENT_IOC_PERIOD: |
3545 | return perf_event_period(event, (u64 __user *)arg); | 3571 | return perf_event_period(event, (u64 __user *)arg); |
3546 | 3572 | ||
3573 | case PERF_EVENT_IOC_ID: | ||
3574 | { | ||
3575 | u64 id = primary_event_id(event); | ||
3576 | |||
3577 | if (copy_to_user((void __user *)arg, &id, sizeof(id))) | ||
3578 | return -EFAULT; | ||
3579 | return 0; | ||
3580 | } | ||
3581 | |||
3547 | case PERF_EVENT_IOC_SET_OUTPUT: | 3582 | case PERF_EVENT_IOC_SET_OUTPUT: |
3548 | { | 3583 | { |
3549 | int ret; | 3584 | int ret; |
@@ -3641,6 +3676,10 @@ void perf_event_update_userpage(struct perf_event *event) | |||
3641 | u64 enabled, running, now; | 3676 | u64 enabled, running, now; |
3642 | 3677 | ||
3643 | rcu_read_lock(); | 3678 | rcu_read_lock(); |
3679 | rb = rcu_dereference(event->rb); | ||
3680 | if (!rb) | ||
3681 | goto unlock; | ||
3682 | |||
3644 | /* | 3683 | /* |
3645 | * compute total_time_enabled, total_time_running | 3684 | * compute total_time_enabled, total_time_running |
3646 | * based on snapshot values taken when the event | 3685 | * based on snapshot values taken when the event |
@@ -3651,12 +3690,8 @@ void perf_event_update_userpage(struct perf_event *event) | |||
3651 | * NMI context | 3690 | * NMI context |
3652 | */ | 3691 | */ |
3653 | calc_timer_values(event, &now, &enabled, &running); | 3692 | calc_timer_values(event, &now, &enabled, &running); |
3654 | rb = rcu_dereference(event->rb); | ||
3655 | if (!rb) | ||
3656 | goto unlock; | ||
3657 | 3693 | ||
3658 | userpg = rb->user_page; | 3694 | userpg = rb->user_page; |
3659 | |||
3660 | /* | 3695 | /* |
3661 | * Disable preemption so as to not let the corresponding user-space | 3696 | * Disable preemption so as to not let the corresponding user-space |
3662 | * spin too long if we get preempted. | 3697 | * spin too long if we get preempted. |
@@ -4251,7 +4286,7 @@ static void __perf_event_header__init_id(struct perf_event_header *header, | |||
4251 | if (sample_type & PERF_SAMPLE_TIME) | 4286 | if (sample_type & PERF_SAMPLE_TIME) |
4252 | data->time = perf_clock(); | 4287 | data->time = perf_clock(); |
4253 | 4288 | ||
4254 | if (sample_type & PERF_SAMPLE_ID) | 4289 | if (sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER)) |
4255 | data->id = primary_event_id(event); | 4290 | data->id = primary_event_id(event); |
4256 | 4291 | ||
4257 | if (sample_type & PERF_SAMPLE_STREAM_ID) | 4292 | if (sample_type & PERF_SAMPLE_STREAM_ID) |
@@ -4290,6 +4325,9 @@ static void __perf_event__output_id_sample(struct perf_output_handle *handle, | |||
4290 | 4325 | ||
4291 | if (sample_type & PERF_SAMPLE_CPU) | 4326 | if (sample_type & PERF_SAMPLE_CPU) |
4292 | perf_output_put(handle, data->cpu_entry); | 4327 | perf_output_put(handle, data->cpu_entry); |
4328 | |||
4329 | if (sample_type & PERF_SAMPLE_IDENTIFIER) | ||
4330 | perf_output_put(handle, data->id); | ||
4293 | } | 4331 | } |
4294 | 4332 | ||
4295 | void perf_event__output_id_sample(struct perf_event *event, | 4333 | void perf_event__output_id_sample(struct perf_event *event, |
@@ -4355,7 +4393,8 @@ static void perf_output_read_group(struct perf_output_handle *handle, | |||
4355 | list_for_each_entry(sub, &leader->sibling_list, group_entry) { | 4393 | list_for_each_entry(sub, &leader->sibling_list, group_entry) { |
4356 | n = 0; | 4394 | n = 0; |
4357 | 4395 | ||
4358 | if (sub != event) | 4396 | if ((sub != event) && |
4397 | (sub->state == PERF_EVENT_STATE_ACTIVE)) | ||
4359 | sub->pmu->read(sub); | 4398 | sub->pmu->read(sub); |
4360 | 4399 | ||
4361 | values[n++] = perf_event_count(sub); | 4400 | values[n++] = perf_event_count(sub); |
@@ -4402,6 +4441,9 @@ void perf_output_sample(struct perf_output_handle *handle, | |||
4402 | 4441 | ||
4403 | perf_output_put(handle, *header); | 4442 | perf_output_put(handle, *header); |
4404 | 4443 | ||
4444 | if (sample_type & PERF_SAMPLE_IDENTIFIER) | ||
4445 | perf_output_put(handle, data->id); | ||
4446 | |||
4405 | if (sample_type & PERF_SAMPLE_IP) | 4447 | if (sample_type & PERF_SAMPLE_IP) |
4406 | perf_output_put(handle, data->ip); | 4448 | perf_output_put(handle, data->ip); |
4407 | 4449 | ||
@@ -4462,20 +4504,6 @@ void perf_output_sample(struct perf_output_handle *handle, | |||
4462 | } | 4504 | } |
4463 | } | 4505 | } |
4464 | 4506 | ||
4465 | if (!event->attr.watermark) { | ||
4466 | int wakeup_events = event->attr.wakeup_events; | ||
4467 | |||
4468 | if (wakeup_events) { | ||
4469 | struct ring_buffer *rb = handle->rb; | ||
4470 | int events = local_inc_return(&rb->events); | ||
4471 | |||
4472 | if (events >= wakeup_events) { | ||
4473 | local_sub(wakeup_events, &rb->events); | ||
4474 | local_inc(&rb->wakeup); | ||
4475 | } | ||
4476 | } | ||
4477 | } | ||
4478 | |||
4479 | if (sample_type & PERF_SAMPLE_BRANCH_STACK) { | 4507 | if (sample_type & PERF_SAMPLE_BRANCH_STACK) { |
4480 | if (data->br_stack) { | 4508 | if (data->br_stack) { |
4481 | size_t size; | 4509 | size_t size; |
@@ -4511,16 +4539,31 @@ void perf_output_sample(struct perf_output_handle *handle, | |||
4511 | } | 4539 | } |
4512 | } | 4540 | } |
4513 | 4541 | ||
4514 | if (sample_type & PERF_SAMPLE_STACK_USER) | 4542 | if (sample_type & PERF_SAMPLE_STACK_USER) { |
4515 | perf_output_sample_ustack(handle, | 4543 | perf_output_sample_ustack(handle, |
4516 | data->stack_user_size, | 4544 | data->stack_user_size, |
4517 | data->regs_user.regs); | 4545 | data->regs_user.regs); |
4546 | } | ||
4518 | 4547 | ||
4519 | if (sample_type & PERF_SAMPLE_WEIGHT) | 4548 | if (sample_type & PERF_SAMPLE_WEIGHT) |
4520 | perf_output_put(handle, data->weight); | 4549 | perf_output_put(handle, data->weight); |
4521 | 4550 | ||
4522 | if (sample_type & PERF_SAMPLE_DATA_SRC) | 4551 | if (sample_type & PERF_SAMPLE_DATA_SRC) |
4523 | perf_output_put(handle, data->data_src.val); | 4552 | perf_output_put(handle, data->data_src.val); |
4553 | |||
4554 | if (!event->attr.watermark) { | ||
4555 | int wakeup_events = event->attr.wakeup_events; | ||
4556 | |||
4557 | if (wakeup_events) { | ||
4558 | struct ring_buffer *rb = handle->rb; | ||
4559 | int events = local_inc_return(&rb->events); | ||
4560 | |||
4561 | if (events >= wakeup_events) { | ||
4562 | local_sub(wakeup_events, &rb->events); | ||
4563 | local_inc(&rb->wakeup); | ||
4564 | } | ||
4565 | } | ||
4566 | } | ||
4524 | } | 4567 | } |
4525 | 4568 | ||
4526 | void perf_prepare_sample(struct perf_event_header *header, | 4569 | void perf_prepare_sample(struct perf_event_header *header, |
@@ -4680,12 +4723,10 @@ perf_event_read_event(struct perf_event *event, | |||
4680 | perf_output_end(&handle); | 4723 | perf_output_end(&handle); |
4681 | } | 4724 | } |
4682 | 4725 | ||
4683 | typedef int (perf_event_aux_match_cb)(struct perf_event *event, void *data); | ||
4684 | typedef void (perf_event_aux_output_cb)(struct perf_event *event, void *data); | 4726 | typedef void (perf_event_aux_output_cb)(struct perf_event *event, void *data); |
4685 | 4727 | ||
4686 | static void | 4728 | static void |
4687 | perf_event_aux_ctx(struct perf_event_context *ctx, | 4729 | perf_event_aux_ctx(struct perf_event_context *ctx, |
4688 | perf_event_aux_match_cb match, | ||
4689 | perf_event_aux_output_cb output, | 4730 | perf_event_aux_output_cb output, |
4690 | void *data) | 4731 | void *data) |
4691 | { | 4732 | { |
@@ -4696,15 +4737,12 @@ perf_event_aux_ctx(struct perf_event_context *ctx, | |||
4696 | continue; | 4737 | continue; |
4697 | if (!event_filter_match(event)) | 4738 | if (!event_filter_match(event)) |
4698 | continue; | 4739 | continue; |
4699 | if (match(event, data)) | 4740 | output(event, data); |
4700 | output(event, data); | ||
4701 | } | 4741 | } |
4702 | } | 4742 | } |
4703 | 4743 | ||
4704 | static void | 4744 | static void |
4705 | perf_event_aux(perf_event_aux_match_cb match, | 4745 | perf_event_aux(perf_event_aux_output_cb output, void *data, |
4706 | perf_event_aux_output_cb output, | ||
4707 | void *data, | ||
4708 | struct perf_event_context *task_ctx) | 4746 | struct perf_event_context *task_ctx) |
4709 | { | 4747 | { |
4710 | struct perf_cpu_context *cpuctx; | 4748 | struct perf_cpu_context *cpuctx; |
@@ -4717,7 +4755,7 @@ perf_event_aux(perf_event_aux_match_cb match, | |||
4717 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | 4755 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); |
4718 | if (cpuctx->unique_pmu != pmu) | 4756 | if (cpuctx->unique_pmu != pmu) |
4719 | goto next; | 4757 | goto next; |
4720 | perf_event_aux_ctx(&cpuctx->ctx, match, output, data); | 4758 | perf_event_aux_ctx(&cpuctx->ctx, output, data); |
4721 | if (task_ctx) | 4759 | if (task_ctx) |
4722 | goto next; | 4760 | goto next; |
4723 | ctxn = pmu->task_ctx_nr; | 4761 | ctxn = pmu->task_ctx_nr; |
@@ -4725,14 +4763,14 @@ perf_event_aux(perf_event_aux_match_cb match, | |||
4725 | goto next; | 4763 | goto next; |
4726 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); | 4764 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); |
4727 | if (ctx) | 4765 | if (ctx) |
4728 | perf_event_aux_ctx(ctx, match, output, data); | 4766 | perf_event_aux_ctx(ctx, output, data); |
4729 | next: | 4767 | next: |
4730 | put_cpu_ptr(pmu->pmu_cpu_context); | 4768 | put_cpu_ptr(pmu->pmu_cpu_context); |
4731 | } | 4769 | } |
4732 | 4770 | ||
4733 | if (task_ctx) { | 4771 | if (task_ctx) { |
4734 | preempt_disable(); | 4772 | preempt_disable(); |
4735 | perf_event_aux_ctx(task_ctx, match, output, data); | 4773 | perf_event_aux_ctx(task_ctx, output, data); |
4736 | preempt_enable(); | 4774 | preempt_enable(); |
4737 | } | 4775 | } |
4738 | rcu_read_unlock(); | 4776 | rcu_read_unlock(); |
@@ -4741,7 +4779,7 @@ next: | |||
4741 | /* | 4779 | /* |
4742 | * task tracking -- fork/exit | 4780 | * task tracking -- fork/exit |
4743 | * | 4781 | * |
4744 | * enabled by: attr.comm | attr.mmap | attr.mmap_data | attr.task | 4782 | * enabled by: attr.comm | attr.mmap | attr.mmap2 | attr.mmap_data | attr.task |
4745 | */ | 4783 | */ |
4746 | 4784 | ||
4747 | struct perf_task_event { | 4785 | struct perf_task_event { |
@@ -4759,6 +4797,13 @@ struct perf_task_event { | |||
4759 | } event_id; | 4797 | } event_id; |
4760 | }; | 4798 | }; |
4761 | 4799 | ||
4800 | static int perf_event_task_match(struct perf_event *event) | ||
4801 | { | ||
4802 | return event->attr.comm || event->attr.mmap || | ||
4803 | event->attr.mmap2 || event->attr.mmap_data || | ||
4804 | event->attr.task; | ||
4805 | } | ||
4806 | |||
4762 | static void perf_event_task_output(struct perf_event *event, | 4807 | static void perf_event_task_output(struct perf_event *event, |
4763 | void *data) | 4808 | void *data) |
4764 | { | 4809 | { |
@@ -4768,6 +4813,9 @@ static void perf_event_task_output(struct perf_event *event, | |||
4768 | struct task_struct *task = task_event->task; | 4813 | struct task_struct *task = task_event->task; |
4769 | int ret, size = task_event->event_id.header.size; | 4814 | int ret, size = task_event->event_id.header.size; |
4770 | 4815 | ||
4816 | if (!perf_event_task_match(event)) | ||
4817 | return; | ||
4818 | |||
4771 | perf_event_header__init_id(&task_event->event_id.header, &sample, event); | 4819 | perf_event_header__init_id(&task_event->event_id.header, &sample, event); |
4772 | 4820 | ||
4773 | ret = perf_output_begin(&handle, event, | 4821 | ret = perf_output_begin(&handle, event, |
@@ -4790,13 +4838,6 @@ out: | |||
4790 | task_event->event_id.header.size = size; | 4838 | task_event->event_id.header.size = size; |
4791 | } | 4839 | } |
4792 | 4840 | ||
4793 | static int perf_event_task_match(struct perf_event *event, | ||
4794 | void *data __maybe_unused) | ||
4795 | { | ||
4796 | return event->attr.comm || event->attr.mmap || | ||
4797 | event->attr.mmap_data || event->attr.task; | ||
4798 | } | ||
4799 | |||
4800 | static void perf_event_task(struct task_struct *task, | 4841 | static void perf_event_task(struct task_struct *task, |
4801 | struct perf_event_context *task_ctx, | 4842 | struct perf_event_context *task_ctx, |
4802 | int new) | 4843 | int new) |
@@ -4825,8 +4866,7 @@ static void perf_event_task(struct task_struct *task, | |||
4825 | }, | 4866 | }, |
4826 | }; | 4867 | }; |
4827 | 4868 | ||
4828 | perf_event_aux(perf_event_task_match, | 4869 | perf_event_aux(perf_event_task_output, |
4829 | perf_event_task_output, | ||
4830 | &task_event, | 4870 | &task_event, |
4831 | task_ctx); | 4871 | task_ctx); |
4832 | } | 4872 | } |
@@ -4853,6 +4893,11 @@ struct perf_comm_event { | |||
4853 | } event_id; | 4893 | } event_id; |
4854 | }; | 4894 | }; |
4855 | 4895 | ||
4896 | static int perf_event_comm_match(struct perf_event *event) | ||
4897 | { | ||
4898 | return event->attr.comm; | ||
4899 | } | ||
4900 | |||
4856 | static void perf_event_comm_output(struct perf_event *event, | 4901 | static void perf_event_comm_output(struct perf_event *event, |
4857 | void *data) | 4902 | void *data) |
4858 | { | 4903 | { |
@@ -4862,6 +4907,9 @@ static void perf_event_comm_output(struct perf_event *event, | |||
4862 | int size = comm_event->event_id.header.size; | 4907 | int size = comm_event->event_id.header.size; |
4863 | int ret; | 4908 | int ret; |
4864 | 4909 | ||
4910 | if (!perf_event_comm_match(event)) | ||
4911 | return; | ||
4912 | |||
4865 | perf_event_header__init_id(&comm_event->event_id.header, &sample, event); | 4913 | perf_event_header__init_id(&comm_event->event_id.header, &sample, event); |
4866 | ret = perf_output_begin(&handle, event, | 4914 | ret = perf_output_begin(&handle, event, |
4867 | comm_event->event_id.header.size); | 4915 | comm_event->event_id.header.size); |
@@ -4883,12 +4931,6 @@ out: | |||
4883 | comm_event->event_id.header.size = size; | 4931 | comm_event->event_id.header.size = size; |
4884 | } | 4932 | } |
4885 | 4933 | ||
4886 | static int perf_event_comm_match(struct perf_event *event, | ||
4887 | void *data __maybe_unused) | ||
4888 | { | ||
4889 | return event->attr.comm; | ||
4890 | } | ||
4891 | |||
4892 | static void perf_event_comm_event(struct perf_comm_event *comm_event) | 4934 | static void perf_event_comm_event(struct perf_comm_event *comm_event) |
4893 | { | 4935 | { |
4894 | char comm[TASK_COMM_LEN]; | 4936 | char comm[TASK_COMM_LEN]; |
@@ -4903,8 +4945,7 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) | |||
4903 | 4945 | ||
4904 | comm_event->event_id.header.size = sizeof(comm_event->event_id) + size; | 4946 | comm_event->event_id.header.size = sizeof(comm_event->event_id) + size; |
4905 | 4947 | ||
4906 | perf_event_aux(perf_event_comm_match, | 4948 | perf_event_aux(perf_event_comm_output, |
4907 | perf_event_comm_output, | ||
4908 | comm_event, | 4949 | comm_event, |
4909 | NULL); | 4950 | NULL); |
4910 | } | 4951 | } |
@@ -4955,6 +4996,9 @@ struct perf_mmap_event { | |||
4955 | 4996 | ||
4956 | const char *file_name; | 4997 | const char *file_name; |
4957 | int file_size; | 4998 | int file_size; |
4999 | int maj, min; | ||
5000 | u64 ino; | ||
5001 | u64 ino_generation; | ||
4958 | 5002 | ||
4959 | struct { | 5003 | struct { |
4960 | struct perf_event_header header; | 5004 | struct perf_event_header header; |
@@ -4967,6 +5011,17 @@ struct perf_mmap_event { | |||
4967 | } event_id; | 5011 | } event_id; |
4968 | }; | 5012 | }; |
4969 | 5013 | ||
5014 | static int perf_event_mmap_match(struct perf_event *event, | ||
5015 | void *data) | ||
5016 | { | ||
5017 | struct perf_mmap_event *mmap_event = data; | ||
5018 | struct vm_area_struct *vma = mmap_event->vma; | ||
5019 | int executable = vma->vm_flags & VM_EXEC; | ||
5020 | |||
5021 | return (!executable && event->attr.mmap_data) || | ||
5022 | (executable && (event->attr.mmap || event->attr.mmap2)); | ||
5023 | } | ||
5024 | |||
4970 | static void perf_event_mmap_output(struct perf_event *event, | 5025 | static void perf_event_mmap_output(struct perf_event *event, |
4971 | void *data) | 5026 | void *data) |
4972 | { | 5027 | { |
@@ -4976,6 +5031,16 @@ static void perf_event_mmap_output(struct perf_event *event, | |||
4976 | int size = mmap_event->event_id.header.size; | 5031 | int size = mmap_event->event_id.header.size; |
4977 | int ret; | 5032 | int ret; |
4978 | 5033 | ||
5034 | if (!perf_event_mmap_match(event, data)) | ||
5035 | return; | ||
5036 | |||
5037 | if (event->attr.mmap2) { | ||
5038 | mmap_event->event_id.header.type = PERF_RECORD_MMAP2; | ||
5039 | mmap_event->event_id.header.size += sizeof(mmap_event->maj); | ||
5040 | mmap_event->event_id.header.size += sizeof(mmap_event->min); | ||
5041 | mmap_event->event_id.header.size += sizeof(mmap_event->ino); | ||
5042 | } | ||
5043 | |||
4979 | perf_event_header__init_id(&mmap_event->event_id.header, &sample, event); | 5044 | perf_event_header__init_id(&mmap_event->event_id.header, &sample, event); |
4980 | ret = perf_output_begin(&handle, event, | 5045 | ret = perf_output_begin(&handle, event, |
4981 | mmap_event->event_id.header.size); | 5046 | mmap_event->event_id.header.size); |
@@ -4986,6 +5051,14 @@ static void perf_event_mmap_output(struct perf_event *event, | |||
4986 | mmap_event->event_id.tid = perf_event_tid(event, current); | 5051 | mmap_event->event_id.tid = perf_event_tid(event, current); |
4987 | 5052 | ||
4988 | perf_output_put(&handle, mmap_event->event_id); | 5053 | perf_output_put(&handle, mmap_event->event_id); |
5054 | |||
5055 | if (event->attr.mmap2) { | ||
5056 | perf_output_put(&handle, mmap_event->maj); | ||
5057 | perf_output_put(&handle, mmap_event->min); | ||
5058 | perf_output_put(&handle, mmap_event->ino); | ||
5059 | perf_output_put(&handle, mmap_event->ino_generation); | ||
5060 | } | ||
5061 | |||
4989 | __output_copy(&handle, mmap_event->file_name, | 5062 | __output_copy(&handle, mmap_event->file_name, |
4990 | mmap_event->file_size); | 5063 | mmap_event->file_size); |
4991 | 5064 | ||
@@ -4996,21 +5069,12 @@ out: | |||
4996 | mmap_event->event_id.header.size = size; | 5069 | mmap_event->event_id.header.size = size; |
4997 | } | 5070 | } |
4998 | 5071 | ||
4999 | static int perf_event_mmap_match(struct perf_event *event, | ||
5000 | void *data) | ||
5001 | { | ||
5002 | struct perf_mmap_event *mmap_event = data; | ||
5003 | struct vm_area_struct *vma = mmap_event->vma; | ||
5004 | int executable = vma->vm_flags & VM_EXEC; | ||
5005 | |||
5006 | return (!executable && event->attr.mmap_data) || | ||
5007 | (executable && event->attr.mmap); | ||
5008 | } | ||
5009 | |||
5010 | static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | 5072 | static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) |
5011 | { | 5073 | { |
5012 | struct vm_area_struct *vma = mmap_event->vma; | 5074 | struct vm_area_struct *vma = mmap_event->vma; |
5013 | struct file *file = vma->vm_file; | 5075 | struct file *file = vma->vm_file; |
5076 | int maj = 0, min = 0; | ||
5077 | u64 ino = 0, gen = 0; | ||
5014 | unsigned int size; | 5078 | unsigned int size; |
5015 | char tmp[16]; | 5079 | char tmp[16]; |
5016 | char *buf = NULL; | 5080 | char *buf = NULL; |
@@ -5019,6 +5083,8 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | |||
5019 | memset(tmp, 0, sizeof(tmp)); | 5083 | memset(tmp, 0, sizeof(tmp)); |
5020 | 5084 | ||
5021 | if (file) { | 5085 | if (file) { |
5086 | struct inode *inode; | ||
5087 | dev_t dev; | ||
5022 | /* | 5088 | /* |
5023 | * d_path works from the end of the rb backwards, so we | 5089 | * d_path works from the end of the rb backwards, so we |
5024 | * need to add enough zero bytes after the string to handle | 5090 | * need to add enough zero bytes after the string to handle |
@@ -5034,6 +5100,13 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | |||
5034 | name = strncpy(tmp, "//toolong", sizeof(tmp)); | 5100 | name = strncpy(tmp, "//toolong", sizeof(tmp)); |
5035 | goto got_name; | 5101 | goto got_name; |
5036 | } | 5102 | } |
5103 | inode = file_inode(vma->vm_file); | ||
5104 | dev = inode->i_sb->s_dev; | ||
5105 | ino = inode->i_ino; | ||
5106 | gen = inode->i_generation; | ||
5107 | maj = MAJOR(dev); | ||
5108 | min = MINOR(dev); | ||
5109 | |||
5037 | } else { | 5110 | } else { |
5038 | if (arch_vma_name(mmap_event->vma)) { | 5111 | if (arch_vma_name(mmap_event->vma)) { |
5039 | name = strncpy(tmp, arch_vma_name(mmap_event->vma), | 5112 | name = strncpy(tmp, arch_vma_name(mmap_event->vma), |
@@ -5064,14 +5137,17 @@ got_name: | |||
5064 | 5137 | ||
5065 | mmap_event->file_name = name; | 5138 | mmap_event->file_name = name; |
5066 | mmap_event->file_size = size; | 5139 | mmap_event->file_size = size; |
5140 | mmap_event->maj = maj; | ||
5141 | mmap_event->min = min; | ||
5142 | mmap_event->ino = ino; | ||
5143 | mmap_event->ino_generation = gen; | ||
5067 | 5144 | ||
5068 | if (!(vma->vm_flags & VM_EXEC)) | 5145 | if (!(vma->vm_flags & VM_EXEC)) |
5069 | mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA; | 5146 | mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA; |
5070 | 5147 | ||
5071 | mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size; | 5148 | mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size; |
5072 | 5149 | ||
5073 | perf_event_aux(perf_event_mmap_match, | 5150 | perf_event_aux(perf_event_mmap_output, |
5074 | perf_event_mmap_output, | ||
5075 | mmap_event, | 5151 | mmap_event, |
5076 | NULL); | 5152 | NULL); |
5077 | 5153 | ||
@@ -5101,6 +5177,10 @@ void perf_event_mmap(struct vm_area_struct *vma) | |||
5101 | .len = vma->vm_end - vma->vm_start, | 5177 | .len = vma->vm_end - vma->vm_start, |
5102 | .pgoff = (u64)vma->vm_pgoff << PAGE_SHIFT, | 5178 | .pgoff = (u64)vma->vm_pgoff << PAGE_SHIFT, |
5103 | }, | 5179 | }, |
5180 | /* .maj (attr_mmap2 only) */ | ||
5181 | /* .min (attr_mmap2 only) */ | ||
5182 | /* .ino (attr_mmap2 only) */ | ||
5183 | /* .ino_generation (attr_mmap2 only) */ | ||
5104 | }; | 5184 | }; |
5105 | 5185 | ||
5106 | perf_event_mmap_event(&mmap_event); | 5186 | perf_event_mmap_event(&mmap_event); |
@@ -5178,6 +5258,7 @@ static int __perf_event_overflow(struct perf_event *event, | |||
5178 | __this_cpu_inc(perf_throttled_count); | 5258 | __this_cpu_inc(perf_throttled_count); |
5179 | hwc->interrupts = MAX_INTERRUPTS; | 5259 | hwc->interrupts = MAX_INTERRUPTS; |
5180 | perf_log_throttle(event, 0); | 5260 | perf_log_throttle(event, 0); |
5261 | tick_nohz_full_kick(); | ||
5181 | ret = 1; | 5262 | ret = 1; |
5182 | } | 5263 | } |
5183 | } | 5264 | } |
@@ -6234,8 +6315,6 @@ perf_event_mux_interval_ms_store(struct device *dev, | |||
6234 | return count; | 6315 | return count; |
6235 | } | 6316 | } |
6236 | 6317 | ||
6237 | #define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store) | ||
6238 | |||
6239 | static struct device_attribute pmu_dev_attrs[] = { | 6318 | static struct device_attribute pmu_dev_attrs[] = { |
6240 | __ATTR_RO(type), | 6319 | __ATTR_RO(type), |
6241 | __ATTR_RW(perf_event_mux_interval_ms), | 6320 | __ATTR_RW(perf_event_mux_interval_ms), |
@@ -6445,6 +6524,44 @@ unlock: | |||
6445 | return pmu; | 6524 | return pmu; |
6446 | } | 6525 | } |
6447 | 6526 | ||
6527 | static void account_event_cpu(struct perf_event *event, int cpu) | ||
6528 | { | ||
6529 | if (event->parent) | ||
6530 | return; | ||
6531 | |||
6532 | if (has_branch_stack(event)) { | ||
6533 | if (!(event->attach_state & PERF_ATTACH_TASK)) | ||
6534 | atomic_inc(&per_cpu(perf_branch_stack_events, cpu)); | ||
6535 | } | ||
6536 | if (is_cgroup_event(event)) | ||
6537 | atomic_inc(&per_cpu(perf_cgroup_events, cpu)); | ||
6538 | } | ||
6539 | |||
6540 | static void account_event(struct perf_event *event) | ||
6541 | { | ||
6542 | if (event->parent) | ||
6543 | return; | ||
6544 | |||
6545 | if (event->attach_state & PERF_ATTACH_TASK) | ||
6546 | static_key_slow_inc(&perf_sched_events.key); | ||
6547 | if (event->attr.mmap || event->attr.mmap_data) | ||
6548 | atomic_inc(&nr_mmap_events); | ||
6549 | if (event->attr.comm) | ||
6550 | atomic_inc(&nr_comm_events); | ||
6551 | if (event->attr.task) | ||
6552 | atomic_inc(&nr_task_events); | ||
6553 | if (event->attr.freq) { | ||
6554 | if (atomic_inc_return(&nr_freq_events) == 1) | ||
6555 | tick_nohz_full_kick_all(); | ||
6556 | } | ||
6557 | if (has_branch_stack(event)) | ||
6558 | static_key_slow_inc(&perf_sched_events.key); | ||
6559 | if (is_cgroup_event(event)) | ||
6560 | static_key_slow_inc(&perf_sched_events.key); | ||
6561 | |||
6562 | account_event_cpu(event, event->cpu); | ||
6563 | } | ||
6564 | |||
6448 | /* | 6565 | /* |
6449 | * Allocate and initialize a event structure | 6566 | * Allocate and initialize a event structure |
6450 | */ | 6567 | */ |
@@ -6459,7 +6576,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
6459 | struct pmu *pmu; | 6576 | struct pmu *pmu; |
6460 | struct perf_event *event; | 6577 | struct perf_event *event; |
6461 | struct hw_perf_event *hwc; | 6578 | struct hw_perf_event *hwc; |
6462 | long err; | 6579 | long err = -EINVAL; |
6463 | 6580 | ||
6464 | if ((unsigned)cpu >= nr_cpu_ids) { | 6581 | if ((unsigned)cpu >= nr_cpu_ids) { |
6465 | if (!task || cpu != -1) | 6582 | if (!task || cpu != -1) |
@@ -6542,49 +6659,35 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
6542 | * we currently do not support PERF_FORMAT_GROUP on inherited events | 6659 | * we currently do not support PERF_FORMAT_GROUP on inherited events |
6543 | */ | 6660 | */ |
6544 | if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP)) | 6661 | if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP)) |
6545 | goto done; | 6662 | goto err_ns; |
6546 | 6663 | ||
6547 | pmu = perf_init_event(event); | 6664 | pmu = perf_init_event(event); |
6548 | |||
6549 | done: | ||
6550 | err = 0; | ||
6551 | if (!pmu) | 6665 | if (!pmu) |
6552 | err = -EINVAL; | 6666 | goto err_ns; |
6553 | else if (IS_ERR(pmu)) | 6667 | else if (IS_ERR(pmu)) { |
6554 | err = PTR_ERR(pmu); | 6668 | err = PTR_ERR(pmu); |
6555 | 6669 | goto err_ns; | |
6556 | if (err) { | ||
6557 | if (event->ns) | ||
6558 | put_pid_ns(event->ns); | ||
6559 | kfree(event); | ||
6560 | return ERR_PTR(err); | ||
6561 | } | 6670 | } |
6562 | 6671 | ||
6563 | if (!event->parent) { | 6672 | if (!event->parent) { |
6564 | if (event->attach_state & PERF_ATTACH_TASK) | ||
6565 | static_key_slow_inc(&perf_sched_events.key); | ||
6566 | if (event->attr.mmap || event->attr.mmap_data) | ||
6567 | atomic_inc(&nr_mmap_events); | ||
6568 | if (event->attr.comm) | ||
6569 | atomic_inc(&nr_comm_events); | ||
6570 | if (event->attr.task) | ||
6571 | atomic_inc(&nr_task_events); | ||
6572 | if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) { | 6673 | if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) { |
6573 | err = get_callchain_buffers(); | 6674 | err = get_callchain_buffers(); |
6574 | if (err) { | 6675 | if (err) |
6575 | free_event(event); | 6676 | goto err_pmu; |
6576 | return ERR_PTR(err); | ||
6577 | } | ||
6578 | } | ||
6579 | if (has_branch_stack(event)) { | ||
6580 | static_key_slow_inc(&perf_sched_events.key); | ||
6581 | if (!(event->attach_state & PERF_ATTACH_TASK)) | ||
6582 | atomic_inc(&per_cpu(perf_branch_stack_events, | ||
6583 | event->cpu)); | ||
6584 | } | 6677 | } |
6585 | } | 6678 | } |
6586 | 6679 | ||
6587 | return event; | 6680 | return event; |
6681 | |||
6682 | err_pmu: | ||
6683 | if (event->destroy) | ||
6684 | event->destroy(event); | ||
6685 | err_ns: | ||
6686 | if (event->ns) | ||
6687 | put_pid_ns(event->ns); | ||
6688 | kfree(event); | ||
6689 | |||
6690 | return ERR_PTR(err); | ||
6588 | } | 6691 | } |
6589 | 6692 | ||
6590 | static int perf_copy_attr(struct perf_event_attr __user *uattr, | 6693 | static int perf_copy_attr(struct perf_event_attr __user *uattr, |
@@ -6866,17 +6969,14 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6866 | 6969 | ||
6867 | if (flags & PERF_FLAG_PID_CGROUP) { | 6970 | if (flags & PERF_FLAG_PID_CGROUP) { |
6868 | err = perf_cgroup_connect(pid, event, &attr, group_leader); | 6971 | err = perf_cgroup_connect(pid, event, &attr, group_leader); |
6869 | if (err) | 6972 | if (err) { |
6870 | goto err_alloc; | 6973 | __free_event(event); |
6871 | /* | 6974 | goto err_task; |
6872 | * one more event: | 6975 | } |
6873 | * - that has cgroup constraint on event->cpu | ||
6874 | * - that may need work on context switch | ||
6875 | */ | ||
6876 | atomic_inc(&per_cpu(perf_cgroup_events, event->cpu)); | ||
6877 | static_key_slow_inc(&perf_sched_events.key); | ||
6878 | } | 6976 | } |
6879 | 6977 | ||
6978 | account_event(event); | ||
6979 | |||
6880 | /* | 6980 | /* |
6881 | * Special case software events and allow them to be part of | 6981 | * Special case software events and allow them to be part of |
6882 | * any hardware group. | 6982 | * any hardware group. |
@@ -7072,6 +7172,8 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, | |||
7072 | goto err; | 7172 | goto err; |
7073 | } | 7173 | } |
7074 | 7174 | ||
7175 | account_event(event); | ||
7176 | |||
7075 | ctx = find_get_context(event->pmu, task, cpu); | 7177 | ctx = find_get_context(event->pmu, task, cpu); |
7076 | if (IS_ERR(ctx)) { | 7178 | if (IS_ERR(ctx)) { |
7077 | err = PTR_ERR(ctx); | 7179 | err = PTR_ERR(ctx); |
@@ -7108,6 +7210,7 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu) | |||
7108 | list_for_each_entry_safe(event, tmp, &src_ctx->event_list, | 7210 | list_for_each_entry_safe(event, tmp, &src_ctx->event_list, |
7109 | event_entry) { | 7211 | event_entry) { |
7110 | perf_remove_from_context(event); | 7212 | perf_remove_from_context(event); |
7213 | unaccount_event_cpu(event, src_cpu); | ||
7111 | put_ctx(src_ctx); | 7214 | put_ctx(src_ctx); |
7112 | list_add(&event->event_entry, &events); | 7215 | list_add(&event->event_entry, &events); |
7113 | } | 7216 | } |
@@ -7120,6 +7223,7 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu) | |||
7120 | list_del(&event->event_entry); | 7223 | list_del(&event->event_entry); |
7121 | if (event->state >= PERF_EVENT_STATE_OFF) | 7224 | if (event->state >= PERF_EVENT_STATE_OFF) |
7122 | event->state = PERF_EVENT_STATE_INACTIVE; | 7225 | event->state = PERF_EVENT_STATE_INACTIVE; |
7226 | account_event_cpu(event, dst_cpu); | ||
7123 | perf_install_in_context(dst_ctx, event, dst_cpu); | 7227 | perf_install_in_context(dst_ctx, event, dst_cpu); |
7124 | get_ctx(dst_ctx); | 7228 | get_ctx(dst_ctx); |
7125 | } | 7229 | } |
@@ -7630,7 +7734,7 @@ static void __init perf_event_init_all_cpus(void) | |||
7630 | } | 7734 | } |
7631 | } | 7735 | } |
7632 | 7736 | ||
7633 | static void __cpuinit perf_event_init_cpu(int cpu) | 7737 | static void perf_event_init_cpu(int cpu) |
7634 | { | 7738 | { |
7635 | struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); | 7739 | struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); |
7636 | 7740 | ||
@@ -7719,7 +7823,7 @@ static struct notifier_block perf_reboot_notifier = { | |||
7719 | .priority = INT_MIN, | 7823 | .priority = INT_MIN, |
7720 | }; | 7824 | }; |
7721 | 7825 | ||
7722 | static int __cpuinit | 7826 | static int |
7723 | perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) | 7827 | perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) |
7724 | { | 7828 | { |
7725 | unsigned int cpu = (long)hcpu; | 7829 | unsigned int cpu = (long)hcpu; |
@@ -7800,7 +7904,8 @@ unlock: | |||
7800 | device_initcall(perf_event_sysfs_init); | 7904 | device_initcall(perf_event_sysfs_init); |
7801 | 7905 | ||
7802 | #ifdef CONFIG_CGROUP_PERF | 7906 | #ifdef CONFIG_CGROUP_PERF |
7803 | static struct cgroup_subsys_state *perf_cgroup_css_alloc(struct cgroup *cont) | 7907 | static struct cgroup_subsys_state * |
7908 | perf_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) | ||
7804 | { | 7909 | { |
7805 | struct perf_cgroup *jc; | 7910 | struct perf_cgroup *jc; |
7806 | 7911 | ||
@@ -7817,11 +7922,10 @@ static struct cgroup_subsys_state *perf_cgroup_css_alloc(struct cgroup *cont) | |||
7817 | return &jc->css; | 7922 | return &jc->css; |
7818 | } | 7923 | } |
7819 | 7924 | ||
7820 | static void perf_cgroup_css_free(struct cgroup *cont) | 7925 | static void perf_cgroup_css_free(struct cgroup_subsys_state *css) |
7821 | { | 7926 | { |
7822 | struct perf_cgroup *jc; | 7927 | struct perf_cgroup *jc = container_of(css, struct perf_cgroup, css); |
7823 | jc = container_of(cgroup_subsys_state(cont, perf_subsys_id), | 7928 | |
7824 | struct perf_cgroup, css); | ||
7825 | free_percpu(jc->info); | 7929 | free_percpu(jc->info); |
7826 | kfree(jc); | 7930 | kfree(jc); |
7827 | } | 7931 | } |
@@ -7833,15 +7937,17 @@ static int __perf_cgroup_move(void *info) | |||
7833 | return 0; | 7937 | return 0; |
7834 | } | 7938 | } |
7835 | 7939 | ||
7836 | static void perf_cgroup_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) | 7940 | static void perf_cgroup_attach(struct cgroup_subsys_state *css, |
7941 | struct cgroup_taskset *tset) | ||
7837 | { | 7942 | { |
7838 | struct task_struct *task; | 7943 | struct task_struct *task; |
7839 | 7944 | ||
7840 | cgroup_taskset_for_each(task, cgrp, tset) | 7945 | cgroup_taskset_for_each(task, css, tset) |
7841 | task_function_call(task, __perf_cgroup_move, task); | 7946 | task_function_call(task, __perf_cgroup_move, task); |
7842 | } | 7947 | } |
7843 | 7948 | ||
7844 | static void perf_cgroup_exit(struct cgroup *cgrp, struct cgroup *old_cgrp, | 7949 | static void perf_cgroup_exit(struct cgroup_subsys_state *css, |
7950 | struct cgroup_subsys_state *old_css, | ||
7845 | struct task_struct *task) | 7951 | struct task_struct *task) |
7846 | { | 7952 | { |
7847 | /* | 7953 | /* |