diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/events/core.c | 233 | ||||
| -rw-r--r-- | kernel/events/internal.h | 4 | ||||
| -rw-r--r-- | kernel/kprobes.c | 30 |
3 files changed, 185 insertions, 82 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 9dc297faf7c0..b391907d5352 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -196,9 +196,6 @@ static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx, | |||
| 196 | static void update_context_time(struct perf_event_context *ctx); | 196 | static void update_context_time(struct perf_event_context *ctx); |
| 197 | static u64 perf_event_time(struct perf_event *event); | 197 | static u64 perf_event_time(struct perf_event *event); |
| 198 | 198 | ||
| 199 | static void ring_buffer_attach(struct perf_event *event, | ||
| 200 | struct ring_buffer *rb); | ||
| 201 | |||
| 202 | void __weak perf_event_print_debug(void) { } | 199 | void __weak perf_event_print_debug(void) { } |
| 203 | 200 | ||
| 204 | extern __weak const char *perf_pmu_name(void) | 201 | extern __weak const char *perf_pmu_name(void) |
| @@ -2918,6 +2915,7 @@ static void free_event_rcu(struct rcu_head *head) | |||
| 2918 | } | 2915 | } |
| 2919 | 2916 | ||
| 2920 | static void ring_buffer_put(struct ring_buffer *rb); | 2917 | static void ring_buffer_put(struct ring_buffer *rb); |
| 2918 | static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb); | ||
| 2921 | 2919 | ||
| 2922 | static void free_event(struct perf_event *event) | 2920 | static void free_event(struct perf_event *event) |
| 2923 | { | 2921 | { |
| @@ -2942,15 +2940,30 @@ static void free_event(struct perf_event *event) | |||
| 2942 | if (has_branch_stack(event)) { | 2940 | if (has_branch_stack(event)) { |
| 2943 | static_key_slow_dec_deferred(&perf_sched_events); | 2941 | static_key_slow_dec_deferred(&perf_sched_events); |
| 2944 | /* is system-wide event */ | 2942 | /* is system-wide event */ |
| 2945 | if (!(event->attach_state & PERF_ATTACH_TASK)) | 2943 | if (!(event->attach_state & PERF_ATTACH_TASK)) { |
| 2946 | atomic_dec(&per_cpu(perf_branch_stack_events, | 2944 | atomic_dec(&per_cpu(perf_branch_stack_events, |
| 2947 | event->cpu)); | 2945 | event->cpu)); |
| 2946 | } | ||
| 2948 | } | 2947 | } |
| 2949 | } | 2948 | } |
| 2950 | 2949 | ||
| 2951 | if (event->rb) { | 2950 | if (event->rb) { |
| 2952 | ring_buffer_put(event->rb); | 2951 | struct ring_buffer *rb; |
| 2953 | event->rb = NULL; | 2952 | |
| 2953 | /* | ||
| 2954 | * Can happen when we close an event with re-directed output. | ||
| 2955 | * | ||
| 2956 | * Since we have a 0 refcount, perf_mmap_close() will skip | ||
| 2957 | * over us; possibly making our ring_buffer_put() the last. | ||
| 2958 | */ | ||
| 2959 | mutex_lock(&event->mmap_mutex); | ||
| 2960 | rb = event->rb; | ||
| 2961 | if (rb) { | ||
| 2962 | rcu_assign_pointer(event->rb, NULL); | ||
| 2963 | ring_buffer_detach(event, rb); | ||
| 2964 | ring_buffer_put(rb); /* could be last */ | ||
| 2965 | } | ||
| 2966 | mutex_unlock(&event->mmap_mutex); | ||
| 2954 | } | 2967 | } |
| 2955 | 2968 | ||
| 2956 | if (is_cgroup_event(event)) | 2969 | if (is_cgroup_event(event)) |
| @@ -3188,30 +3201,13 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) | |||
| 3188 | unsigned int events = POLL_HUP; | 3201 | unsigned int events = POLL_HUP; |
| 3189 | 3202 | ||
| 3190 | /* | 3203 | /* |
| 3191 | * Race between perf_event_set_output() and perf_poll(): perf_poll() | 3204 | * Pin the event->rb by taking event->mmap_mutex; otherwise |
| 3192 | * grabs the rb reference but perf_event_set_output() overrides it. | 3205 | * perf_event_set_output() can swizzle our rb and make us miss wakeups. |
| 3193 | * Here is the timeline for two threads T1, T2: | ||
| 3194 | * t0: T1, rb = rcu_dereference(event->rb) | ||
| 3195 | * t1: T2, old_rb = event->rb | ||
| 3196 | * t2: T2, event->rb = new rb | ||
| 3197 | * t3: T2, ring_buffer_detach(old_rb) | ||
| 3198 | * t4: T1, ring_buffer_attach(rb1) | ||
| 3199 | * t5: T1, poll_wait(event->waitq) | ||
| 3200 | * | ||
| 3201 | * To avoid this problem, we grab mmap_mutex in perf_poll() | ||
| 3202 | * thereby ensuring that the assignment of the new ring buffer | ||
| 3203 | * and the detachment of the old buffer appear atomic to perf_poll() | ||
| 3204 | */ | 3206 | */ |
| 3205 | mutex_lock(&event->mmap_mutex); | 3207 | mutex_lock(&event->mmap_mutex); |
| 3206 | 3208 | rb = event->rb; | |
| 3207 | rcu_read_lock(); | 3209 | if (rb) |
| 3208 | rb = rcu_dereference(event->rb); | ||
| 3209 | if (rb) { | ||
| 3210 | ring_buffer_attach(event, rb); | ||
| 3211 | events = atomic_xchg(&rb->poll, 0); | 3210 | events = atomic_xchg(&rb->poll, 0); |
| 3212 | } | ||
| 3213 | rcu_read_unlock(); | ||
| 3214 | |||
| 3215 | mutex_unlock(&event->mmap_mutex); | 3211 | mutex_unlock(&event->mmap_mutex); |
| 3216 | 3212 | ||
| 3217 | poll_wait(file, &event->waitq, wait); | 3213 | poll_wait(file, &event->waitq, wait); |
| @@ -3521,16 +3517,12 @@ static void ring_buffer_attach(struct perf_event *event, | |||
| 3521 | return; | 3517 | return; |
| 3522 | 3518 | ||
| 3523 | spin_lock_irqsave(&rb->event_lock, flags); | 3519 | spin_lock_irqsave(&rb->event_lock, flags); |
| 3524 | if (!list_empty(&event->rb_entry)) | 3520 | if (list_empty(&event->rb_entry)) |
| 3525 | goto unlock; | 3521 | list_add(&event->rb_entry, &rb->event_list); |
| 3526 | |||
| 3527 | list_add(&event->rb_entry, &rb->event_list); | ||
| 3528 | unlock: | ||
| 3529 | spin_unlock_irqrestore(&rb->event_lock, flags); | 3522 | spin_unlock_irqrestore(&rb->event_lock, flags); |
| 3530 | } | 3523 | } |
| 3531 | 3524 | ||
| 3532 | static void ring_buffer_detach(struct perf_event *event, | 3525 | static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb) |
| 3533 | struct ring_buffer *rb) | ||
| 3534 | { | 3526 | { |
| 3535 | unsigned long flags; | 3527 | unsigned long flags; |
| 3536 | 3528 | ||
| @@ -3549,13 +3541,10 @@ static void ring_buffer_wakeup(struct perf_event *event) | |||
| 3549 | 3541 | ||
| 3550 | rcu_read_lock(); | 3542 | rcu_read_lock(); |
| 3551 | rb = rcu_dereference(event->rb); | 3543 | rb = rcu_dereference(event->rb); |
| 3552 | if (!rb) | 3544 | if (rb) { |
| 3553 | goto unlock; | 3545 | list_for_each_entry_rcu(event, &rb->event_list, rb_entry) |
| 3554 | 3546 | wake_up_all(&event->waitq); | |
| 3555 | list_for_each_entry_rcu(event, &rb->event_list, rb_entry) | 3547 | } |
| 3556 | wake_up_all(&event->waitq); | ||
| 3557 | |||
| 3558 | unlock: | ||
| 3559 | rcu_read_unlock(); | 3548 | rcu_read_unlock(); |
| 3560 | } | 3549 | } |
| 3561 | 3550 | ||
| @@ -3584,18 +3573,10 @@ static struct ring_buffer *ring_buffer_get(struct perf_event *event) | |||
| 3584 | 3573 | ||
| 3585 | static void ring_buffer_put(struct ring_buffer *rb) | 3574 | static void ring_buffer_put(struct ring_buffer *rb) |
| 3586 | { | 3575 | { |
| 3587 | struct perf_event *event, *n; | ||
| 3588 | unsigned long flags; | ||
| 3589 | |||
| 3590 | if (!atomic_dec_and_test(&rb->refcount)) | 3576 | if (!atomic_dec_and_test(&rb->refcount)) |
| 3591 | return; | 3577 | return; |
| 3592 | 3578 | ||
| 3593 | spin_lock_irqsave(&rb->event_lock, flags); | 3579 | WARN_ON_ONCE(!list_empty(&rb->event_list)); |
| 3594 | list_for_each_entry_safe(event, n, &rb->event_list, rb_entry) { | ||
| 3595 | list_del_init(&event->rb_entry); | ||
| 3596 | wake_up_all(&event->waitq); | ||
| 3597 | } | ||
| 3598 | spin_unlock_irqrestore(&rb->event_lock, flags); | ||
| 3599 | 3580 | ||
| 3600 | call_rcu(&rb->rcu_head, rb_free_rcu); | 3581 | call_rcu(&rb->rcu_head, rb_free_rcu); |
| 3601 | } | 3582 | } |
| @@ -3605,26 +3586,100 @@ static void perf_mmap_open(struct vm_area_struct *vma) | |||
| 3605 | struct perf_event *event = vma->vm_file->private_data; | 3586 | struct perf_event *event = vma->vm_file->private_data; |
| 3606 | 3587 | ||
| 3607 | atomic_inc(&event->mmap_count); | 3588 | atomic_inc(&event->mmap_count); |
| 3589 | atomic_inc(&event->rb->mmap_count); | ||
| 3608 | } | 3590 | } |
| 3609 | 3591 | ||
| 3592 | /* | ||
| 3593 | * A buffer can be mmap()ed multiple times; either directly through the same | ||
| 3594 | * event, or through other events by use of perf_event_set_output(). | ||
| 3595 | * | ||
| 3596 | * In order to undo the VM accounting done by perf_mmap() we need to destroy | ||
| 3597 | * the buffer here, where we still have a VM context. This means we need | ||
| 3598 | * to detach all events redirecting to us. | ||
| 3599 | */ | ||
| 3610 | static void perf_mmap_close(struct vm_area_struct *vma) | 3600 | static void perf_mmap_close(struct vm_area_struct *vma) |
| 3611 | { | 3601 | { |
| 3612 | struct perf_event *event = vma->vm_file->private_data; | 3602 | struct perf_event *event = vma->vm_file->private_data; |
| 3613 | 3603 | ||
| 3614 | if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) { | 3604 | struct ring_buffer *rb = event->rb; |
| 3615 | unsigned long size = perf_data_size(event->rb); | 3605 | struct user_struct *mmap_user = rb->mmap_user; |
| 3616 | struct user_struct *user = event->mmap_user; | 3606 | int mmap_locked = rb->mmap_locked; |
| 3617 | struct ring_buffer *rb = event->rb; | 3607 | unsigned long size = perf_data_size(rb); |
| 3608 | |||
| 3609 | atomic_dec(&rb->mmap_count); | ||
