Re: [PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-26 Thread Christoph Lameter
On Tue, 26 Aug 2014, Joonsoo Kim wrote:

> On Mon, Aug 25, 2014 at 10:27:58AM -0500, Christoph Lameter wrote:
> > Uhh.. You would have to specify "slub_nomerge" to get slab to not merge
> > slab caches?
>
> Should fix it. How about following change?
>
> #ifdef CONFIG_SLUB
> __setup("slub_nomerge", setup_slab_nomerge);
> #endif
>
> __setup("slab_nomerge", setup_slab_nomerge);
>
> This makes "slab_nomerge" works for all SL[aou]B.

Ok. At some point we need to make slub_nomerge legacy then.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-26 Thread Christoph Lameter
On Tue, 26 Aug 2014, Joonsoo Kim wrote:

 On Mon, Aug 25, 2014 at 10:27:58AM -0500, Christoph Lameter wrote:
  Uhh.. You would have to specify slub_nomerge to get slab to not merge
  slab caches?

 Should fix it. How about following change?

 #ifdef CONFIG_SLUB
 __setup(slub_nomerge, setup_slab_nomerge);
 #endif

 __setup(slab_nomerge, setup_slab_nomerge);

 This makes slab_nomerge works for all SL[aou]B.

Ok. At some point we need to make slub_nomerge legacy then.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-25 Thread Joonsoo Kim
On Mon, Aug 25, 2014 at 10:27:58AM -0500, Christoph Lameter wrote:
> On Thu, 21 Aug 2014, Joonsoo Kim wrote:
> 
> > +static int __init setup_slab_nomerge(char *str)
> > +{
> > +   slab_nomerge = 1;
> > +   return 1;
> > +}
> > +__setup("slub_nomerge", setup_slab_nomerge);
> 
> Uhh.. You would have to specify "slub_nomerge" to get slab to not merge
> slab caches?

Should fix it. How about following change?

#ifdef CONFIG_SLUB
__setup("slub_nomerge", setup_slab_nomerge);
#endif

__setup("slab_nomerge", setup_slab_nomerge);

This makes "slab_nomerge" works for all SL[aou]B.

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-25 Thread Christoph Lameter
On Thu, 21 Aug 2014, Joonsoo Kim wrote:

> +static int __init setup_slab_nomerge(char *str)
> +{
> + slab_nomerge = 1;
> + return 1;
> +}
> +__setup("slub_nomerge", setup_slab_nomerge);

Uhh.. You would have to specify "slub_nomerge" to get slab to not merge
slab caches?

Otherwise this is a straightforward move into the common area.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-25 Thread Joonsoo Kim
On Thu, Aug 21, 2014 at 09:22:35AM -0500, Christoph Lameter wrote:
> On Thu, 21 Aug 2014, Joonsoo Kim wrote:
> 
> > Slab merge is good feature to reduce fragmentation. Now, it is only
> > applied to SLUB, but, it would be good to apply it to SLAB. This patch
> > is preparation step to apply slab merge to SLAB by commonizing slab
> > merge logic.
> 
> Oh. Wow. Never thought that would be possible. Need to have some more time
> to review this though.

Yes, please review it. :)

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-25 Thread Joonsoo Kim
On Thu, Aug 21, 2014 at 09:22:35AM -0500, Christoph Lameter wrote:
 On Thu, 21 Aug 2014, Joonsoo Kim wrote:
 
  Slab merge is good feature to reduce fragmentation. Now, it is only
  applied to SLUB, but, it would be good to apply it to SLAB. This patch
  is preparation step to apply slab merge to SLAB by commonizing slab
  merge logic.
 
 Oh. Wow. Never thought that would be possible. Need to have some more time
 to review this though.

Yes, please review it. :)

Thanks.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-25 Thread Christoph Lameter
On Thu, 21 Aug 2014, Joonsoo Kim wrote:

 +static int __init setup_slab_nomerge(char *str)
 +{
 + slab_nomerge = 1;
 + return 1;
 +}
 +__setup(slub_nomerge, setup_slab_nomerge);

Uhh.. You would have to specify slub_nomerge to get slab to not merge
slab caches?

Otherwise this is a straightforward move into the common area.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-25 Thread Joonsoo Kim
On Mon, Aug 25, 2014 at 10:27:58AM -0500, Christoph Lameter wrote:
 On Thu, 21 Aug 2014, Joonsoo Kim wrote:
 
  +static int __init setup_slab_nomerge(char *str)
  +{
  +   slab_nomerge = 1;
  +   return 1;
  +}
  +__setup(slub_nomerge, setup_slab_nomerge);
 
 Uhh.. You would have to specify slub_nomerge to get slab to not merge
 slab caches?

Should fix it. How about following change?

#ifdef CONFIG_SLUB
__setup(slub_nomerge, setup_slab_nomerge);
#endif

__setup(slab_nomerge, setup_slab_nomerge);

This makes slab_nomerge works for all SL[aou]B.

Thanks.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-21 Thread Christoph Lameter
On Thu, 21 Aug 2014, Joonsoo Kim wrote:

> Slab merge is good feature to reduce fragmentation. Now, it is only
> applied to SLUB, but, it would be good to apply it to SLAB. This patch
> is preparation step to apply slab merge to SLAB by commonizing slab
> merge logic.

Oh. Wow. Never thought that would be possible. Need to have some more time
to review this though.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-21 Thread Joonsoo Kim
Slab merge is good feature to reduce fragmentation. Now, it is only
applied to SLUB, but, it would be good to apply it to SLAB. This patch
is preparation step to apply slab merge to SLAB by commonizing slab
merge logic.

Signed-off-by: Joonsoo Kim 
---
 mm/slab.h|   15 +
 mm/slab_common.c |   86 +++
 mm/slub.c|   91 ++
 3 files changed, 103 insertions(+), 89 deletions(-)

diff --git a/mm/slab.h b/mm/slab.h
index 5cb4649..7c6e1ed 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -85,15 +85,30 @@ extern void create_boot_cache(struct kmem_cache *, const 
char *name,
size_t size, unsigned long flags);
 
 struct mem_cgroup;
+
+int slab_unmergeable(struct kmem_cache *s);
+struct kmem_cache *find_mergeable(size_t size, size_t align,
+   unsigned long flags, const char *name, void (*ctor)(void *));
 #ifdef CONFIG_SLUB
 struct kmem_cache *
 __kmem_cache_alias(const char *name, size_t size, size_t align,
   unsigned long flags, void (*ctor)(void *));
+
+unsigned long kmem_cache_flags(unsigned long object_size,
+   unsigned long flags, const char *name,
+   void (*ctor)(void *));
 #else
 static inline struct kmem_cache *
 __kmem_cache_alias(const char *name, size_t size, size_t align,
   unsigned long flags, void (*ctor)(void *))
 { return NULL; }
+
+static inline unsigned long kmem_cache_flags(unsigned long object_size,
+   unsigned long flags, const char *name,
+   void (*ctor)(void *))
+{
+   return flags;
+}
 #endif
 
 
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 2088904..65a5811 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -31,6 +31,29 @@ DEFINE_MUTEX(slab_mutex);
 struct kmem_cache *kmem_cache;
 
 /*
+ * Set of flags that will prevent slab merging
+ */
+#define SLAB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
+   SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE | \
+   SLAB_FAILSLAB)
+
+#define SLAB_MERGE_SAME (SLAB_DEBUG_FREE | SLAB_RECLAIM_ACCOUNT | \
+   SLAB_CACHE_DMA | SLAB_NOTRACK)
+
+/*
+ * Merge control. If this is set then no merging of slab caches will occur.
+ * (Could be removed. This was introduced to pacify the merge skeptics.)
+ */
+static int slab_nomerge;
+
+static int __init setup_slab_nomerge(char *str)
+{
+   slab_nomerge = 1;
+   return 1;
+}
+__setup("slub_nomerge", setup_slab_nomerge);
+
+/*
  * Determine the size of a slab object
  */
 unsigned int kmem_cache_size(struct kmem_cache *s)
