[Devel] [PATCH rh7 2/2] mm/memcg: close potential race of kmem unharge and reparent.
Andrey Ryabinin
aryabinin at virtuozzo.com
Wed Aug 14 15:02:57 MSK 2019
Make sure that we uncharge ->kmem first, so that mem_cgroup_reparent_charges()
won't see false positive ->memory <= ->kmem.
Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
mm/memcontrol.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 435fdcf8c141..45ed18514992 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3206,13 +3206,13 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, bool kmem_charge
* successful charge implies full memory barrier.
*/
if (unlikely(memcg->is_offline)) {
- page_counter_uncharge(&memcg->memory, batch);
- if (do_swap_account)
- page_counter_uncharge(&memcg->memsw, batch);
if (kmem_charge) {
WARN_ON_ONCE(1);
page_counter_uncharge(&memcg->kmem, nr_pages);
}
+ page_counter_uncharge(&memcg->memory, batch);
+ if (do_swap_account)
+ page_counter_uncharge(&memcg->memsw, batch);
goto bypass;
}
@@ -4380,6 +4380,13 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg)
* charge before adding to the LRU.
*/
mem = page_counter_read(&memcg->memory);
+
+ /*
+ * Make sure that we won't see ->memory ucharge before ->kmem unharge,
+ * see uncharge_batch(), memcg_uncharge_kmem(). Pairing barrier provided
+ * by page_counter_ucharge()->page_counter_cancel()->atomic_long_sub_return().
+ */
+ smp_rmb();
kmem = page_counter_read(&memcg->kmem);
} while ((mem - kmem > 0) && time_before(jiffies, timeout));
@@ -7582,12 +7589,12 @@ static void uncharge_batch(struct mem_cgroup *memcg, unsigned long pgpgout,
unsigned long flags;
if (!mem_cgroup_is_root(memcg)) {
+ if (nr_kmem)
+ page_counter_uncharge(&memcg->kmem, nr_kmem);
if (nr_mem + nr_kmem)
page_counter_uncharge(&memcg->memory, nr_mem + nr_kmem);
if (nr_memsw + nr_kmem)
page_counter_uncharge(&memcg->memsw, nr_memsw + nr_kmem);
- if (nr_kmem)
- page_counter_uncharge(&memcg->kmem, nr_kmem);
if (nr_file)
page_counter_uncharge(&memcg->cache, nr_file - nr_shmem);
--
2.21.0
More information about the Devel
mailing list