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: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
8f53470bab
commit
9a9e97b2f1
1 changed files with 13 additions and 3 deletions
|
@ -28,9 +28,12 @@ void cgroup_rstat_updated(struct cgroup *cgrp, int cpu)
|
|||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Speculative already-on-list test. This may race leading to
|
||||
* temporary inaccuracies, which is fine.
|
||||
*
|
||||
* Paired with the one in cgroup_rstat_cpu_pop_upated(). Either we
|
||||
* see NULL updated_next or they see our updated stat.
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
/*
|
||||
* Because @parent's updated_children is terminated with @parent
|
||||
* instead of NULL, we can tell whether @cgrp is on the list by
|
||||
* 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;
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue