diff options
author | Jiri Kosina <jkosina@suse.cz> | 2011-02-15 04:24:31 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-02-15 04:24:31 -0500 |
commit | 0a9d59a2461477bd9ed143c01af9df3f8f00fa81 (patch) | |
tree | df997d1cfb0786427a0df1fbd6f0640fa4248cf4 /kernel/perf_event.c | |
parent | a23ce6da9677d245aa0aadc99f4197030350ab54 (diff) | |
parent | 795abaf1e4e188c4171e3cd3dbb11a9fcacaf505 (diff) |
Merge branch 'master' into for-next
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r-- | kernel/perf_event.c | 79 |
1 files changed, 44 insertions, 35 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 05ebe841270b..999835b6112b 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -1901,11 +1901,12 @@ static void __perf_event_read(void *info) | |||
1901 | return; | 1901 | return; |
1902 | 1902 | ||
1903 | raw_spin_lock(&ctx->lock); | 1903 | raw_spin_lock(&ctx->lock); |
1904 | update_context_time(ctx); | 1904 | if (ctx->is_active) |
1905 | update_context_time(ctx); | ||
1905 | update_event_times(event); | 1906 | update_event_times(event); |
1907 | if (event->state == PERF_EVENT_STATE_ACTIVE) | ||
1908 | event->pmu->read(event); | ||
1906 | raw_spin_unlock(&ctx->lock); | 1909 | raw_spin_unlock(&ctx->lock); |
1907 | |||
1908 | event->pmu->read(event); | ||
1909 | } | 1910 | } |
1910 | 1911 | ||
1911 | static inline u64 perf_event_count(struct perf_event *event) | 1912 | static inline u64 perf_event_count(struct perf_event *event) |
@@ -1999,8 +2000,7 @@ static int alloc_callchain_buffers(void) | |||
1999 | * accessed from NMI. Use a temporary manual per cpu allocation | 2000 | * accessed from NMI. Use a temporary manual per cpu allocation |
2000 | * until that gets sorted out. | 2001 | * until that gets sorted out. |
2001 | */ | 2002 | */ |
2002 | size = sizeof(*entries) + sizeof(struct perf_callchain_entry *) * | 2003 | size = offsetof(struct callchain_cpus_entries, cpu_entries[nr_cpu_ids]); |
2003 | num_possible_cpus(); | ||
2004 | 2004 | ||
2005 | entries = kzalloc(size, GFP_KERNEL); | 2005 | entries = kzalloc(size, GFP_KERNEL); |
2006 | if (!entries) | 2006 | if (!entries) |
@@ -2201,13 +2201,6 @@ find_lively_task_by_vpid(pid_t vpid) | |||
2201 | if (!task) | 2201 | if (!task) |
2202 | return ERR_PTR(-ESRCH); | 2202 | return ERR_PTR(-ESRCH); |
2203 | 2203 | ||
2204 | /* | ||
2205 | * Can't attach events to a dying task. | ||
2206 | */ | ||
2207 | err = -ESRCH; | ||
2208 | if (task->flags & PF_EXITING) | ||
2209 | goto errout; | ||
2210 | |||
2211 | /* Reuse ptrace permission checks for now. */ | 2204 | /* Reuse ptrace permission checks for now. */ |
2212 | err = -EACCES; | 2205 | err = -EACCES; |
2213 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) | 2206 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) |
@@ -2228,14 +2221,11 @@ find_get_context(struct pmu *pmu, struct task_struct *task, int cpu) | |||
2228 | unsigned long flags; | 2221 | unsigned long flags; |
2229 | int ctxn, err; | 2222 | int ctxn, err; |
2230 | 2223 | ||
2231 | if (!task && cpu != -1) { | 2224 | if (!task) { |
2232 | /* Must be root to operate on a CPU event: */ | 2225 | /* Must be root to operate on a CPU event: */ |
2233 | if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) | 2226 | if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) |
2234 | return ERR_PTR(-EACCES); | 2227 | return ERR_PTR(-EACCES); |
2235 | 2228 | ||
2236 | if (cpu < 0 || cpu >= nr_cpumask_bits) | ||
2237 | return ERR_PTR(-EINVAL); | ||
2238 | |||
2239 | /* | 2229 | /* |
2240 | * We could be clever and allow to attach a event to an | 2230 | * We could be clever and allow to attach a event to an |
2241 | * offline CPU and activate it when the CPU comes up, but | 2231 | * offline CPU and activate it when the CPU comes up, but |
@@ -2271,14 +2261,27 @@ retry: | |||
2271 | 2261 | ||
2272 | get_ctx(ctx); | 2262 | get_ctx(ctx); |
2273 | 2263 | ||
2274 | if (cmpxchg(&task->perf_event_ctxp[ctxn], NULL, ctx)) { | 2264 | err = 0; |
2275 | /* | 2265 | mutex_lock(&task->perf_event_mutex); |
2276 | * We raced with some other task; use | 2266 | /* |
2277 | * the context they set. | 2267 | * If it has already passed perf_event_exit_task(). |
2278 | */ | 2268 | * we must see PF_EXITING, it takes this mutex too. |
2269 | */ | ||
2270 | if (task->flags & PF_EXITING) | ||
2271 | err = -ESRCH; | ||
2272 | else if (task->perf_event_ctxp[ctxn]) | ||
2273 | err = -EAGAIN; | ||
2274 | else | ||
2275 | rcu_assign_pointer(task->perf_event_ctxp[ctxn], ctx); | ||
2276 | mutex_unlock(&task->perf_event_mutex); | ||
2277 | |||
2278 | if (unlikely(err)) { | ||
2279 | put_task_struct(task); | 2279 | put_task_struct(task); |
2280 | kfree(ctx); | 2280 | kfree(ctx); |
2281 | goto retry; | 2281 | |
2282 | if (err == -EAGAIN) | ||
2283 | goto retry; | ||
2284 | goto errout; | ||
2282 | } | 2285 | } |
2283 | } | 2286 | } |
2284 | 2287 | ||
@@ -5377,6 +5380,8 @@ free_dev: | |||
5377 | goto out; | 5380 | goto out; |
5378 | } | 5381 | } |
5379 | 5382 | ||
5383 | static struct lock_class_key cpuctx_mutex; | ||
5384 | |||
5380 | int perf_pmu_register(struct pmu *pmu, char *name, int type) | 5385 | int perf_pmu_register(struct pmu *pmu, char *name, int type) |
5381 | { | 5386 | { |
5382 | int cpu, ret; | 5387 | int cpu, ret; |
@@ -5425,6 +5430,7 @@ skip_type: | |||
5425 | 5430 | ||
5426 | cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); | 5431 | cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); |
5427 | __perf_event_init_context(&cpuctx->ctx); | 5432 | __perf_event_init_context(&cpuctx->ctx); |
5433 | lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex); | ||
5428 | cpuctx->ctx.type = cpu_context; | 5434 | cpuctx->ctx.type = cpu_context; |
5429 | cpuctx->ctx.pmu = pmu; | 5435 | cpuctx->ctx.pmu = pmu; |
5430 | cpuctx->jiffies_interval = 1; | 5436 | cpuctx->jiffies_interval = 1; |
@@ -5541,6 +5547,11 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
5541 | struct hw_perf_event *hwc; | 5547 | struct hw_perf_event *hwc; |
5542 | long err; | 5548 | long err; |
5543 | 5549 | ||
5550 | if ((unsigned)cpu >= nr_cpu_ids) { | ||
5551 | if (!task || cpu != -1) | ||
5552 | return ERR_PTR(-EINVAL); | ||
5553 | } | ||
5554 | |||
5544 | event = kzalloc(sizeof(*event), GFP_KERNEL); | 5555 | event = kzalloc(sizeof(*event), GFP_KERNEL); |
5545 | if (!event) | 5556 | if (!event) |
5546 | return ERR_PTR(-ENOMEM); | 5557 | return ERR_PTR(-ENOMEM); |
@@ -5589,7 +5600,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
5589 | 5600 | ||
5590 | if (!overflow_handler && parent_event) | 5601 | if (!overflow_handler && parent_event) |
5591 | overflow_handler = parent_event->overflow_handler; | 5602 | overflow_handler = parent_event->overflow_handler; |
5592 | 5603 | ||
5593 | event->overflow_handler = overflow_handler; | 5604 | event->overflow_handler = overflow_handler; |
5594 | 5605 | ||
5595 | if (attr->disabled) | 5606 | if (attr->disabled) |
@@ -6125,7 +6136,7 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn) | |||
6125 | * scheduled, so we are now safe from rescheduling changing | 6136 | * scheduled, so we are now safe from rescheduling changing |
6126 | * our context. | 6137 | * our context. |
6127 | */ | 6138 | */ |
6128 | child_ctx = child->perf_event_ctxp[ctxn]; | 6139 | child_ctx = rcu_dereference_raw(child->perf_event_ctxp[ctxn]); |
6129 | task_ctx_sched_out(child_ctx, EVENT_ALL); | 6140 | task_ctx_sched_out(child_ctx, EVENT_ALL); |
6130 | 6141 | ||
6131 | /* | 6142 | /* |
@@ -6438,11 +6449,6 @@ int perf_event_init_context(struct task_struct *child, int ctxn) | |||
6438 | unsigned long flags; | 6449 | unsigned long flags; |
6439 | int ret = 0; | 6450 | int ret = 0; |
6440 | 6451 | ||
6441 | child->perf_event_ctxp[ctxn] = NULL; | ||
6442 | |||
6443 | mutex_init(&child->perf_event_mutex); | ||
6444 | INIT_LIST_HEAD(&child->perf_event_list); | ||
6445 | |||
6446 | if (likely(!parent->perf_event_ctxp[ctxn])) | 6452 | if (likely(!parent->perf_event_ctxp[ctxn])) |
6447 | return 0; | 6453 | return 0; |
6448 | 6454 | ||
@@ -6494,7 +6500,6 @@ int perf_event_init_context(struct task_struct *child, int ctxn) | |||
6494 | 6500 | ||
6495 | raw_spin_lock_irqsave(&parent_ctx->lock, flags); | 6501 | raw_spin_lock_irqsave(&parent_ctx->lock, flags); |
6496 | parent_ctx->rotate_disable = 0; | 6502 | parent_ctx->rotate_disable = 0; |
6497 | raw_spin_unlock_irqrestore(&parent_ctx->lock, flags); | ||
6498 | 6503 | ||
6499 | child_ctx = child->perf_event_ctxp[ctxn]; | 6504 | child_ctx = child->perf_event_ctxp[ctxn]; |
6500 | 6505 | ||
@@ -6502,12 +6507,11 @@ int perf_event_init_context(struct task_struct *child, int ctxn) | |||
6502 | /* | 6507 | /* |
6503 | * Mark the child context as a clone of the parent | 6508 | * Mark the child context as a clone of the parent |
6504 | * context, or of whatever the parent is a clone of. | 6509 | * context, or of whatever the parent is a clone of. |
6505 | * Note that if the parent is a clone, it could get | 6510 | * |
6506 | * uncloned at any point, but that doesn't matter | 6511 | * Note that if the parent is a clone, the holding of |
6507 | * because the list of events and the generation | 6512 | * parent_ctx->lock avoids it from being uncloned. |
6508 | * count can't have changed since we took the mutex. | ||
6509 | */ | 6513 | */ |
6510 | cloned_ctx = rcu_dereference(parent_ctx->parent_ctx); | 6514 | cloned_ctx = parent_ctx->parent_ctx; |
6511 | if (cloned_ctx) { | 6515 | if (cloned_ctx) { |
6512 | child_ctx->parent_ctx = cloned_ctx; | 6516 | child_ctx->parent_ctx = cloned_ctx; |
6513 | child_ctx->parent_gen = parent_ctx->parent_gen; | 6517 | child_ctx->parent_gen = parent_ctx->parent_gen; |
@@ -6518,6 +6522,7 @@ int perf_event_init_context(struct task_struct *child, int ctxn) | |||
6518 | get_ctx(child_ctx->parent_ctx); | 6522 | get_ctx(child_ctx->parent_ctx); |
6519 | } | 6523 | } |
6520 | 6524 | ||
6525 | raw_spin_unlock_irqrestore(&parent_ctx->lock, flags); | ||
6521 | mutex_unlock(&parent_ctx->mutex); | 6526 | mutex_unlock(&parent_ctx->mutex); |
6522 | 6527 | ||
6523 | perf_unpin_context(parent_ctx); | 6528 | perf_unpin_context(parent_ctx); |
@@ -6532,6 +6537,10 @@ int perf_event_init_task(struct task_struct *child) | |||
6532 | { | 6537 | { |
6533 | int ctxn, ret; | 6538 | int ctxn, ret; |
6534 | 6539 | ||
6540 | memset(child->perf_event_ctxp, 0, sizeof(child->perf_event_ctxp)); | ||
6541 | mutex_init(&child->perf_event_mutex); | ||
6542 | INIT_LIST_HEAD(&child->perf_event_list); | ||
6543 | |||
6535 | for_each_task_context_nr(ctxn) { | 6544 | for_each_task_context_nr(ctxn) { |
6536 | ret = perf_event_init_context(child, ctxn); | 6545 | ret = perf_event_init_context(child, ctxn); |
6537 | if (ret) | 6546 | if (ret) |