Reclaiming memory above memory.cache.limit_in_bytes always in direct reclaim mode adds to much of a cost for vstorage. Instead of direct reclaim allow to overflow memory.cache.limit_in_bytes but launch the reclaim in background task.
https://pmc.acronis.com/browse/VSTOR-24395 https://jira.sw.ru/browse/PSBM-94761 Signed-off-by: Andrey Ryabinin <[email protected]> --- mm/memcontrol.c | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index cc8cf887c205..a28a66bff002 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3002,11 +3002,15 @@ static void reclaim_high(struct mem_cgroup *memcg, unsigned int nr_pages, gfp_t gfp_mask) { + do { - if (page_counter_read(&memcg->memory) <= memcg->high) - continue; + if (page_counter_read(&memcg->memory) > memcg->high) + try_to_free_mem_cgroup_pages(memcg, nr_pages, gfp_mask, 0); + + if (page_counter_read(&memcg->cache) > memcg->cache.limit) + try_to_free_mem_cgroup_pages(memcg, nr_pages, gfp_mask, + MEM_CGROUP_RECLAIM_NOSWAP); - try_to_free_mem_cgroup_pages(memcg, nr_pages, gfp_mask, 0); } while ((memcg = parent_mem_cgroup(memcg))); } @@ -3067,11 +3071,6 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, bool kmem_charge goto charge; } - if (cache_charge && page_counter_try_charge( - &memcg->cache, nr_pages, &counter)) { - refill_stock(memcg, nr_pages); - goto charge; - } goto done; } @@ -3097,19 +3096,6 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, bool kmem_charge } } - if (!mem_over_limit && cache_charge) { - if (!page_counter_try_charge(&memcg->cache, nr_pages, &counter)) - goto done_restock; - - flags |= MEM_CGROUP_RECLAIM_NOSWAP; - mem_over_limit = mem_cgroup_from_counter(counter, cache); - page_counter_uncharge(&memcg->memory, batch); - if (do_swap_account) - page_counter_uncharge(&memcg->memsw, batch); - if (kmem_charge) - page_counter_uncharge(&memcg->kmem, batch); - } - if (!mem_over_limit) goto done_restock; @@ -3222,8 +3208,6 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, bool kmem_charge page_counter_uncharge(&memcg->memory, batch); if (do_swap_account) page_counter_uncharge(&memcg->memsw, batch); - if (cache_charge) - page_counter_uncharge(&memcg->cache, nr_pages); if (kmem_charge) { WARN_ON_ONCE(1); page_counter_uncharge(&memcg->kmem, nr_pages); @@ -3235,6 +3219,9 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, bool kmem_charge if (batch > nr_pages) refill_stock(memcg, batch - nr_pages); done: + if (cache_charge) + page_counter_charge(&memcg->cache, nr_pages); + /* * If the hierarchy is above the normal consumption range, schedule * reclaim on returning to userland. We can perform reclaim here @@ -3254,7 +3241,11 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, bool kmem_charge current->memcg_nr_pages_over_high += batch; set_notify_resume(current); break; + } else if (page_counter_read(&memcg->cache) > memcg->cache.limit) { + if (!work_pending(&memcg->high_work)) + schedule_work(&memcg->high_work); } + } while ((memcg = parent_mem_cgroup(memcg))); return 0; -- 2.21.0 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
