perf/cgroup: Fix child event counting bug
[platform/kernel/linux-rpi.git] / kernel / events / core.c
index cb8274d..bd9d4d3 100644 (file)
@@ -642,9 +642,15 @@ static inline void __update_cgrp_time(struct perf_cgroup *cgrp)
 
 static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx)
 {
-       struct perf_cgroup *cgrp_out = cpuctx->cgrp;
-       if (cgrp_out)
-               __update_cgrp_time(cgrp_out);
+       struct perf_cgroup *cgrp = cpuctx->cgrp;
+       struct cgroup_subsys_state *css;
+
+       if (cgrp) {
+               for (css = &cgrp->css; css; css = css->parent) {
+                       cgrp = container_of(css, struct perf_cgroup, css);
+                       __update_cgrp_time(cgrp);
+               }
+       }
 }
 
 static inline void update_cgrp_time_from_event(struct perf_event *event)
@@ -672,6 +678,7 @@ perf_cgroup_set_timestamp(struct task_struct *task,
 {
        struct perf_cgroup *cgrp;
        struct perf_cgroup_info *info;
+       struct cgroup_subsys_state *css;
 
        /*
         * ctx->lock held by caller
@@ -682,8 +689,12 @@ perf_cgroup_set_timestamp(struct task_struct *task,
                return;
 
        cgrp = perf_cgroup_from_task(task, ctx);
-       info = this_cpu_ptr(cgrp->info);
-       info->timestamp = ctx->timestamp;
+
+       for (css = &cgrp->css; css; css = css->parent) {
+               cgrp = container_of(css, struct perf_cgroup, css);
+               info = this_cpu_ptr(cgrp->info);
+               info->timestamp = ctx->timestamp;
+       }
 }
 
 static DEFINE_PER_CPU(struct list_head, cgrp_cpuctx_list);