All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Davydov <vdavydov.dev@gmail.com>
To: Kirill Tkhai <ktkhai@virtuozzo.com>
Cc: viro@zeniv.linux.org.uk, hannes@cmpxchg.org, mhocko@kernel.org,
	akpm@linux-foundation.org, 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,
	hillf.zj@alibaba-inc.com, ying.huang@intel.com,
	mgorman@techsingularity.net, shakeelb@google.com, jbacik@fb.com,
	linux@roeck-us.net, linux-kernel@vger.kernel.org,
	linux-mm@kvack.org, willy@infradead.org
Subject: Re: [PATCH 10/10] mm: Clear shrinker bit if there are no objects related to memcg
Date: Sat, 24 Mar 2018 23:33:12 +0300	[thread overview]
Message-ID: <20180324203312.b2whjgadm7gwby3v@esperanza> (raw)
In-Reply-To: <152163858159.21546.2876185232270486710.stgit@localhost.localdomain>

On Wed, Mar 21, 2018 at 04:23:01PM +0300, Kirill Tkhai wrote:
> To avoid further unneed calls of do_shrink_slab()
> for shrinkers, which already do not have any charged
> objects in a memcg, their bits have to be cleared.
> 
> This patch introduces new return value SHRINK_EMPTY,
> which will be used in case of there is no charged
> objects in shrinker. We can't use 0 instead of that,
> as a shrinker may return 0, when it has very small
> amount of objects.
> 
> To prevent race with parallel list lru add, we call
> do_shrink_slab() once again, after the bit is cleared.
> So, if there is a new object, we never miss it, and
> the bit will be restored again.
> 
> The below test shows significant performance growths
> after using the patchset:
> 
> $echo 1 > /sys/fs/cgroup/memory/memory.use_hierarchy
> $mkdir /sys/fs/cgroup/memory/ct
> $echo 4000M > /sys/fs/cgroup/memory/ct/memory.kmem.limit_in_bytes
> $for i in `seq 0 4000`; do mkdir /sys/fs/cgroup/memory/ct/$i; echo $$ > /sys/fs/cgroup/memory/ct/$i/cgroup.procs; mkdir -p s/$i; mount -t tmpfs $i s/$i; touch s/$i/file; done
> 
> Then 4 drop_caches:
> $time echo 3 > /proc/sys/vm/drop_caches
> 
> Times of drop_caches:
> 
> *Before (4 iterations)*
> 0.00user 6.80system 0:06.82elapsed 99%CPU
> 0.00user 4.61system 0:04.62elapsed 99%CPU
> 0.00user 4.61system 0:04.61elapsed 99%CPU
> 0.00user 4.61system 0:04.61elapsed 99%CPU
> 
> *After (4 iterations)*
> 0.00user 0.93system 0:00.94elapsed 99%CPU
> 0.00user 0.00system 0:00.01elapsed 80%CPU
> 0.00user 0.00system 0:00.01elapsed 80%CPU
> 0.00user 0.00system 0:00.01elapsed 81%CPU
> 
> 4.61s/0.01s = 461 times faster.
> 
> Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
> ---
>  fs/super.c               |    3 +++
>  include/linux/shrinker.h |    1 +
>  mm/vmscan.c              |   21 ++++++++++++++++++---
>  mm/workingset.c          |    3 +++
>  4 files changed, 25 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
> index 24aeed1bc332..b23180deb928 100644
> --- a/include/linux/shrinker.h
> +++ b/include/linux/shrinker.h
> @@ -34,6 +34,7 @@ struct shrink_control {
>  };
>  
>  #define SHRINK_STOP (~0UL)
> +#define SHRINK_EMPTY (~0UL - 1)

Please update the comment below accordingly.

>  /*
>   * A callback you can register to apply pressure to ageable caches.
>   *
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index e1fd16bc7a9b..1fc05e8bde04 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -387,6 +387,7 @@ void set_shrinker_bit(struct mem_cgroup *memcg, int nid, int nr)
>  {
>  	struct shrinkers_map *map = SHRINKERS_MAP(memcg);
>  
> +	smp_mb__before_atomic(); /* Pairs with mb in shrink_slab() */

I don't understand the purpose of this barrier. Please add a comment
explaining why you need it.

>  	set_bit(nr, map->map[nid]);
>  }
>  #else /* CONFIG_MEMCG && !CONFIG_SLOB */
> @@ -568,8 +569,8 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
>  	long scanned = 0, next_deferred;
>  
>  	freeable = shrinker->count_objects(shrinker, shrinkctl);
> -	if (freeable == 0)
> -		return 0;
> +	if (freeable == 0 || freeable == SHRINK_EMPTY)
> +		return freeable;
>  
>  	/*
>  	 * copy the current shrinker scan count into a local variable
> @@ -708,6 +709,7 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
>  #if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
>  	if (!memcg_kmem_enabled() || memcg) {
>  		struct shrinkers_map *map;
> +		unsigned long ret;
>  		int i;
>  
>  		map = rcu_dereference_protected(SHRINKERS_MAP(memcg), true);
> @@ -724,7 +726,20 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
>  					clear_bit(i, map->map[nid]);
>  					continue;
>  				}
> -				freed += do_shrink_slab(&sc, shrinker, priority);
> +				if (!(shrinker->flags & SHRINKER_NUMA_AWARE))
> +					sc.nid = 0;

Hmm, if my memory doesn't fail, in the previous patch you added a BUG_ON
ensuring that a memcg-aware shrinker must also be numa-aware while here
you still check it. Please remove the BUG_ON or remove this check.
Better remove the BUG_ON, because a memcg-aware shrinker doesn't have to
be numa-aware.

> +				ret = do_shrink_slab(&sc, shrinker, priority);
> +				if (ret == SHRINK_EMPTY) {

do_shrink_slab() is also called for memcg-unaware shrinkers, you should
probably handle SHRINK_EMPTY there as well.

> +					clear_bit(i, map->map[nid]);
> +					/* pairs with mb in set_shrinker_bit() */
> +					smp_mb__after_atomic();
> +					ret = do_shrink_slab(&sc, shrinker, priority);
> +					if (ret == SHRINK_EMPTY)
> +						ret = 0;
> +					else
> +						set_bit(i, map->map[nid]);

