]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blobdiff - kernel/events/core.c
locking/atomics: COCCINELLE/treewide: Convert trivial ACCESS_ONCE() patterns to READ_...
[mirror_ubuntu-focal-kernel.git] / kernel / events / core.c
index 6bc21e202ae40d36ceb9fa23d3c78785cad957da..8fd2f2d1358a852e66735ebd34cdf2e3aba84095 100644 (file)
@@ -662,7 +662,7 @@ static inline void update_cgrp_time_from_event(struct perf_event *event)
        /*
         * Do not update time when cgroup is not active
         */
-       if (cgrp == event->cgrp)
+       if (cgroup_is_descendant(cgrp->css.cgroup, event->cgrp->css.cgroup))
                __update_cgrp_time(event->cgrp);
 }
 
@@ -1200,7 +1200,7 @@ perf_event_ctx_lock_nested(struct perf_event *event, int nesting)
 
 again:
        rcu_read_lock();
-       ctx = ACCESS_ONCE(event->ctx);
+       ctx = READ_ONCE(event->ctx);
        if (!atomic_inc_not_zero(&ctx->refcount)) {
                rcu_read_unlock();
                goto again;
@@ -4231,7 +4231,7 @@ static void perf_remove_from_owner(struct perf_event *event)
         * indeed free this event, otherwise we need to serialize on
         * owner->perf_event_mutex.
         */
-       owner = lockless_dereference(event->owner);
+       owner = READ_ONCE(event->owner);
        if (owner) {
                /*
                 * Since delayed_put_task_struct() also drops the last
@@ -4328,7 +4328,7 @@ again:
                 * Cannot change, child events are not migrated, see the
                 * comment with perf_event_ctx_lock_nested().
                 */
-               ctx = lockless_dereference(child->ctx);
+               ctx = READ_ONCE(child->ctx);
                /*
                 * Since child_mutex nests inside ctx::mutex, we must jump
                 * through hoops. We start by grabbing a reference on the ctx.
@@ -5302,8 +5302,8 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
                if (!rb)
                        goto aux_unlock;
 
-               aux_offset = ACCESS_ONCE(rb->user_page->aux_offset);
-               aux_size = ACCESS_ONCE(rb->user_page->aux_size);
+               aux_offset = READ_ONCE(rb->user_page->aux_offset);
+               aux_size = READ_ONCE(rb->user_page->aux_size);
 
                if (aux_offset < perf_data_size(rb) + PAGE_SIZE)
                        goto aux_unlock;
@@ -8955,6 +8955,14 @@ static struct perf_cpu_context __percpu *find_pmu_context(int ctxn)
 
 static void free_pmu_context(struct pmu *pmu)
 {
+       /*
+        * Static contexts such as perf_sw_context have a global lifetime
+        * and may be shared between different PMUs. Avoid freeing them
+        * when a single PMU is going away.
+        */
+       if (pmu->task_ctx_nr > perf_invalid_context)
+               return;
+
        mutex_lock(&pmus_lock);
        free_percpu(pmu->pmu_cpu_context);
        mutex_unlock(&pmus_lock);