All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wei Yang <richard.weiyang@gmail.com>
Cc: cl@linux.com, penberg@kernel.org, rientjes@google.com,
	iamjoonsoo.kim@lge.com, akpm@linux-foundation.org,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Wei Yang <richard.weiyang@gmail.com>
Subject: Re: [PATCH 3/3] mm/slub: wrap kmem_cache->cpu_partial in config CONFIG_SLUB_CPU_PARTIAL
Date: Mon, 1 May 2017 23:37:52 +0800	[thread overview]
Message-ID: <20170501153752.GA1653@WeideMacBook-Pro.local> (raw)
In-Reply-To: <20170430113152.6590-4-richard.weiyang@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5871 bytes --]

On Sun, Apr 30, 2017 at 07:31:52PM +0800, Wei Yang wrote:
>kmem_cache->cpu_partial is just used when CONFIG_SLUB_CPU_PARTIAL is set,
>so wrap it with config CONFIG_SLUB_CPU_PARTIAL will save some space
>on 32bit arch.
>
>This patch wrap kmem_cache->cpu_partial in config CONFIG_SLUB_CPU_PARTIAL
>and wrap its sysfs too.
>
>Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
>---
> include/linux/slub_def.h |  2 ++
> mm/slub.c                | 72 +++++++++++++++++++++++++++++-------------------
> 2 files changed, 46 insertions(+), 28 deletions(-)
>
>diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
>index 0debd8df1a7d..477ab99800ed 100644
>--- a/include/linux/slub_def.h
>+++ b/include/linux/slub_def.h
>@@ -69,7 +69,9 @@ struct kmem_cache {
> 	int size;		/* The size of an object including meta data */
> 	int object_size;	/* The size of an object without meta data */
> 	int offset;		/* Free pointer offset. */
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
> 	int cpu_partial;	/* Number of per cpu partial objects to keep around */
>+#endif
> 	struct kmem_cache_order_objects oo;
> 
> 	/* Allocation and freeing of slabs */
>diff --git a/mm/slub.c b/mm/slub.c
>index fde499b6dad8..94978f27882a 100644
>--- a/mm/slub.c
>+++ b/mm/slub.c
>@@ -1829,7 +1829,10 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n,
> 			stat(s, CPU_PARTIAL_NODE);
> 		}
> 		if (!kmem_cache_has_cpu_partial(s)
>-			|| available > s->cpu_partial / 2)
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
>+			|| available > s->cpu_partial / 2
>+#endif
>+			)
> 			break;

Matthew,

I plan to change this one with the same idea you mentioned in previous reply.

While one special "technique" is how to name it.

How about name this one

    slub_cpu_partial()

And rename the previous one

   slub_percpu_partial()

