mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-04 12:13:43 +00:00
mm: increment gen # before restarting traversal
The generation number in struct mem_cgroup_reclaim_iter should be incremented on every round-trip. Currently, it is possible for a concurrent reclaimer to jump in at the end of the hierarchy, causing a traversal restart (resetting the iteration position) without incrementing the generation number. By resetting the position without incrementing the generation, it's possible for another ongoing mem_cgroup_iter() thread to walk the tree twice. Move the traversal restart such that the generation number is incremented before the restart. Link: https://lkml.kernel.org/r/20240905003058.1859929-4-kinseyho@google.com Signed-off-by: Kinsey Ho <kinseyho@google.com> Reviewed-by: T.J. Mercier <tjmercier@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@kernel.org> Cc: Michal Koutný <mkoutny@suse.com> Cc: Muchun Song <muchun.song@linux.dev> Cc: Roman Gushchin <roman.gushchin@linux.dev> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Tejun Heo <tj@kernel.org> Cc: Yosry Ahmed <yosryahmed@google.com> Cc: Zefan Li <lizefan.x@bytedance.com> Cc: Hugh Dickins <hughd@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
4a2698b013
commit
3d150e31a1
@ -997,7 +997,7 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
|
|||||||
root = root_mem_cgroup;
|
root = root_mem_cgroup;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
restart:
|
||||||
if (reclaim) {
|
if (reclaim) {
|
||||||
struct mem_cgroup_per_node *mz;
|
struct mem_cgroup_per_node *mz;
|
||||||
|
|
||||||
@ -1024,14 +1024,6 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
css = css_next_descendant_pre(css, &root->css);
|
css = css_next_descendant_pre(css, &root->css);
|
||||||
if (!css) {
|
if (!css) {
|
||||||
/*
|
|
||||||
* Reclaimers share the hierarchy walk, and a
|
|
||||||
* new one might jump in right at the end of
|
|
||||||
* the hierarchy - make sure they see at least
|
|
||||||
* one group and restart from the beginning.
|
|
||||||
*/
|
|
||||||
if (!prev)
|
|
||||||
continue;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1054,8 +1046,18 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
|
|||||||
*/
|
*/
|
||||||
(void)cmpxchg(&iter->position, pos, memcg);
|
(void)cmpxchg(&iter->position, pos, memcg);
|
||||||
|
|
||||||
if (!memcg)
|
if (!memcg) {
|
||||||
iter->generation++;
|
iter->generation++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reclaimers share the hierarchy walk, and a
|
||||||
|
* new one might jump in right at the end of
|
||||||
|
* the hierarchy - make sure they see at least
|
||||||
|
* one group and restart from the beginning.
|
||||||
|
*/
|
||||||
|
if (!prev)
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
|
Loading…
Reference in New Issue
Block a user