@@ -115,6 +138,69 @@ out:
 #endif
 
 /*
+ * Find a mergeable slab cache
+ */
+int slab_unmergeable(struct kmem_cache *s)
+{
+   if (slab_nomerge || (s->flags & SLAB_NEVER_MERGE))
+   return 1;
+
+   if (!is_root_cache(s))
+   return 1;
+
+   if (s->ctor)
+   return 1;
+
+   /*
+* We may have set a slab to be unmergeable during bootstrap.
+*/
+   if (s->refcount < 0)
+   return 1;
+
+   return 0;
+}
+
+struct kmem_cache *find_mergeable(size_t size, size_t align,
+   unsigned long flags, const char *name, void (*ctor)(void *))
+{
+   struct kmem_cache *s;
+
+   if (slab_nomerge || (flags & SLAB_NEVER_MERGE))
+   return NULL;
+
+   if (ctor)
+   return NULL;
+
+   size = ALIGN(size, sizeof(void *));
+   align = calculate_alignment(flags, align, size);
+   size = ALIGN(size, align);
+   flags = kmem_cache_flags(size, flags, name, NULL);
+
+   list_for_each_entry(s, _caches, list) {
+   if (slab_unmergeable(s))
+   continue;
+
+   if (size > s->size)
+   continue;
+
+   if ((flags & SLAB_MERGE_SAME) != (s->flags & SLAB_MERGE_SAME))
+   continue;
+   /*
+* Check if alignment is compatible.
+* Courtesy of Adrian Drzewiecki
+*/
+   if ((s->size & ~(align - 1)) != s->size)
+   continue;
+
+   if (s->size - size >= sizeof(void *))
+   continue;
+
+   return s;
+   }
+   return NULL;
+}
+
+/*
  * Figure out what the alignment of the objects will be given a set of
  * flags, a user specified alignment and the size of the objects.
  */
diff --git a/mm/slub.c b/mm/slub.c
index 3e8afcc..b29e835 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -169,16 +169,6 @@ static inline bool kmem_cache_has_cpu_partial(struct 
kmem_cache *s)
  */
 #define DEBUG_METADATA_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER)
 
-/*
- * Set of flags that will prevent slab merging
- */
-#define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
-   SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE | \
-   SLAB_FAILSLAB)
-

[PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-21 Thread Joonsoo Kim
Slab merge is good feature to reduce fragmentation. Now, it is only
applied to SLUB, but, it would be good to apply it to SLAB. This patch
is preparation step to apply slab merge to SLAB by commonizing slab
merge logic.

Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com
---
 mm/slab.h|   15 +
 mm/slab_common.c |   86 +++
 mm/slub.c|   91 ++
 3 files changed, 103 insertions(+), 89 deletions(-)

diff --git a/mm/slab.h b/mm/slab.h
index 5cb4649..7c6e1ed 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -85,15 +85,30 @@ extern void create_boot_cache(struct kmem_cache *, const 
char *name,
size_t size, unsigned long flags);
 
 struct mem_cgroup;
+
+int slab_unmergeable(struct kmem_cache *s);
+struct kmem_cache *find_mergeable(size_t size, size_t align,
+   unsigned long flags, const char *name, void (*ctor)(void *));
 #ifdef CONFIG_SLUB
 struct kmem_cache *
 __kmem_cache_alias(const char *name, size_t size, size_t align,
   unsigned long flags, void (*ctor)(void *));
+
+unsigned long kmem_cache_flags(unsigned long object_size,
+   unsigned long flags, const char *name,
+   void (*ctor)(void *));
 #else
 static inline struct kmem_cache *
 __kmem_cache_alias(const char *name, size_t size, size_t align,
   unsigned long flags, void (*ctor)(void *))
 { return NULL; }
+
+static inline unsigned long kmem_cache_flags(unsigned long object_size,
+   unsigned long flags, const char *name,
+   void (*ctor)(void *))
+{
+   return flags;
+}
 #endif
 
 
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 2088904..65a5811 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -31,6 +31,29 @@ DEFINE_MUTEX(slab_mutex);
 struct kmem_cache *kmem_cache;
 
 /*
+ * Set of flags that will prevent slab merging
+ */
+#define SLAB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
+   SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE | \
+   SLAB_FAILSLAB)
+
+#define SLAB_MERGE_SAME (SLAB_DEBUG_FREE | SLAB_RECLAIM_ACCOUNT | \
+   SLAB_CACHE_DMA | SLAB_NOTRACK)
+
+/*
+ * Merge control. If this is set then no merging of slab caches will occur.
+ * (Could be removed. This was introduced to pacify the merge skeptics.)
+ */
+static int slab_nomerge;
+
+static int __init setup_slab_nomerge(char *str)
+{
+   slab_nomerge = 1;
+   return 1;
+}
+__setup(slub_nomerge, setup_slab_nomerge);
+
+/*
  * Determine the size of a slab object
  */
 unsigned int kmem_cache_size(struct kmem_cache *s)
@@ -115,6 +138,69 @@ out:
 #endif
 
 /*
+ * Find a mergeable slab cache
+ */
+int slab_unmergeable(struct kmem_cache *s)
+{
+   if (slab_nomerge || (s-flags  SLAB_NEVER_MERGE))
+   return 1;
+
+   if (!is_root_cache(s))
+   return 1;
+
+   if (s-ctor)
+   return 1;
+
+   /*
+* We may have set a slab to be unmergeable during bootstrap.
+*/
+   if (s-refcount  0)
+   return 1;
+
+   return 0;
+}
+
+struct kmem_cache *find_mergeable(size_t size, size_t align,
+   unsigned long flags, const char *name, void (*ctor)(void *))
+{
+   struct kmem_cache *s;
+
+   if (slab_nomerge || (flags  SLAB_NEVER_MERGE))
+   return NULL;
+
+   if (ctor)
+   return NULL;
+
+   size = ALIGN(size, sizeof(void *));
+   align = calculate_alignment(flags, align, size);
+   size = ALIGN(size, align);
+   flags = kmem_cache_flags(size, flags, name, NULL);
+
+   list_for_each_entry(s, slab_caches, list) {
+   if (slab_unmergeable(s))
+   continue;
+
+   if (size  s-size)
+   continue;
+
+   if ((flags  SLAB_MERGE_SAME) != (s-flags  SLAB_MERGE_SAME))
+   continue;
+   /*
+* Check if alignment is compatible.
+* Courtesy of Adrian Drzewiecki
+*/
+   if ((s-size  ~(align - 1)) != s-size)
+   continue;
+
+   if (s-size - size = sizeof(void *))
+   continue;
+
+   return s;
+   }
+   return NULL;
+}
+
+/*
  * Figure out what the alignment of the objects will be given a set of
  * flags, a user specified alignment and the size of the objects.
  */
diff --git a/mm/slub.c b/mm/slub.c
index 3e8afcc..b29e835 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -169,16 +169,6 @@ static inline bool kmem_cache_has_cpu_partial(struct 
kmem_cache *s)
  */
 #define DEBUG_METADATA_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER)
 
-/*
- * Set of flags that will prevent slab merging
- */
-#define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
-   SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE | \
-   SLAB_FAILSLAB)

Re: [PATCH 2/3] mm/slab_common: commonize slab merge logic

2014-08-21 Thread Christoph Lameter
On Thu, 21 Aug 2014, Joonsoo Kim wrote:

 Slab merge is good feature to reduce fragmentation. Now, it is only
 applied to SLUB, but, it would be good to apply it to SLAB. This patch
 is preparation step to apply slab merge to SLAB by commonizing slab
 merge logic.

Oh. Wow. Never thought that would be possible. Need to have some more time
to review this though.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/