LKML Archive on lore.kernel.org help / color / mirror / Atom feed
From: Kirill Tkhai <ktkhai@virtuozzo.com> To: akpm@linux-foundation.org, vdavydov.dev@gmail.com, shakeelb@google.com, viro@zeniv.linux.org.uk, hannes@cmpxchg.org, mhocko@kernel.org, ktkhai@virtuozzo.com, tglx@linutronix.de, pombredanne@nexb.com, stummala@codeaurora.org, gregkh@linuxfoundation.org, sfr@canb.auug.org.au, guro@fb.com, mka@chromium.org, penguin-kernel@I-love.SAKURA.ne.jp, chris@chris-wilson.co.uk, longman@redhat.com, minchan@kernel.org, ying.huang@intel.com, mgorman@techsingularity.net, jbacik@fb.com, linux@roeck-us.net, linux-kernel@vger.kernel.org, linux-mm@kvack.org, willy@infradead.org, lirongqing@baidu.com, aryabinin@virtuozzo.com Subject: [PATCH v4 11/13] mm: Iterate only over charged shrinkers during memcg shrink_slab() Date: Wed, 09 May 2018 14:58:38 +0300 [thread overview] Message-ID: <152586711800.3048.17462409401469930692.stgit@localhost.localdomain> (raw) In-Reply-To: <152586686544.3048.15776787801312398314.stgit@localhost.localdomain> Using the preparations made in previous patches, in case of memcg shrink, we may avoid shrinkers, which are not set in memcg's shrinkers bitmap. To do that, we separate iterations over memcg-aware and !memcg-aware shrinkers, and memcg-aware shrinkers are chosen via for_each_set_bit() from the bitmap. In case of big nodes, having many isolated environments, this gives significant performance growth. See next patches for the details. Note, that the patch does not respect to empty memcg shrinkers, since we never clear the bitmap bits after we set it once. Their shrinkers will be called again, with no shrinked objects as result. This functionality is provided by next patches. Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com> --- include/linux/memcontrol.h | 1 + mm/vmscan.c | 70 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 1fb2f96dc2f6..4548b09e44a7 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -756,6 +756,7 @@ void mem_cgroup_split_huge_fixup(struct page *head); #define MEM_CGROUP_ID_MAX 0 struct mem_cgroup; +#define root_mem_cgroup NULL static inline bool mem_cgroup_disabled(void) { diff --git a/mm/vmscan.c b/mm/vmscan.c index d1940244d0bf..648b08621334 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -376,6 +376,7 @@ int prealloc_shrinker(struct shrinker *shrinker) goto free_deferred; } + INIT_LIST_HEAD(&shrinker->list); return 0; free_deferred: @@ -547,6 +548,63 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, return freed; } +#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB) +static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int nid, + struct mem_cgroup *memcg, int priority) +{ + struct memcg_shrinker_map *map; + unsigned long freed = 0; + int ret, i; + + if (!memcg_kmem_enabled() || !mem_cgroup_online(memcg)) + return 0; + + if (!down_read_trylock(&shrinker_rwsem)) + return 0; + + /* + * 1)Caller passes only alive memcg, so map can't be NULL. + * 2)shrinker_rwsem protects from maps expanding. + */ + map = rcu_dereference_protected(MEMCG_SHRINKER_MAP(memcg, nid), true); + BUG_ON(!map); + + for_each_set_bit(i, map->map, memcg_shrinker_nr_max) { + struct shrink_control sc = { + .gfp_mask = gfp_mask, + .nid = nid, + .memcg = memcg, + }; + struct shrinker *shrinker; + + shrinker = idr_find(&shrinker_idr, i); + if (!shrinker) { + clear_bit(i, map->map); + continue; + } + if (list_empty(&shrinker->list)) + continue; + + ret = do_shrink_slab(&sc, shrinker, priority); + freed += ret; + + if (rwsem_is_contended(&shrinker_rwsem)) { + freed = freed ? : 1; + break; + } + } + + up_read(&shrinker_rwsem); + return freed; +} +#else +static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int nid, + struct mem_cgroup *memcg, int priority) +{ + return 0; +} +#endif + /** * shrink_slab - shrink slab caches * @gfp_mask: allocation context @@ -576,8 +634,8 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct shrinker *shrinker; unsigned long freed = 0; - if (memcg && (!memcg_kmem_enabled() || !mem_cgroup_online(memcg))) - return 0; + if (memcg && memcg != root_mem_cgroup) + return shrink_slab_memcg(gfp_mask, nid, memcg, priority); if (!down_read_trylock(&shrinker_rwsem)) goto out; @@ -589,13 +647,7 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid, .memcg = memcg, }; - /* - * If kernel memory accounting is disabled, we ignore - * SHRINKER_MEMCG_AWARE flag and call all shrinkers - * passing NULL for memcg. - */ - if (memcg_kmem_enabled() && - !!memcg != !!(shrinker->flags & SHRINKER_MEMCG_AWARE)) + if (!!memcg != !!(shrinker->flags & SHRINKER_MEMCG_AWARE)) continue; if (!(shrinker->flags & SHRINKER_NUMA_AWARE))
next prev parent reply other threads:[~2018-05-09 11:58 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-05-09 11:56 [PATCH v4 00/13] Improve shrink_slab() scalability (old complexity was O(n^2), new is O(n)) Kirill Tkhai 2018-05-09 11:56 ` [PATCH v4 01/13] mm: Assign id to every memcg-aware shrinker Kirill Tkhai 2018-05-09 22:55 ` Andrew Morton 2018-05-10 2:47 ` Shakeel Butt 2018-05-10 9:42 ` Kirill Tkhai 2018-05-09 11:57 ` [PATCH v4 02/13] memcg: Move up for_each_mem_cgroup{, _tree} defines Kirill Tkhai 2018-05-09 11:57 ` [PATCH v4 03/13] mm: Assign memcg-aware shrinkers bitmap to memcg Kirill Tkhai 2018-05-09 11:57 ` [PATCH v4 04/13] mm: Refactoring in workingset_init() Kirill Tkhai 2018-05-09 11:57 ` [PATCH v4 05/13] fs: Refactoring in alloc_super() Kirill Tkhai 2018-05-09 11:57 ` [PATCH v4 06/13] fs: Propagate shrinker::id to list_lru Kirill Tkhai 2018-05-09 11:57 ` [PATCH v4 07/13] list_lru: Add memcg argument to list_lru_from_kmem() Kirill Tkhai 2018-05-09 11:58 ` [PATCH v4 08/13] list_lru: Pass dst_memcg argument to memcg_drain_list_lru_node() Kirill Tkhai 2018-05-09 11:58 ` [PATCH v4 09/13] list_lru: Pass lru " Kirill Tkhai 2018-05-09 11:58 ` [PATCH v4 10/13] mm: Set bit in memcg shrinker bitmap on first list_lru item apearance Kirill Tkhai 2018-05-09 11:58 ` Kirill Tkhai [this message] 2018-05-09 11:58 ` [PATCH v4 12/13] mm: Add SHRINK_EMPTY shrinker methods return value Kirill Tkhai 2018-05-09 11:58 ` [PATCH v4 13/13] mm: Clear shrinker bit if there are no objects related to memcg Kirill Tkhai
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=152586711800.3048.17462409401469930692.stgit@localhost.localdomain \ --to=ktkhai@virtuozzo.com \ --cc=akpm@linux-foundation.org \ --cc=aryabinin@virtuozzo.com \ --cc=chris@chris-wilson.co.uk \ --cc=gregkh@linuxfoundation.org \ --cc=guro@fb.com \ --cc=hannes@cmpxchg.org \ --cc=jbacik@fb.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=linux@roeck-us.net \ --cc=lirongqing@baidu.com \ --cc=longman@redhat.com \ --cc=mgorman@techsingularity.net \ --cc=mhocko@kernel.org \ --cc=minchan@kernel.org \ --cc=mka@chromium.org \ --cc=penguin-kernel@I-love.SAKURA.ne.jp \ --cc=pombredanne@nexb.com \ --cc=sfr@canb.auug.org.au \ --cc=shakeelb@google.com \ --cc=stummala@codeaurora.org \ --cc=tglx@linutronix.de \ --cc=vdavydov.dev@gmail.com \ --cc=viro@zeniv.linux.org.uk \ --cc=willy@infradead.org \ --cc=ying.huang@intel.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).