aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/events
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/events')
-rw-r--r--kernel/events/core.c142
-rw-r--r--kernel/events/hw_breakpoint.c11
-rw-r--r--kernel/events/uprobes.c8
3 files changed, 89 insertions, 72 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 2ba890450d15..dbccf83c134d 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -372,6 +372,8 @@ void perf_cgroup_switch(struct task_struct *task, int mode)
372 372
373 list_for_each_entry_rcu(pmu, &pmus, entry) { 373 list_for_each_entry_rcu(pmu, &pmus, entry) {
374 cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); 374 cpuctx = this_cpu_ptr(pmu->pmu_cpu_context);
375 if (cpuctx->unique_pmu != pmu)
376 continue; /* ensure we process each cpuctx once */
375 377
376 /* 378 /*
377 * perf_cgroup_events says at least one 379 * perf_cgroup_events says at least one
@@ -395,9 +397,10 @@ void perf_cgroup_switch(struct task_struct *task, int mode)
395 397
396 if (mode & PERF_CGROUP_SWIN) { 398 if (mode & PERF_CGROUP_SWIN) {
397 WARN_ON_ONCE(cpuctx->cgrp); 399 WARN_ON_ONCE(cpuctx->cgrp);
398 /* set cgrp before ctxsw in to 400 /*
399 * allow event_filter_match() to not 401 * set cgrp before ctxsw in to allow
400 * have to pass task around 402 * event_filter_match() to not have to pass
403 * task around
401 */ 404 */
402 cpuctx->cgrp = perf_cgroup_from_task(task); 405 cpuctx->cgrp = perf_cgroup_from_task(task);
403 cpu_ctx_sched_in(cpuctx, EVENT_ALL, task); 406 cpu_ctx_sched_in(cpuctx, EVENT_ALL, task);
@@ -468,14 +471,13 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event,
468{ 471{
469 struct perf_cgroup *cgrp; 472 struct perf_cgroup *cgrp;
470 struct cgroup_subsys_state *css; 473 struct cgroup_subsys_state *css;
471 struct file *file; 474 struct fd f = fdget(fd);
472 int ret = 0, fput_needed; 475 int ret = 0;
473 476
474 file = fget_light(fd, &fput_needed); 477 if (!f.file)
475 if (!file)
476 return -EBADF; 478 return -EBADF;
477 479
478 css = cgroup_css_from_dir(file, perf_subsys_id); 480 css = cgroup_css_from_dir(f.file, perf_subsys_id);
479 if (IS_ERR(css)) { 481 if (IS_ERR(css)) {
480 ret = PTR_ERR(css); 482 ret = PTR_ERR(css);
481 goto out; 483 goto out;
@@ -501,7 +503,7 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event,
501 ret = -EINVAL; 503 ret = -EINVAL;
502 } 504 }
503out: 505out:
504 fput_light(file, fput_needed); 506 fdput(f);
505 return ret; 507 return ret;
506} 508}
507 509
@@ -1254,7 +1256,7 @@ retry:
1254/* 1256/*
1255 * Cross CPU call to disable a performance event 1257 * Cross CPU call to disable a performance event
1256 */ 1258 */
1257static int __perf_event_disable(void *info) 1259int __perf_event_disable(void *info)
1258{ 1260{
1259 struct perf_event *event = info; 1261 struct perf_event *event = info;
1260 struct perf_event_context *ctx = event->ctx; 1262 struct perf_event_context *ctx = event->ctx;
@@ -2936,12 +2938,12 @@ EXPORT_SYMBOL_GPL(perf_event_release_kernel);
2936/* 2938/*
2937 * Called when the last reference to the file is gone. 2939 * Called when the last reference to the file is gone.
2938 */ 2940 */
2939static int perf_release(struct inode *inode, struct file *file) 2941static void put_event(struct perf_event *event)
2940{ 2942{
2941 struct perf_event *event = file->private_data;
2942 struct task_struct *owner; 2943 struct task_struct *owner;
2943 2944
2944 file->private_data = NULL; 2945 if (!atomic_long_dec_and_test(&event->refcount))
2946 return;
2945 2947
2946 rcu_read_lock(); 2948 rcu_read_lock();
2947 owner = ACCESS_ONCE(event->owner); 2949 owner = ACCESS_ONCE(event->owner);
@@ -2976,7 +2978,13 @@ static int perf_release(struct inode *inode, struct file *file)
2976 put_task_struct(owner); 2978 put_task_struct(owner);
2977 } 2979 }
2978 2980
2979 return perf_event_release_kernel(event); 2981 perf_event_release_kernel(event);
2982}
2983
2984static int perf_release(struct inode *inode, struct file *file)
2985{
2986 put_event(file->private_data);
2987 return 0;
2980} 2988}
2981 2989
2982u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) 2990u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running)
@@ -3228,21 +3236,18 @@ unlock:
3228 3236
3229static const struct file_operations perf_fops; 3237static const struct file_operations perf_fops;
3230 3238
3231static struct perf_event *perf_fget_light(int fd, int *fput_needed) 3239static inline int perf_fget_light(int fd, struct fd *p)
3232{ 3240{
3233 struct file *file; 3241 struct fd f = fdget(fd);
3234 3242 if (!f.file)
3235 file = fget_light(fd, fput_needed); 3243 return -EBADF;
3236 if (!file)
3237 return ERR_PTR(-EBADF);
3238 3244
3239 if (file->f_op != &perf_fops) { 3245 if (f.file->f_op != &perf_fops) {
3240 fput_light(file, *fput_needed); 3246 fdput(f);
3241 *fput_needed = 0; 3247 return -EBADF;
3242 return ERR_PTR(-EBADF);
3243 } 3248 }
3244 3249 *p = f;
3245 return file->private_data; 3250 return 0;
3246} 3251}
3247 3252
3248static int perf_event_set_output(struct perf_event *event, 3253static int perf_event_set_output(struct perf_event *event,
@@ -3274,20 +3279,19 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3274 3279
3275 case PERF_EVENT_IOC_SET_OUTPUT: 3280 case PERF_EVENT_IOC_SET_OUTPUT:
3276 { 3281 {
3277 struct perf_event *output_event = NULL;
3278 int fput_needed = 0;
3279 int ret; 3282 int ret;
3280
3281 if (arg != -1) { 3283 if (arg != -1) {
3282 output_event = perf_fget_light(arg, &fput_needed); 3284 struct perf_event *output_event;
3283 if (IS_ERR(output_event)) 3285 struct fd output;
3284 return PTR_ERR(output_event); 3286 ret = perf_fget_light(arg, &output);
3287 if (ret)
3288 return ret;
3289 output_event = output.file->private_data;
3290 ret = perf_event_set_output(event, output_event);
3291 fdput(output);
3292 } else {
3293 ret = perf_event_set_output(event, NULL);
3285 } 3294 }
3286
3287 ret = perf_event_set_output(event, output_event);
3288 if (output_event)
3289 fput_light(output_event->filp, fput_needed);
3290
3291 return ret; 3295 return ret;
3292 } 3296 }
3293 3297
@@ -3670,7 +3674,7 @@ unlock:
3670 atomic_inc(&event->mmap_count); 3674 atomic_inc(&event->mmap_count);
3671 mutex_unlock(&event->mmap_mutex); 3675 mutex_unlock(&event->mmap_mutex);
3672 3676
3673 vma->vm_flags |= VM_RESERVED; 3677 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
3674 vma->vm_ops = &perf_mmap_vmops; 3678 vma->vm_ops = &perf_mmap_vmops;
3675 3679
3676 return ret; 3680 return ret;
@@ -4411,7 +4415,7 @@ static void perf_event_task_event(struct perf_task_event *task_event)
4411 rcu_read_lock(); 4415 rcu_read_lock();
4412 list_for_each_entry_rcu(pmu, &pmus, entry) { 4416 list_for_each_entry_rcu(pmu, &pmus, entry) {
4413 cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); 4417 cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
4414 if (cpuctx->active_pmu != pmu) 4418 if (cpuctx->unique_pmu != pmu)
4415 goto next; 4419 goto next;
4416 perf_event_task_ctx(&cpuctx->ctx, task_event); 4420 perf_event_task_ctx(&cpuctx->ctx, task_event);
4417 4421
@@ -4557,7 +4561,7 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
4557 rcu_read_lock(); 4561 rcu_read_lock();
4558 list_for_each_entry_rcu(pmu, &pmus, entry) { 4562 list_for_each_entry_rcu(pmu, &pmus, entry) {
4559 cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); 4563 cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
4560 if (cpuctx->active_pmu != pmu) 4564 if (cpuctx->unique_pmu != pmu)
4561 goto next; 4565 goto next;
4562 perf_event_comm_ctx(&cpuctx->ctx, comm_event); 4566 perf_event_comm_ctx(&cpuctx->ctx, comm_event);
4563 4567
@@ -4753,7 +4757,7 @@ got_name:
4753 rcu_read_lock(); 4757 rcu_read_lock();
4754 list_for_each_entry_rcu(pmu, &pmus, entry) { 4758 list_for_each_entry_rcu(pmu, &pmus, entry) {
4755 cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); 4759 cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
4756 if (cpuctx->active_pmu != pmu) 4760 if (cpuctx->unique_pmu != pmu)
4757 goto next; 4761 goto next;
4758 perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, 4762 perf_event_mmap_ctx(&cpuctx->ctx, mmap_event,
4759 vma->vm_flags & VM_EXEC); 4763 vma->vm_flags & VM_EXEC);
@@ -5854,8 +5858,8 @@ static void update_pmu_context(struct pmu *pmu, struct pmu *old_pmu)
5854 5858
5855 cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); 5859 cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
5856 5860
5857 if (cpuctx->active_pmu == old_pmu) 5861 if (cpuctx->unique_pmu == old_pmu)
5858 cpuctx->active_pmu = pmu; 5862 cpuctx->unique_pmu = pmu;
5859 } 5863 }
5860} 5864}
5861 5865
@@ -5990,7 +5994,7 @@ skip_type:
5990 cpuctx->ctx.pmu = pmu; 5994 cpuctx->ctx.pmu = pmu;
5991 cpuctx->jiffies_interval = 1; 5995 cpuctx->jiffies_interval = 1;
5992 INIT_LIST_HEAD(&cpuctx->rotation_list); 5996 INIT_LIST_HEAD(&cpuctx->rotation_list);
5993 cpuctx->active_pmu = pmu; 5997 cpuctx->unique_pmu = pmu;
5994 } 5998 }
5995 5999
5996got_cpu_context: 6000got_cpu_context:
@@ -6142,6 +6146,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
6142 6146
6143 mutex_init(&event->mmap_mutex); 6147 mutex_init(&event->mmap_mutex);
6144 6148
6149 atomic_long_set(&event->refcount, 1);
6145 event->cpu = cpu; 6150 event->cpu = cpu;
6146 event->attr = *attr; 6151 event->attr = *attr;
6147 event->group_leader = group_leader; 6152 event->group_leader = group_leader;
@@ -6434,12 +6439,11 @@ SYSCALL_DEFINE5(perf_event_open,
6434 struct perf_event_attr attr; 6439 struct perf_event_attr attr;
6435 struct perf_event_context *ctx; 6440 struct perf_event_context *ctx;
6436 struct file *event_file = NULL; 6441 struct file *event_file = NULL;
6437 struct file *group_file = NULL; 6442 struct fd group = {NULL, 0};
6438 struct task_struct *task = NULL; 6443 struct task_struct *task = NULL;
6439 struct pmu *pmu; 6444 struct pmu *pmu;
6440 int event_fd; 6445 int event_fd;
6441 int move_group = 0; 6446 int move_group = 0;
6442 int fput_needed = 0;
6443 int err; 6447 int err;
6444 6448
6445 /* for future expandability... */ 6449 /* for future expandability... */
@@ -6469,17 +6473,15 @@ SYSCALL_DEFINE5(perf_event_open,
6469 if ((flags & PERF_FLAG_PID_CGROUP) && (pid == -1 || cpu == -1)) 6473 if ((flags & PERF_FLAG_PID_CGROUP) && (pid == -1 || cpu == -1))
6470 return -EINVAL; 6474 return -EINVAL;
6471 6475
6472 event_fd = get_unused_fd_flags(O_RDWR); 6476 event_fd = get_unused_fd();
6473 if (event_fd < 0) 6477 if (event_fd < 0)
6474 return event_fd; 6478 return event_fd;
6475 6479
6476 if (group_fd != -1) { 6480 if (group_fd != -1) {
6477 group_leader = perf_fget_light(group_fd, &fput_needed); 6481 err = perf_fget_light(group_fd, &group);
6478 if (IS_ERR(group_leader)) { 6482 if (err)
6479 err = PTR_ERR(group_leader);
6480 goto err_fd; 6483 goto err_fd;
6481 } 6484 group_leader = group.file->private_data;
6482 group_file = group_leader->filp;
6483 if (flags & PERF_FLAG_FD_OUTPUT) 6485 if (flags & PERF_FLAG_FD_OUTPUT)
6484 output_event = group_leader; 6486 output_event = group_leader;
6485 if (flags & PERF_FLAG_FD_NO_GROUP) 6487 if (flags & PERF_FLAG_FD_NO_GROUP)
@@ -6616,7 +6618,6 @@ SYSCALL_DEFINE5(perf_event_open,
6616 put_ctx(gctx); 6618 put_ctx(gctx);
6617 } 6619 }
6618 6620
6619 event->filp = event_file;
6620 WARN_ON_ONCE(ctx->parent_ctx); 6621 WARN_ON_ONCE(ctx->parent_ctx);
6621 mutex_lock(&ctx->mutex); 6622 mutex_lock(&ctx->mutex);
6622 6623
@@ -6656,7 +6657,7 @@ SYSCALL_DEFINE5(perf_event_open,
6656 * of the group leader will find the pointer to itself in 6657 * of the group leader will find the pointer to itself in
6657 * perf_group_detach(). 6658 * perf_group_detach().
6658 */ 6659 */
6659 fput_light(group_file, fput_needed); 6660 fdput(group);
6660 fd_install(event_fd, event_file); 6661 fd_install(event_fd, event_file);
6661 return event_fd; 6662 return event_fd;
6662 6663
@@ -6670,7 +6671,7 @@ err_task:
6670 if (task) 6671 if (task)
6671 put_task_struct(task); 6672 put_task_struct(task);
6672err_group_fd: 6673err_group_fd:
6673 fput_light(group_file, fput_needed); 6674 fdput(group);
6674err_fd: 6675err_fd:
6675 put_unused_fd(event_fd); 6676 put_unused_fd(event_fd);
6676 return err; 6677 return err;
@@ -6710,7 +6711,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
6710 goto err_free; 6711 goto err_free;
6711 } 6712 }
6712 6713
6713 event->filp = NULL;
6714 WARN_ON_ONCE(ctx->parent_ctx); 6714 WARN_ON_ONCE(ctx->parent_ctx);
6715 mutex_lock(&ctx->mutex); 6715 mutex_lock(&ctx->mutex);
6716 perf_install_in_context(ctx, event, cpu); 6716 perf_install_in_context(ctx, event, cpu);
@@ -6792,7 +6792,7 @@ static void sync_child_event(struct perf_event *child_event,
6792 * Release the parent event, if this was the last 6792 * Release the parent event, if this was the last
6793 * reference to it. 6793 * reference to it.
6794 */ 6794 */
6795 fput(parent_event->filp); 6795 put_event(parent_event);
6796} 6796}
6797 6797
6798static void 6798static void
@@ -6868,9 +6868,8 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
6868 * 6868 *
6869 * __perf_event_exit_task() 6869 * __perf_event_exit_task()
6870 * sync_child_event() 6870 * sync_child_event()
6871 * fput(parent_event->filp) 6871 * put_event()
6872 * perf_release() 6872 * mutex_lock(&ctx->mutex)
6873 * mutex_lock(&ctx->mutex)
6874 * 6873 *
6875 * But since its the parent context it won't be the same instance. 6874 * But since its the parent context it won't be the same instance.
6876 */ 6875 */
@@ -6938,7 +6937,7 @@ static void perf_free_event(struct perf_event *event,
6938 list_del_init(&event->child_list); 6937 list_del_init(&event->child_list);
6939 mutex_unlock(&parent->child_mutex); 6938 mutex_unlock(&parent->child_mutex);
6940 6939
6941 fput(parent->filp); 6940 put_event(parent);
6942 6941
6943 perf_group_detach(event); 6942 perf_group_detach(event);
6944 list_del_event(event, ctx); 6943 list_del_event(event, ctx);
@@ -7018,6 +7017,12 @@ inherit_event(struct perf_event *parent_event,
7018 NULL, NULL); 7017 NULL, NULL);
7019 if (IS_ERR(child_event)) 7018 if (IS_ERR(child_event))
7020 return child_event; 7019 return child_event;
7020
7021 if (!atomic_long_inc_not_zero(&parent_event->refcount)) {
7022 free_event(child_event);
7023 return NULL;
7024 }
7025
7021 get_ctx(child_ctx); 7026 get_ctx(child_ctx);
7022 7027
7023 /* 7028 /*
@@ -7059,14 +7064,6 @@ inherit_event(struct perf_event *parent_event,
7059 raw_spin_unlock_irqrestore(&child_ctx->lock, flags); 7064 raw_spin_unlock_irqrestore(&child_ctx->lock, flags);
7060 7065
7061 /* 7066 /*
7062 * Get a reference to the parent filp - we will fput it
7063 * when the child event exits. This is safe to do because
7064 * we are in the parent and we know that the filp still
7065 * exists and has a nonzero count:
7066 */
7067 atomic_long_inc(&parent_event->filp->f_count);
7068
7069 /*
7070 * Link this into the parent event's child list 7067 * Link this into the parent event's child list
7071 */ 7068 */
7072 WARN_ON_ONCE(parent_event->ctx->parent_ctx); 7069 WARN_ON_ONCE(parent_event->ctx->parent_ctx);
@@ -7499,5 +7496,12 @@ struct cgroup_subsys perf_subsys = {
7499 .destroy = perf_cgroup_destroy, 7496 .destroy = perf_cgroup_destroy,
7500 .exit = perf_cgroup_exit, 7497 .exit = perf_cgroup_exit,
7501 .attach = perf_cgroup_attach, 7498 .attach = perf_cgroup_attach,
7499
7500 /*
7501 * perf_event cgroup doesn't handle nesting correctly.
7502 * ctx->nr_cgroups adjustments should be propagated through the
7503 * cgroup hierarchy. Fix it and remove the following.
7504 */
7505 .broken_hierarchy = true,
7502}; 7506};
7503#endif /* CONFIG_CGROUP_PERF */ 7507#endif /* CONFIG_CGROUP_PERF */
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c
index bb38c4d3ee12..9a7b487c6fe2 100644
--- a/kernel/events/hw_breakpoint.c
+++ b/kernel/events/hw_breakpoint.c
@@ -453,7 +453,16 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
453 int old_type = bp->attr.bp_type; 453 int old_type = bp->attr.bp_type;
454 int err = 0; 454 int err = 0;
455 455
456 perf_event_disable(bp); 456 /*
457 * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it
458 * will not be possible to raise IPIs that invoke __perf_event_disable.
459 * So call the function directly after making sure we are targeting the
460 * current task.
461 */
462 if (irqs_disabled() && bp->ctx && bp->ctx->task == current)
463 __perf_event_disable(bp);
464 else
465 perf_event_disable(bp);
457 466
458 bp->attr.bp_addr = attr->bp_addr; 467 bp->attr.bp_addr = attr->bp_addr;
459 bp->attr.bp_type = attr->bp_type; 468 bp->attr.bp_type = attr->bp_type;
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index c92651d619ca..5cc4e7e42e68 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -144,10 +144,14 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
144 spinlock_t *ptl; 144 spinlock_t *ptl;
145 pte_t *ptep; 145 pte_t *ptep;
146 int err; 146 int err;
147 /* For mmu_notifiers */
148 const unsigned long mmun_start = addr;
149 const unsigned long mmun_end = addr + PAGE_SIZE;
147 150
148 /* For try_to_free_swap() and munlock_vma_page() below */ 151 /* For try_to_free_swap() and munlock_vma_page() below */
149 lock_page(page); 152 lock_page(page);
150 153
154 mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
151 err = -EAGAIN; 155 err = -EAGAIN;
152 ptep = page_check_address(page, mm, addr, &ptl, 0); 156 ptep = page_check_address(page, mm, addr, &ptl, 0);
153 if (!ptep) 157 if (!ptep)
@@ -176,6 +180,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
176 180
177 err = 0; 181 err = 0;
178 unlock: 182 unlock:
183 mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
179 unlock_page(page); 184 unlock_page(page);
180 return err; 185 return err;
181} 186}
@@ -690,7 +695,6 @@ static struct map_info *
690build_map_info(struct address_space *mapping, loff_t offset, bool is_register) 695build_map_info(struct address_space *mapping, loff_t offset, bool is_register)
691{ 696{
692 unsigned long pgoff = offset >> PAGE_SHIFT; 697 unsigned long pgoff = offset >> PAGE_SHIFT;
693 struct prio_tree_iter iter;
694 struct vm_area_struct *vma; 698 struct vm_area_struct *vma;
695 struct map_info *curr = NULL; 699 struct map_info *curr = NULL;
696 struct map_info *prev = NULL; 700 struct map_info *prev = NULL;
@@ -699,7 +703,7 @@ build_map_info(struct address_space *mapping, loff_t offset, bool is_register)
699 703
700 again: 704 again:
701 mutex_lock(&mapping->i_mmap_mutex); 705 mutex_lock(&mapping->i_mmap_mutex);
702 vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { 706 vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
703 if (!valid_vma(vma, is_register)) 707 if (!valid_vma(vma, is_register))
704 continue; 708 continue;
705 709