Well, that's definitely a tricky part and hence needs a good comment.

Anyway, it would be great if we could simplify this part somehow.

> +				}
> +				freed += ret;
>  
>  				if (rwsem_is_contended(&shrinker_rwsem)) {
>  					freed = freed ? : 1;

  reply	other threads:[~2018-03-24 20:33 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-21 13:21 [PATCH 00/10] Improve shrink_slab() scalability (old complexity was O(n^2), new is O(n)) Kirill Tkhai
2018-03-21 13:21 ` [PATCH 01/10] mm: Assign id to every memcg-aware shrinker Kirill Tkhai
2018-03-24 18:40   ` Vladimir Davydov
2018-03-26 15:09     ` Kirill Tkhai
2018-03-26 15:14       ` Matthew Wilcox
2018-03-26 15:38         ` Kirill Tkhai
2018-03-27  9:15       ` Vladimir Davydov
2018-03-27 15:09         ` Kirill Tkhai
2018-03-27 15:48           ` Vladimir Davydov
2018-03-28 10:30             ` Kirill Tkhai
2018-03-28 11:02               ` Vladimir Davydov
2018-03-21 13:21 ` [PATCH 02/10] mm: Maintain memcg-aware shrinkers in mcg_shrinkers array Kirill Tkhai
2018-03-24 18:45   ` Vladimir Davydov
2018-03-26 15:20     ` Kirill Tkhai
2018-03-26 15:34       ` Matthew Wilcox
2018-03-27  9:18       ` Vladimir Davydov
2018-03-27 15:30         ` Kirill Tkhai
2018-03-21 13:21 ` [PATCH 03/10] mm: Assign memcg-aware shrinkers bitmap to memcg Kirill Tkhai
2018-03-21 14:56   ` Matthew Wilcox
2018-03-21 15:12     ` Kirill Tkhai
2018-03-21 15:26       ` Matthew Wilcox
2018-03-21 15:43         ` Kirill Tkhai
2018-03-21 16:20           ` Matthew Wilcox
2018-03-21 16:42             ` Kirill Tkhai
2018-03-21 17:54               ` Matthew Wilcox
2018-03-22 16:39                 ` Kirill Tkhai
2018-03-23  9:06   ` kbuild test robot
2018-03-23  9:06     ` kbuild test robot
2018-03-23 11:26     ` Kirill Tkhai
2018-03-24 19:25   ` Vladimir Davydov
2018-03-26 15:29     ` Kirill Tkhai
2018-03-27 10:00       ` Vladimir Davydov
2018-03-27 15:17         ` Kirill Tkhai
2018-03-21 13:21 ` [PATCH 04/10] fs: Propagate shrinker::id to list_lru Kirill Tkhai
2018-03-24 18:50   ` Vladimir Davydov
2018-03-26 15:29     ` Kirill Tkhai
2018-03-21 13:22 ` [PATCH 05/10] list_lru: Add memcg argument to list_lru_from_kmem() Kirill Tkhai
2018-04-02  3:17   ` [lkp-robot] [list_lru] 42658d54ce: BUG:unable_to_handle_kernel kernel test robot
2018-04-02  3:17     ` kernel test robot
2018-04-02  3:17     ` kernel test robot
2018-04-02  8:51     ` Kirill Tkhai
2018-04-02  8:51       ` Kirill Tkhai
2018-03-21 13:22 ` [PATCH 06/10] list_lru: Pass dst_memcg argument to memcg_drain_list_lru_node() Kirill Tkhai
2018-03-24 19:32   ` Vladimir Davydov
2018-03-26 15:30     ` Kirill Tkhai
2018-03-28 14:49       ` Kirill Tkhai
2018-03-21 13:22 ` [PATCH 07/10] list_lru: Pass lru " Kirill Tkhai
2018-03-21 13:22 ` [PATCH 08/10] mm: Set bit in memcg shrinker bitmap on first list_lru item apearance Kirill Tkhai
2018-03-24 19:45   ` Vladimir Davydov
2018-03-26 15:31     ` Kirill Tkhai
2018-03-21 13:22 ` [PATCH 09/10] mm: Iterate only over charged shrinkers during memcg shrink_slab() Kirill Tkhai
2018-03-24 20:11   ` Vladimir Davydov
2018-03-26 15:33     ` Kirill Tkhai
2018-03-21 13:23 ` [PATCH 10/10] mm: Clear shrinker bit if there are no objects related to memcg Kirill Tkhai
2018-03-24 20:33   ` Vladimir Davydov [this message]
2018-03-26 15:37     ` Kirill Tkhai
2018-03-21 13:23 ` [PATCH 00/10] Improve shrink_slab() scalability (old complexity was O(n^2), new is O(n)) 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=20180324203312.b2whjgadm7gwby3v@esperanza \
    --to=vdavydov.dev@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=chris@chris-wilson.co.uk \
    --cc=gregkh@linuxfoundation.org \
    --cc=guro@fb.com \
    --cc=hannes@cmpxchg.org \
    --cc=hillf.zj@alibaba-inc.com \
    --cc=jbacik@fb.com \
    --cc=ktkhai@virtuozzo.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux@roeck-us.net \
    --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=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: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.