diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-05-23 13:02:34 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-05-23 13:02:34 -0400 |
| commit | e6a32c3ad1e78a33dda5ee9e9ca5704288d35fd4 (patch) | |
| tree | 6c4fee3575323391ec862bb2256fdddb2a6bd0e1 /kernel | |
| parent | 2b2d323a31dc8b369a4c0e33705339399021fa83 (diff) | |
| parent | b69cf53640da2b86439596118cfa95233154ee76 (diff) | |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar:
"The biggest changes are fixes for races that kept triggering Trinity
crashes, plus liblockdep build fixes and smaller misc fixes.
The liblockdep bits in perf/urgent are a pull mistake - they should
have been in locking/urgent - but by the time I noticed other commits
were added and testing was done :-/ Sorry about that"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf: Fix a race between ring_buffer_detach() and ring_buffer_attach()
perf: Prevent false warning in perf_swevent_add
perf: Limit perf_event_attr::sample_period to 63 bits
tools/liblockdep: Remove all build files when doing make clean
tools/liblockdep: Build liblockdep from tools/Makefile
perf/x86/intel: Fix Silvermont's event constraints
perf: Fix perf_event_init_context()
perf: Fix race in removing an event
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/events/core.c | 174 |
1 files changed, 92 insertions, 82 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index f83a71a3e46d..440eefc67397 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -1443,6 +1443,11 @@ group_sched_out(struct perf_event *group_event, | |||
| 1443 | cpuctx->exclusive = 0; | 1443 | cpuctx->exclusive = 0; |
| 1444 | } | 1444 | } |
| 1445 | 1445 | ||
| 1446 | struct remove_event { | ||
| 1447 | struct perf_event *event; | ||
| 1448 | bool detach_group; | ||
| 1449 | }; | ||
| 1450 | |||
| 1446 | /* | 1451 | /* |
| 1447 | * Cross CPU call to remove a performance event | 1452 | * Cross CPU call to remove a performance event |
| 1448 | * | 1453 | * |
| @@ -1451,12 +1456,15 @@ group_sched_out(struct perf_event *group_event, | |||
| 1451 | */ | 1456 | */ |
| 1452 | static int __perf_remove_from_context(void *info) | 1457 | static int __perf_remove_from_context(void *info) |
| 1453 | { | 1458 | { |
| 1454 | struct perf_event *event = info; | 1459 | struct remove_event *re = info; |
| 1460 | struct perf_event *event = re->event; | ||
| 1455 | struct perf_event_context *ctx = event->ctx; | 1461 | struct perf_event_context *ctx = event->ctx; |
| 1456 | struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); | 1462 | struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); |
| 1457 | 1463 | ||
| 1458 | raw_spin_lock(&ctx->lock); | 1464 | raw_spin_lock(&ctx->lock); |
| 1459 | event_sched_out(event, cpuctx, ctx); | 1465 | event_sched_out(event, cpuctx, ctx); |
| 1466 | if (re->detach_group) | ||
| 1467 | perf_group_detach(event); | ||
| 1460 | list_del_event(event, ctx); | 1468 | list_del_event(event, ctx); |
| 1461 | if (!ctx->nr_events && cpuctx->task_ctx == ctx) { | 1469 | if (!ctx->nr_events && cpuctx->task_ctx == ctx) { |
| 1462 | ctx->is_active = 0; | 1470 | ctx->is_active = 0; |
| @@ -1481,10 +1489,14 @@ static int __perf_remove_from_context(void *info) | |||
| 1481 | * When called from perf_event_exit_task, it's OK because the | 1489 | * When called from perf_event_exit_task, it's OK because the |
| 1482 | * context has been detached from its task. | 1490 | * context has been detached from its task. |
| 1483 | */ | 1491 | */ |
| 1484 | static void perf_remove_from_context(struct perf_event *event) | 1492 | static void perf_remove_from_context(struct perf_event *event, bool detach_group) |
| 1485 | { | 1493 | { |
| 1486 | struct perf_event_context *ctx = event->ctx; | 1494 | struct perf_event_context *ctx = event->ctx; |
| 1487 | struct task_struct *task = ctx->task; | 1495 | struct task_struct *task = ctx->task; |
| 1496 | struct remove_event re = { | ||
| 1497 | .event = event, | ||
| 1498 | .detach_group = detach_group, | ||
| 1499 | }; | ||
| 1488 | 1500 | ||
| 1489 | lockdep_assert_held(&ctx->mutex); | 1501 | lockdep_assert_held(&ctx->mutex); |
| 1490 | 1502 | ||
| @@ -1493,12 +1505,12 @@ static void perf_remove_from_context(struct perf_event *event) | |||
| 1493 | * Per cpu events are removed via an smp call and | 1505 | * Per cpu events are removed via an smp call and |
| 1494 | * the removal is always successful. | 1506 | * the removal is always successful. |
| 1495 | */ | 1507 | */ |
| 1496 | cpu_function_call(event->cpu, __perf_remove_from_context, event); | 1508 | cpu_function_call(event->cpu, __perf_remove_from_context, &re); |
| 1497 | return; | 1509 | return; |
| 1498 | } | 1510 | } |
| 1499 | 1511 | ||
| 1500 | retry: | 1512 | retry: |
| 1501 | if (!task_function_call(task, __perf_remove_from_context, event)) | 1513 | if (!task_function_call(task, __perf_remove_from_context, &re)) |
| 1502 | return; | 1514 | return; |
| 1503 | 1515 | ||
| 1504 | raw_spin_lock_irq(&ctx->lock); | 1516 | raw_spin_lock_irq(&ctx->lock); |
| @@ -1515,6 +1527,8 @@ retry: | |||
| 1515 | * Since the task isn't running, its safe to remove the event, us | 1527 | * Since the task isn't running, its safe to remove the event, us |
| 1516 | * holding the ctx->lock ensures the task won't get scheduled in. | 1528 | * holding the ctx->lock ensures the task won't get scheduled in. |
| 1517 | */ | 1529 | */ |
| 1530 | if (detach_group) | ||
| 1531 | perf_group_detach(event); | ||
| 1518 | list_del_event(event, ctx); | 1532 | list_del_event(event, ctx); |
| 1519 | raw_spin_unlock_irq(&ctx->lock); | 1533 | raw_spin_unlock_irq(&ctx->lock); |
| 1520 | } | 1534 | } |
| @@ -3178,7 +3192,8 @@ static void free_event_rcu(struct rcu_head *head) | |||
| 3178 | } | 3192 | } |
| 3179 | 3193 | ||
| 3180 | static void ring_buffer_put(struct ring_buffer *rb); | 3194 | static void ring_buffer_put(struct ring_buffer *rb); |
| 3181 | static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb); | 3195 | static void ring_buffer_attach(struct perf_event *event, |
| 3196 | struct ring_buffer *rb); | ||
| 3182 | 3197 | ||
| 3183 | static void unaccount_event_cpu(struct perf_event *event, int cpu) | 3198 | static void unaccount_event_cpu(struct perf_event *event, int cpu) |
| 3184 | { | 3199 | { |
| @@ -3238,8 +3253,6 @@ static void free_event(struct perf_event *event) | |||
| 3238 | unaccount_event(event); | 3253 | unaccount_event(event); |
| 3239 | 3254 | ||
| 3240 | if (event->rb) { | 3255 | if (event->rb) { |
| 3241 | struct ring_buffer *rb; | ||
| 3242 | |||
| 3243 | /* | 3256 | /* |
| 3244 | * Can happen when we close an event with re-directed output. | 3257 | * Can happen when we close an event with re-directed output. |
| 3245 | * | 3258 | * |
| @@ -3247,12 +3260,7 @@ static void free_event(struct perf_event *event) | |||
| 3247 | * over us; possibly making our ring_buffer_put() the last. | 3260 | * over us; possibly making our ring_buffer_put() the last. |
| 3248 | */ | 3261 | */ |
| 3249 | mutex_lock(&event->mmap_mutex); | 3262 | mutex_lock(&event->mmap_mutex); |
| 3250 | rb = event->rb; | 3263 | ring_buffer_attach(event, NULL); |
| 3251 | if (rb) { | ||
| 3252 | rcu_assign_pointer(event->rb, NULL); | ||
| 3253 | ring_buffer_detach(event, rb); | ||
| 3254 | ring_buffer_put(rb); /* could be last */ | ||
| 3255 | } | ||
| 3256 | mutex_unlock(&event->mmap_mutex); | 3264 | mutex_unlock(&event->mmap_mutex); |
| 3257 | } | 3265 | } |
| 3258 | 3266 | ||
| @@ -3281,10 +3289,7 @@ int perf_event_release_kernel(struct perf_event *event) | |||
| 3281 | * to trigger the AB-BA case. | 3289 | * to trigger the AB-BA case. |
| 3282 | */ | 3290 | */ |
| 3283 | mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING); | 3291 | mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING); |
| 3284 | raw_spin_lock_irq(&ctx->lock); | 3292 | perf_remove_from_context(event, true); |
| 3285 | perf_group_detach(event); | ||
| 3286 | raw_spin_unlock_irq(&ctx->lock); | ||
| 3287 | perf_remove_from_context(event); | ||
| 3288 | mutex_unlock(&ctx->mutex); | 3293 | mutex_unlock(&ctx->mutex); |
| 3289 | 3294 | ||
| 3290 | free_event(event); | 3295 | free_event(event); |
| @@ -3839,28 +3844,47 @@ unlock: | |||
| 3839 | static void ring_buffer_attach(struct perf_event *event, | 3844 | static void ring_buffer_attach(struct perf_event *event, |
| 3840 | struct ring_buffer *rb) | 3845 | struct ring_buffer *rb) |
| 3841 | { | 3846 | { |
| 3847 | struct ring_buffer *old_rb = NULL; | ||
| 3842 | unsigned long flags; | 3848 | unsigned long flags; |
| 3843 | 3849 | ||
| 3844 | if (!list_empty(&event->rb_entry)) | 3850 | if (event->rb) { |
| 3845 | return; | 3851 | /* |
| 3852 | * Should be impossible, we set this when removing | ||
| 3853 | * event->rb_entry and wait/clear when adding event->rb_entry. | ||
| 3854 | */ | ||
| 3855 | WARN_ON_ONCE(event->rcu_pending); | ||
| 3846 | 3856 | ||
| 3847 | spin_lock_irqsave(&rb->event_lock, flags); | 3857 | old_rb = event->rb; |
| 3848 | if (list_empty(&event->rb_entry)) | 3858 | event->rcu_batches = get_state_synchronize_rcu(); |
| 3849 | list_add(&event->rb_entry, &rb->event_list); | 3859 | event->rcu_pending = 1; |
| 3850 | spin_unlock_irqrestore(&rb->event_lock, flags); | ||
| 3851 | } | ||
| 3852 | 3860 | ||
| 3853 | static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb) | 3861 | spin_lock_irqsave(&old_rb->event_lock, flags); |
| 3854 | { | 3862 | list_del_rcu(&event->rb_entry); |
| 3855 | unsigned long flags; | 3863 | spin_unlock_irqrestore(&old_rb->event_lock, flags); |
| 3864 | } | ||
| 3856 | 3865 | ||
| 3857 | if (list_empty(&event->rb_entry)) | 3866 | if (event->rcu_pending && rb) { |
| 3858 | return; | 3867 | cond_synchronize_rcu(event->rcu_batches); |
| 3868 | event->rcu_pending = 0; | ||
| 3869 | } | ||
| 3870 | |||
| 3871 | if (rb) { | ||
| 3872 | spin_lock_irqsave(&rb->event_lock, flags); | ||
| 3873 | list_add_rcu(&event->rb_entry, &rb->event_list); | ||
| 3874 | spin_unlock_irqrestore(&rb->event_lock, flags); | ||
| 3875 | } | ||
| 3876 | |||
| 3877 | rcu_assign_pointer(event->rb, rb); | ||
| 3859 | 3878 | ||
| 3860 | spin_lock_irqsave(&rb->event_lock, flags); | ||
