The commit is pushed to "branch-rh7-3.10.0-957.27.2.vz7.107.x-ovz" and will
appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-957.27.2.vz7.107.3
------>
commit 4a279f9156ef9dbbc637924e5a46397db3e7a42b
Author: Andrey Ryabinin <[email protected]>
Date: Wed Aug 14 19:40:29 2019 +0300
mm/memcg: close potential race of kmem unharge and reparent.
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 <[email protected]>
khorenko@: note, this is not only about false positive warning we faced in
PSBM-97012, this is also about theoretical possibility of stopping
reparenting
too early due to the race.
---
mm/memcontrol.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 435fdcf8c141..464b6116c62e 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 uncharge before ->kmem
uncharge,
+ * 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);
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel