From: Christoph Lameter <cl@linux.com>
To: akpm@linuxfoundation.org
Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org,
penberg@kernel.org, iamjoonsoo@lge.com,
Jesper Dangaard Brouer <brouer@redhat.com>
Subject: [PATCH 1/3] Slab infrastructure for array operations
Date: Tue, 10 Feb 2015 13:48:05 -0600 [thread overview]
Message-ID: <20150210194811.787556326@linux.com> (raw)
In-Reply-To: <20150210194804.288708936@linux.com>
[-- Attachment #1: array_alloc --]
[-- Type: text/plain, Size: 5423 bytes --]
This patch adds the basic infrastructure for alloc / free operations
on pointer arrays. It includes a fallback function that can perform
the array operations using the single alloc and free that every
slab allocator performs.
Allocators must define _HAVE_SLAB_ALLOCATOR_OPERATIONS in their
header files in order to implement their own fast version for
these array operations.
Array operations allow a reduction of the processing overhead
during allocation and therefore speed up acquisition of larger
amounts of objects.
Signed-off-by: Christoph Lameter <cl@linux.com>
Index: linux/include/linux/slab.h
===================================================================
--- linux.orig/include/linux/slab.h
+++ linux/include/linux/slab.h
@@ -123,6 +123,7 @@ struct kmem_cache *memcg_create_kmem_cac
void kmem_cache_destroy(struct kmem_cache *);
int kmem_cache_shrink(struct kmem_cache *);
void kmem_cache_free(struct kmem_cache *, void *);
+void kmem_cache_free_array(struct kmem_cache *, size_t, void **);
/*
* Please use this macro to create slab caches. Simply specify the
@@ -289,6 +290,8 @@ static __always_inline int kmalloc_index
void *__kmalloc(size_t size, gfp_t flags);
void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags);
+int kmem_cache_alloc_array(struct kmem_cache *, gfp_t gfpflags,
+ size_t nr, void **);
#ifdef CONFIG_NUMA
void *__kmalloc_node(size_t size, gfp_t flags, int node);
Index: linux/mm/slab_common.c
===================================================================
--- linux.orig/mm/slab_common.c
+++ linux/mm/slab_common.c
@@ -105,6 +105,83 @@ static inline int kmem_cache_sanity_chec
}
#endif
+/*
+ * Fallback function that just calls kmem_cache_alloc
+ * for each element. This may be used if not all
+ * objects can be allocated or as a generic fallback
+ * if the allocator cannot support buik operations.
+ */
+int __kmem_cache_alloc_array(struct kmem_cache *s,
+ gfp_t flags, size_t nr, void **p)
+{
+ int i;
+
+ for (i = 0; i < nr; i++) {
+ void *x = kmem_cache_alloc(s, flags);
+
+ if (!x)
+ return i;
+ p[i] = x;
+ }
+ return i;
+}
+
+int kmem_cache_alloc_array(struct kmem_cache *s,
+ gfp_t flags, size_t nr, void **p)
+{
+ int i = 0;
+
+#ifdef _HAVE_SLAB_ALLOCATOR_ARRAY_OPERATIONS
+ /*
+ * First extract objects from partial lists in order to
+ * avoid further fragmentation.
+ */
+ i += slab_array_alloc_from_partial(s, nr - i, p + i);
+
+ /*
+ * If there are still a larger number of objects to be allocated
+ * use the page allocator directly.
+ */
+ if (nr - i > objects_per_slab_page(s))
+ i += slab_array_alloc_from_page_allocator(s,
+ flags, nr - i, p + i);
+
+ /* Get per cpu objects that may be available */
+ if (i < nr)
+ i += slab_array_alloc_from_local(s, nr - i, p + i);
+
+#endif
+ /*
+ * If a fully filled array has been requested then fill it
+ * up if there are objects missing using the regular kmem_cache_alloc()
+ */
+ if (i < nr)
+ i += __kmem_cache_alloc_array(s, flags, nr - i, p + i);
+
+ return i;
+}
+EXPORT_SYMBOL(kmem_cache_alloc_array);
+
+/*
+ * Fallback function for objects that an allocator does not want
+ * to deal with or for allocators that do not support bulk operations.
+ */
+void __kmem_cache_free_array(struct kmem_cache *s, size_t nr, void **p)
+{
+ int i;
+
+ for (i = 0; i < nr; i++)
+ kmem_cache_free(s, p[i]);
+}
+
+#ifndef _HAVE_SLAB_ALLOCATOR_ARRAY_OPERATIONS
+void kmem_cache_free_array(struct kmem_cache *s, size_t nr, void **p)
+{
+ __kmem_cache_free_array(s, nr, p);
+}
+EXPORT_SYMBOL(kmem_cache_free_array);
+#endif
+
#ifdef CONFIG_MEMCG_KMEM
static int memcg_alloc_cache_params(struct mem_cgroup *memcg,
struct kmem_cache *s, struct kmem_cache *root_cache)
Index: linux/mm/slab.h
===================================================================
--- linux.orig/mm/slab.h
+++ linux/mm/slab.h
@@ -69,6 +69,9 @@ extern struct kmem_cache *kmem_cache;
unsigned long calculate_alignment(unsigned long flags,
unsigned long align, unsigned long size);
+/* Determine the number of objects per slab page */
+unsigned objects_per_slab_page(struct kmem_cache *);
+
#ifndef CONFIG_SLOB
/* Kmalloc array related functions */
void create_kmalloc_caches(unsigned long);
@@ -362,4 +365,12 @@ void *slab_next(struct seq_file *m, void
void slab_stop(struct seq_file *m, void *p);
int memcg_slab_show(struct seq_file *m, void *p);
+void __kmem_cache_free_array(struct kmem_cache *s, int nr, void **p);
+void __kmem_cache_alloc_array(struct kmem_cache *s, gfp_t flags, int nr, void **p);
+
+int slab_array_alloc_from_partial(struct kmem_cache *s, size_t nr, void **p);
+int slab_array_alloc_from_local(struct kmem_cache *s, size_t nr, void **p);
+int slab_array_alloc_from_page_allocator(struct kmem_cache *s, gfp_t flags,
+ size_t nr, void **p);
+
#endif /* MM_SLAB_H */
Index: linux/mm/slub.c
===================================================================
--- linux.orig/mm/slub.c
+++ linux/mm/slub.c
@@ -332,6 +332,11 @@ static inline int oo_objects(struct kmem
return x.x & OO_MASK;
}
+unsigned objects_per_slab_page(struct kmem_cache *s)
+{
+ return oo_objects(s->oo);
+}
+
/*
* Per slab locking using the pagelock
*/
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2015-02-10 19:48 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-10 19:48 [PATCH 0/3] Slab allocator array operations V2 Christoph Lameter
2015-02-10 19:48 ` Christoph Lameter [this message]
2015-02-10 22:43 ` [PATCH 1/3] Slab infrastructure for array operations Jesper Dangaard Brouer
2015-02-10 23:58 ` David Rientjes
2015-02-11 18:47 ` Christoph Lameter
2015-02-11 20:18 ` David Rientjes
2015-02-11 22:04 ` Christoph Lameter
2015-02-12 0:35 ` David Rientjes
2015-02-13 2:35 ` Joonsoo Kim
2015-02-13 15:47 ` Christoph Lameter
2015-02-13 21:20 ` David Rientjes
2015-02-17 5:15 ` Joonsoo Kim
2015-02-17 16:03 ` Christoph Lameter
2015-02-17 21:32 ` Jesper Dangaard Brouer
2015-02-18 23:02 ` Christoph Lameter
2015-02-10 19:48 ` [PATCH 2/3] slub: Support " Christoph Lameter
2015-02-11 4:48 ` Jesper Dangaard Brouer
2015-02-11 19:07 ` Christoph Lameter
2015-02-11 21:43 ` Jesper Dangaard Brouer
2015-02-11 22:06 ` Christoph Lameter
2015-02-12 0:16 ` Jesper Dangaard Brouer
2015-02-12 2:46 ` Christoph Lameter
2015-02-13 2:45 ` Joonsoo Kim
2015-02-13 15:49 ` Christoph Lameter
2015-02-17 5:26 ` Joonsoo Kim
2015-02-10 19:48 ` [PATCH 3/3] Array alloc test code 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=20150210194811.787556326@linux.com \
--to=cl@linux.com \
--cc=akpm@linuxfoundation.org \
--cc=brouer@redhat.com \
--cc=iamjoonsoo@lge.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=penberg@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox