From: "Yan, Zheng" <zheng.z....@intel.com>

allow allocating PMU specific data for perf task context

Signed-off-by: Yan, Zheng <zheng.z....@intel.com>
---
 include/linux/perf_event.h |  5 +++++
 kernel/events/core.c       | 19 ++++++++++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 96cb88b..147f9d3 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -252,6 +252,10 @@ struct pmu {
         */
        void (*sched_task)              (struct perf_event_context *ctx,
                                         bool sched_in);
+       /*
+        * PMU specific data size
+        */
+       size_t                          task_ctx_size;
 };
 
 /**
@@ -496,6 +500,7 @@ struct perf_event_context {
        int                             pin_count;
        int                             nr_cgroups;      /* cgroup evts */
        int                             nr_branch_stack; /* branch_stack evt */
+       void                            *task_ctx_data; /* pmu specific data */
        struct rcu_head                 rcu_head;
 };
 
diff --git a/kernel/events/core.c b/kernel/events/core.c
index c281265..6499dae 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -882,6 +882,15 @@ static void get_ctx(struct perf_event_context *ctx)
        WARN_ON(!atomic_inc_not_zero(&ctx->refcount));
 }
 
+static void free_ctx(struct rcu_head *head)
+{
+       struct perf_event_context *ctx;
+
+       ctx = container_of(head, struct perf_event_context, rcu_head);
+       kfree(ctx->task_ctx_data);
+       kfree(ctx);
+}
+
 static void put_ctx(struct perf_event_context *ctx)
 {
        if (atomic_dec_and_test(&ctx->refcount)) {
@@ -889,7 +898,7 @@ static void put_ctx(struct perf_event_context *ctx)
                        put_ctx(ctx->parent_ctx);
                if (ctx->task)
                        put_task_struct(ctx->task);
-               kfree_rcu(ctx, rcu_head);
+               call_rcu(&ctx->rcu_head, free_ctx);
        }
 }
 
@@ -3025,6 +3034,14 @@ alloc_perf_context(struct pmu *pmu, struct task_struct 
*task)
        if (!ctx)
                return NULL;
 
+       if (task && pmu->task_ctx_size > 0) {
+               ctx->task_ctx_data = kzalloc(pmu->task_ctx_size, GFP_KERNEL);
+               if (!ctx->task_ctx_data) {
+                       kfree(ctx);
+                       return NULL;
+               }
+       }
+
        __perf_event_init_context(ctx);
        if (task) {
                ctx->task = task;
-- 
1.8.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to