aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_event.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2010-09-07 09:55:13 -0400
committerIngo Molnar <mingo@elte.hu>2010-09-09 14:46:33 -0400
commiteb184479874238393ac186c4e054d24311c34aaa (patch)
treeac7206becfb3e0d18600252d8f5aa15478c32390 /kernel/perf_event.c
parent97dee4f3206622f31396dede2b5ddb8670458f56 (diff)
perf: Clean up perf_event_context allocation
Unify the two perf_event_context allocation sites. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: paulus <paulus@samba.org> Cc: stephane eranian <eranian@googlemail.com> Cc: Robert Richter <robert.richter@amd.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Lin Ming <ming.m.lin@intel.com> Cc: Yanmin <yanmin_zhang@linux.intel.com> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r--kernel/perf_event.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index dae0e2f3029..13d98d75634 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1959,9 +1959,7 @@ exit_put:
1959/* 1959/*
1960 * Initialize the perf_event context in a task_struct: 1960 * Initialize the perf_event context in a task_struct:
1961 */ 1961 */
1962static void 1962static void __perf_event_init_context(struct perf_event_context *ctx)
1963__perf_event_init_context(struct perf_event_context *ctx,
1964 struct task_struct *task)
1965{ 1963{
1966 raw_spin_lock_init(&ctx->lock); 1964 raw_spin_lock_init(&ctx->lock);
1967 mutex_init(&ctx->mutex); 1965 mutex_init(&ctx->mutex);
@@ -1969,7 +1967,25 @@ __perf_event_init_context(struct perf_event_context *ctx,
1969 INIT_LIST_HEAD(&ctx->flexible_groups); 1967 INIT_LIST_HEAD(&ctx->flexible_groups);
1970 INIT_LIST_HEAD(&ctx->event_list); 1968 INIT_LIST_HEAD(&ctx->event_list);
1971 atomic_set(&ctx->refcount, 1); 1969 atomic_set(&ctx->refcount, 1);
1972 ctx->task = task; 1970}
1971
1972static struct perf_event_context *
1973alloc_perf_context(struct pmu *pmu, struct task_struct *task)
1974{
1975 struct perf_event_context *ctx;
1976
1977 ctx = kzalloc(sizeof(struct perf_event_context), GFP_KERNEL);
1978 if (!ctx)
1979 return NULL;
1980
1981 __perf_event_init_context(ctx);
1982 if (task) {
1983 ctx->task = task;
1984 get_task_struct(task);
1985 }
1986 ctx->pmu = pmu;
1987
1988 return ctx;
1973} 1989}
1974 1990
1975static struct perf_event_context * 1991static struct perf_event_context *
@@ -2036,22 +2052,22 @@ retry:
2036 } 2052 }
2037 2053
2038 if (!ctx) { 2054 if (!ctx) {
2039 ctx = kzalloc(sizeof(struct perf_event_context), GFP_KERNEL); 2055 ctx = alloc_perf_context(pmu, task);
2040 err = -ENOMEM; 2056 err = -ENOMEM;
2041 if (!ctx) 2057 if (!ctx)
2042 goto errout; 2058 goto errout;
2043 __perf_event_init_context(ctx, task); 2059
2044 ctx->pmu = pmu;
2045 get_ctx(ctx); 2060 get_ctx(ctx);
2061
2046 if (cmpxchg(&task->perf_event_ctxp, NULL, ctx)) { 2062 if (cmpxchg(&task->perf_event_ctxp, NULL, ctx)) {
2047 /* 2063 /*
2048 * We raced with some other task; use 2064 * We raced with some other task; use
2049 * the context they set. 2065 * the context they set.
2050 */ 2066 */
2067 put_task_struct(task);
2051 kfree(ctx); 2068 kfree(ctx);
2052 goto retry; 2069 goto retry;
2053 } 2070 }
2054 get_task_struct(task);
2055 } 2071 }
2056 2072
2057 put_task_struct(task); 2073 put_task_struct(task);
@@ -5044,7 +5060,7 @@ int perf_pmu_register(struct pmu *pmu)
5044 struct perf_cpu_context *cpuctx; 5060 struct perf_cpu_context *cpuctx;
5045 5061
5046 cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); 5062 cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
5047 __perf_event_init_context(&cpuctx->ctx, NULL); 5063 __perf_event_init_context(&cpuctx->ctx);
5048 cpuctx->ctx.pmu = pmu; 5064 cpuctx->ctx.pmu = pmu;
5049 cpuctx->timer_interval = TICK_NSEC; 5065 cpuctx->timer_interval = TICK_NSEC;
5050 hrtimer_init(&cpuctx->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 5066 hrtimer_init(&cpuctx->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
@@ -5866,15 +5882,11 @@ inherit_task_group(struct perf_event *event, struct task_struct *parent,
5866 * child. 5882 * child.
5867 */ 5883 */
5868 5884
5869 child_ctx = kzalloc(sizeof(struct perf_event_context), 5885 child_ctx = alloc_perf_context(event->pmu, child);
5870 GFP_KERNEL);
5871 if (!child_ctx) 5886 if (!child_ctx)
5872 return -ENOMEM; 5887 return -ENOMEM;
5873 5888
5874 __perf_event_init_context(child_ctx, child);
5875 child_ctx->pmu = event->pmu;
5876 child->perf_event_ctxp = child_ctx; 5889 child->perf_event_ctxp = child_ctx;
5877 get_task_struct(child);
5878 } 5890 }
5879 5891
5880 ret = inherit_group(event, parent, parent_ctx, 5892 ret = inherit_group(event, parent, parent_ctx,
@@ -5886,7 +5898,6 @@ inherit_task_group(struct perf_event *event, struct task_struct *parent,
5886 return ret; 5898 return ret;
5887} 5899}
5888 5900
5889
5890/* 5901/*
5891 * Initialize the perf_event context in task_struct 5902 * Initialize the perf_event context in task_struct
5892 */ 5903 */