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;
|
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;
|
||||||
|
|
Loading…
Reference in a new issue