Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a9e97b2 authored by Tejun Heo's avatar Tejun Heo
Browse files

cgroup: Add memory barriers to plug cgroup_rstat_updated() race window



cgroup_rstat_updated() has a small race window where an updated
signaling can race with flush and could be lost till the next update.
This wasn't a problem for the existing usages, but we plan to use
rstat to track counters which need to be accurate.

This patch plugs the race window by synchronizing
cgroup_rstat_updated() and flush path with memory barriers around
cgroup_rstat_cpu->updated_next pointer.

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent 8f53470b
Loading
Loading
Loading
Loading
+13 −3
Original line number Original line Diff line number Diff line
@@ -28,9 +28,12 @@ void cgroup_rstat_updated(struct cgroup *cgrp, int cpu)
	unsigned long flags;
	unsigned long flags;


	/*
	/*
	 * Speculative already-on-list test.  This may race leading to
	 * Paired with the one in cgroup_rstat_cpu_pop_upated().  Either we
	 * temporary inaccuracies, which is fine.
	 * see NULL updated_next or they see our updated stat.
	 *
	 */
	smp_mb();

	/*
	 * Because @parent's updated_children is terminated with @parent
	 * Because @parent's updated_children is terminated with @parent
	 * instead of NULL, we can tell whether @cgrp is on the list by
	 * instead of NULL, we can tell whether @cgrp is on the list by
	 * testing the next pointer for NULL.
	 * testing the next pointer for NULL.
@@ -126,6 +129,13 @@ static struct cgroup *cgroup_rstat_cpu_pop_updated(struct cgroup *pos,


		*nextp = rstatc->updated_next;
		*nextp = rstatc->updated_next;
		rstatc->updated_next = NULL;
		rstatc->updated_next = NULL;

		/*
		 * Paired with the one in cgroup_rstat_cpu_updated().
		 * Either they see NULL updated_next or we see their
		 * updated stat.
		 */
		smp_mb();
	}
	}


	return pos;
	return pos;