mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
mm/page_counter: use WRITE_ONCE() for emin/elow when parent is the root
page_counter_calculate_protection() runs without locks. Several reclaimers can update the same counter's emin and elow at the same time, and readers such as mem_cgroup_below_min(), mem_cgroup_protection() and the dmem eviction code load them with READ_ONCE(). Commitb3a7822e5e("mm, memcg: prevent mem_cgroup_protected store tearing") made the main path store emin and elow with WRITE_ONCE(), but it missed the early return for a counter whose parent is the reclaim root. Those two stores are the only plain accesses to emin and elow left. With CONFIG_KCSAN_STRICT=y, a few tasks writing to the same cgroup's memory.reclaim trigger reports like this within seconds: BUG: KCSAN: data-race in page_counter_calculate_protection / shrink_node read (marked) to 0xff1f91b146d40e40 of 8 bytes by task 163 on cpu 4: shrink_node+0x57a/0x1210 do_try_to_free_pages+0x194/0x930 try_to_free_mem_cgroup_pages+0x204/0x3f0 user_proactive_reclaim+0x28a/0x4d0 memory_reclaim+0x35/0x50 ... write to 0xff1f91b146d40e40 of 8 bytes by task 167 on cpu 6: page_counter_calculate_protection+0x1fa/0x360 mem_cgroup_calculate_protection+0x4e/0x70 shrink_node+0x53e/0x1210 ... The default KCSAN config does not report it, because it treats aligned word-sized plain writes as atomic. Use WRITE_ONCE() for these two stores as well. There is no functional change. Readers already accept stale values, and compilers emit a single word-sized store either way: with GCC 14 the x86-64 object code is the same before and after this change. Link: https://lore.kernel.org/20261021204818.3431099-1-shakeel.butt@linux.dev Fixes:b3a7822e5e("mm, memcg: prevent mem_cgroup_protected store tearing") Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Reported-by: Sashiko <sashiko-bot@kernel.org> Reviewed-by: Gregory Price (Meta) <gourry@gourry.net> Reviewed-by: SJ Park <sj@kernel.org> Acked-by: Muchun Song <muchun.song@linux.dev> Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@kernel.org> Cc: Roman Gushchin <roman.gushchin@linux.dev> Cc: Chris Down <chris@chrisdown.name>
This commit is contained in:
parent
30a397468e
commit
51542d55bc
|
|
@ -472,8 +472,8 @@ void page_counter_calculate_protection(struct page_counter *root,
|
|||
return;
|
||||
|
||||
if (parent == root) {
|
||||
counter->emin = READ_ONCE(counter->min);
|
||||
counter->elow = READ_ONCE(counter->low);
|
||||
WRITE_ONCE(counter->emin, READ_ONCE(counter->min));
|
||||
WRITE_ONCE(counter->elow, READ_ONCE(counter->low));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user