This is really hard to say which one is better :-(
Not sure whether you have some insight in this.

> 
> 	}
>@@ -3418,6 +3421,39 @@ static void set_min_partial(struct kmem_cache *s, unsigned long min)
> 	s->min_partial = min;
> }
> 
>+static void set_cpu_partial(struct kmem_cache *s)
>+{
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
>+	/*
>+	 * cpu_partial determined the maximum number of objects kept in the
>+	 * per cpu partial lists of a processor.
>+	 *
>+	 * Per cpu partial lists mainly contain slabs that just have one
>+	 * object freed. If they are used for allocation then they can be
>+	 * filled up again with minimal effort. The slab will never hit the
>+	 * per node partial lists and therefore no locking will be required.
>+	 *
>+	 * This setting also determines
>+	 *
>+	 * A) The number of objects from per cpu partial slabs dumped to the
>+	 *    per node list when we reach the limit.
>+	 * B) The number of objects in cpu partial slabs to extract from the
>+	 *    per node list when we run out of per cpu objects. We only fetch
>+	 *    50% to keep some capacity around for frees.
>+	 */
>+	if (!kmem_cache_has_cpu_partial(s))
>+		s->cpu_partial = 0;
>+	else if (s->size >= PAGE_SIZE)
>+		s->cpu_partial = 2;
>+	else if (s->size >= 1024)
>+		s->cpu_partial = 6;
>+	else if (s->size >= 256)
>+		s->cpu_partial = 13;
>+	else
>+		s->cpu_partial = 30;
>+#endif
>+}
>+
> /*
>  * calculate_sizes() determines the order and the distribution of data within
>  * a slab object.
>@@ -3576,33 +3612,7 @@ static int kmem_cache_open(struct kmem_cache *s, unsigned long flags)
> 	 */
> 	set_min_partial(s, ilog2(s->size) / 2);
> 
>-	/*
>-	 * cpu_partial determined the maximum number of objects kept in the
>-	 * per cpu partial lists of a processor.
>-	 *
>-	 * Per cpu partial lists mainly contain slabs that just have one
>-	 * object freed. If they are used for allocation then they can be
>-	 * filled up again with minimal effort. The slab will never hit the
>-	 * per node partial lists and therefore no locking will be required.
>-	 *
>-	 * This setting also determines
>-	 *
>-	 * A) The number of objects from per cpu partial slabs dumped to the
>-	 *    per node list when we reach the limit.
>-	 * B) The number of objects in cpu partial slabs to extract from the
>-	 *    per node list when we run out of per cpu objects. We only fetch
>-	 *    50% to keep some capacity around for frees.
>-	 */
>-	if (!kmem_cache_has_cpu_partial(s))
>-		s->cpu_partial = 0;
>-	else if (s->size >= PAGE_SIZE)
>-		s->cpu_partial = 2;
>-	else if (s->size >= 1024)
>-		s->cpu_partial = 6;
>-	else if (s->size >= 256)
>-		s->cpu_partial = 13;
>-	else
>-		s->cpu_partial = 30;
>+	set_cpu_partial(s);
> 
> #ifdef CONFIG_NUMA
> 	s->remote_node_defrag_ratio = 1000;
>@@ -3989,7 +3999,9 @@ void __kmemcg_cache_deactivate(struct kmem_cache *s)
> 	 * Disable empty slabs caching. Used to avoid pinning offline
> 	 * memory cgroups by kmem pages that can be freed.
> 	 */
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
> 	s->cpu_partial = 0;
>+#endif
> 	s->min_partial = 0;
> 
> 	/*
>@@ -4929,6 +4941,7 @@ static ssize_t min_partial_store(struct kmem_cache *s, const char *buf,
> }
> SLAB_ATTR(min_partial);
> 
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
> static ssize_t cpu_partial_show(struct kmem_cache *s, char *buf)
> {
> 	return sprintf(buf, "%u\n", s->cpu_partial);
>@@ -4951,6 +4964,7 @@ static ssize_t cpu_partial_store(struct kmem_cache *s, const char *buf,
> 	return length;
> }
> SLAB_ATTR(cpu_partial);
>+#endif
> 
> static ssize_t ctor_show(struct kmem_cache *s, char *buf)
> {
>@@ -5363,7 +5377,9 @@ static struct attribute *slab_attrs[] = {
> 	&objs_per_slab_attr.attr,
> 	&order_attr.attr,
> 	&min_partial_attr.attr,
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
> 	&cpu_partial_attr.attr,
>+#endif
> 	&objects_attr.attr,
> 	&objects_partial_attr.attr,
> 	&partial_attr.attr,
>-- 
>2.11.0

-- 
Wei Yang
Help you, Help me

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: Wei Yang <richard.weiyang@gmail.com>
To: unlisted-recipients:; (no To-header on input)
Cc: cl@linux.com, penberg@kernel.org, rientjes@google.com,
	iamjoonsoo.kim@lge.com, akpm@linux-foundation.org,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Wei Yang <richard.weiyang@gmail.com>
Subject: Re: [PATCH 3/3] mm/slub: wrap kmem_cache->cpu_partial in config CONFIG_SLUB_CPU_PARTIAL
Date: Mon, 1 May 2017 23:37:52 +0800	[thread overview]
Message-ID: <20170501153752.GA1653@WeideMacBook-Pro.local> (raw)
In-Reply-To: <20170430113152.6590-4-richard.weiyang@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5871 bytes --]

On Sun, Apr 30, 2017 at 07:31:52PM +0800, Wei Yang wrote:
>kmem_cache->cpu_partial is just used when CONFIG_SLUB_CPU_PARTIAL is set,
>so wrap it with config CONFIG_SLUB_CPU_PARTIAL will save some space
>on 32bit arch.
>
>This patch wrap kmem_cache->cpu_partial in config CONFIG_SLUB_CPU_PARTIAL
>and wrap its sysfs too.
>
>Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
>---
> include/linux/slub_def.h |  2 ++
> mm/slub.c                | 72 +++++++++++++++++++++++++++++-------------------
> 2 files changed, 46 insertions(+), 28 deletions(-)
>
>diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
>index 0debd8df1a7d..477ab99800ed 100644
>--- a/include/linux/slub_def.h
>+++ b/include/linux/slub_def.h
>@@ -69,7 +69,9 @@ struct kmem_cache {
> 	int size;		/* The size of an object including meta data */
> 	int object_size;	/* The size of an object without meta data */
> 	int offset;		/* Free pointer offset. */
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
> 	int cpu_partial;	/* Number of per cpu partial objects to keep around */
>+#endif
> 	struct kmem_cache_order_objects oo;
> 
> 	/* Allocation and freeing of slabs */
>diff --git a/mm/slub.c b/mm/slub.c
>index fde499b6dad8..94978f27882a 100644
>--- a/mm/slub.c
>+++ b/mm/slub.c
>@@ -1829,7 +1829,10 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n,
> 			stat(s, CPU_PARTIAL_NODE);
> 		}
> 		if (!kmem_cache_has_cpu_partial(s)
>-			|| available > s->cpu_partial / 2)
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
>+			|| available > s->cpu_partial / 2
>+#endif
>+			)
> 			break;

Matthew,

I plan to change this one with the same idea you mentioned in previous reply.

While one special "technique" is how to name it.

How about name this one

    slub_cpu_partial()

And rename the previous one

   slub_percpu_partial()

This is really hard to say which one is better :-(
Not sure whether you have some insight in this.

> 
> 	}
>@@ -3418,6 +3421,39 @@ static void set_min_partial(struct kmem_cache *s, unsigned long min)
> 	s->min_partial = min;
> }
> 
>+static void set_cpu_partial(struct kmem_cache *s)
>+{
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
>+	/*
>+	 * cpu_partial determined the maximum number of objects kept in the
>+	 * per cpu partial lists of a processor.
>+	 *
>+	 * Per cpu partial lists mainly contain slabs that just have one
>+	 * object freed. If they are used for allocation then they can be
>+	 * filled up again with minimal effort. The slab will never hit the
>+	 * per node partial lists and therefore no locking will be required.
>+	 *
>+	 * This setting also determines
>+	 *
>+	 * A) The number of objects from per cpu partial slabs dumped to the
>+	 *    per node list when we reach the limit.
>+	 * B) The number of objects in cpu partial slabs to extract from the
>+	 *    per node list when we run out of per cpu objects. We only fetch
>+	 *    50% to keep some capacity around for frees.
>+	 */
>+	if (!kmem_cache_has_cpu_partial(s))
>+		s->cpu_partial = 0;
>+	else if (s->size >= PAGE_SIZE)
>+		s->cpu_partial = 2;
>+	else if (s->size >= 1024)
>+		s->cpu_partial = 6;
>+	else if (s->size >= 256)
>+		s->cpu_partial = 13;
>+	else
>+		s->cpu_partial = 30;
>+#endif
>+}
>+
> /*
>  * calculate_sizes() determines the order and the distribution of data within
>  * a slab object.
>@@ -3576,33 +3612,7 @@ static int kmem_cache_open(struct kmem_cache *s, unsigned long flags)
> 	 */
> 	set_min_partial(s, ilog2(s->size) / 2);
> 
>-	/*
>-	 * cpu_partial determined the maximum number of objects kept in the
>-	 * per cpu partial lists of a processor.
>-	 *
>-	 * Per cpu partial lists mainly contain slabs that just have one
>-	 * object freed. If they are used for allocation then they can be
>-	 * filled up again with minimal effort. The slab will never hit the
>-	 * per node partial lists and therefore no locking will be required.
>-	 *
>-	 * This setting also determines
>-	 *
>-	 * A) The number of objects from per cpu partial slabs dumped to the
>-	 *    per node list when we reach the limit.
>-	 * B) The number of objects in cpu partial slabs to extract from the
>-	 *    per node list when we run out of per cpu objects. We only fetch
>-	 *    50% to keep some capacity around for frees.
>-	 */
>-	if (!kmem_cache_has_cpu_partial(s))
>-		s->cpu_partial = 0;
>-	else if (s->size >= PAGE_SIZE)
>-		s->cpu_partial = 2;
>-	else if (s->size >= 1024)
>-		s->cpu_partial = 6;
>-	else if (s->size >= 256)
>-		s->cpu_partial = 13;
>-	else
>-		s->cpu_partial = 30;
>+	set_cpu_partial(s);
> 
> #ifdef CONFIG_NUMA
> 	s->remote_node_defrag_ratio = 1000;
>@@ -3989,7 +3999,9 @@ void __kmemcg_cache_deactivate(struct kmem_cache *s)
> 	 * Disable empty slabs caching. Used to avoid pinning offline
> 	 * memory cgroups by kmem pages that can be freed.
> 	 */
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
> 	s->cpu_partial = 0;
>+#endif
> 	s->min_partial = 0;
> 
> 	/*
>@@ -4929,6 +4941,7 @@ static ssize_t min_partial_store(struct kmem_cache *s, const char *buf,
> }
> SLAB_ATTR(min_partial);
> 
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
> static ssize_t cpu_partial_show(struct kmem_cache *s, char *buf)
> {
> 	return sprintf(buf, "%u\n", s->cpu_partial);
>@@ -4951,6 +4964,7 @@ static ssize_t cpu_partial_store(struct kmem_cache *s, const char *buf,
> 	return length;
> }
> SLAB_ATTR(cpu_partial);
>+#endif
> 
> static ssize_t ctor_show(struct kmem_cache *s, char *buf)
> {
>@@ -5363,7 +5377,9 @@ static struct attribute *slab_attrs[] = {
> 	&objs_per_slab_attr.attr,
> 	&order_attr.attr,
> 	&min_partial_attr.attr,
>+#ifdef CONFIG_SLUB_CPU_PARTIAL
> 	&cpu_partial_attr.attr,
>+#endif
> 	&objects_attr.attr,
> 	&objects_partial_attr.attr,
> 	&partial_attr.attr,
>-- 
>2.11.0

-- 
Wei Yang
Help you, Help me

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

  reply	other threads:[~2017-05-01 15:37 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-30 11:31 [PATCH 0/3] try to save some memory for kmem_cache in some cases Wei Yang
2017-04-30 11:31 ` Wei Yang
2017-04-30 11:31 ` [PATCH 1/3] mm/slub: pack red_left_pad with another int to save a word Wei Yang
2017-04-30 11:31   ` Wei Yang
2017-04-30 11:31 ` [PATCH 2/3] mm/slub: wrap cpu_slab->partial in CONFIG_SLUB_CPU_PARTIAL Wei Yang
2017-04-30 11:31   ` Wei Yang
2017-05-01  2:41   ` Matthew Wilcox
2017-05-01  2:41     ` Matthew Wilcox
2017-05-01  7:39     ` Wei Yang
2017-05-01  8:20     ` Wei Yang
2017-05-01 14:39       ` Matthew Wilcox
2017-05-01 14:39         ` Matthew Wilcox
2017-05-01 15:15         ` Wei Yang
2017-04-30 11:31 ` [PATCH 3/3] mm/slub: wrap kmem_cache->cpu_partial in config CONFIG_SLUB_CPU_PARTIAL Wei Yang
2017-04-30 11:31   ` Wei Yang
2017-05-01 15:37   ` Wei Yang [this message]
2017-05-01 15:37     ` Wei Yang
2017-04-30 21:22 ` [PATCH 0/3] try to save some memory for kmem_cache in some cases Christoph Lameter
2017-04-30 21:22   ` Christoph Lameter

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=20170501153752.GA1653@WeideMacBook-Pro.local \
    --to=richard.weiyang@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=cl@linux.com \
    --cc=iamjoonsoo.kim@lge.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=penberg@kernel.org \
    --cc=rientjes@google.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.