[RFC/PATCH 2/2] slab: mempool-backed object caches

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Matthew,

This completely untested patch adds kmem_cache_create_mempool which
creates a mempool-backed object cache. It wont work as-is (we're not
checking page order, for example) but you should get the idea.

The good part is that now you can create object caches for many critical
allocations which can share the same subsystem-specific mempool.

Signed-off-by: Pekka Enberg <[email protected]>
---

 include/linux/slab.h |   15 ++++++++++++---
 mm/slab.c            |   44 ++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 52 insertions(+), 7 deletions(-)

Index: 2.6-mm/include/linux/slab.h
===================================================================
--- 2.6-mm.orig/include/linux/slab.h
+++ 2.6-mm/include/linux/slab.h
@@ -15,6 +15,7 @@ typedef struct kmem_cache kmem_cache_t;
 #include	<linux/gfp.h>
 #include	<linux/init.h>
 #include	<linux/types.h>
+#include	<linux/mempool.h>
 #include	<asm/page.h>		/* kmalloc_sizes.h needs PAGE_SIZE */
 #include	<asm/cache.h>		/* kmalloc_sizes.h needs L1_CACHE_BYTES */
 
@@ -58,9 +59,17 @@ typedef struct kmem_cache kmem_cache_t;
 /* prototypes */
 extern void __init kmem_cache_init(void);
 
-extern kmem_cache_t *kmem_cache_create(const char *, size_t, size_t, unsigned long,
-				       void (*)(void *, kmem_cache_t *, unsigned long),
-				       void (*)(void *, kmem_cache_t *, unsigned long));
+typedef void (*kmem_ctor_fn)(void *, kmem_cache_t *, unsigned long);
+typedef void (*kmem_dtor_fn)(void *, kmem_cache_t *, unsigned long);
+
+extern struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
+					    unsigned long, kmem_ctor_fn,
+					    kmem_dtor_fn);
+
+extern struct kmem_cache *kmem_cache_create_mempool(const char *, size_t,
+						    size_t, unsigned long,
+						    kmem_ctor_fn,
+						    kmem_dtor_fn, mempool_t *);
 extern int kmem_cache_destroy(kmem_cache_t *);
 extern int kmem_cache_shrink(kmem_cache_t *);
 extern void *kmem_cache_alloc(kmem_cache_t *, gfp_t);
Index: 2.6-mm/mm/slab.c
===================================================================
--- 2.6-mm.orig/mm/slab.c
+++ 2.6-mm/mm/slab.c
@@ -406,6 +406,7 @@ struct kmem_cache {
 	/* de-constructor func */
 	void (*dtor) (void *, struct kmem_cache *, unsigned long);
 
+	mempool_t *mempool;
 	struct kmem_cache_operations *ops;
 
 	/* shrinker data for this cache */
@@ -1346,6 +1347,22 @@ static struct kmem_cache_operations page
 	.freepages = pagealloc_freepages
 };
 
+static void *mempool_getpages(struct kmem_cache *cache, gfp_t flags,
+			      int nodeid)
+{
+	return mempool_alloc(cache->mempool, flags);
+}
+
+static void mempool_freepages(struct kmem_cache *cache, void *addr)
+{
+	mempool_free(addr, cache->mempool);
+}
+
+static struct kmem_cache_operations mempool_ops = {
+	.getpages = mempool_getpages,
+	.freepages = mempool_freepages
+};
+
 static void kmem_rcu_free(struct rcu_head *head)
 {
 	struct slab_rcu *slab_rcu = (struct slab_rcu *)head;
@@ -1678,9 +1695,9 @@ static inline size_t calculate_slab_orde
  * as davem.
  */
 struct kmem_cache *
-kmem_cache_create (const char *name, size_t size, size_t align,
-	unsigned long flags, void (*ctor)(void*, struct kmem_cache *, unsigned long),
-	void (*dtor)(void*, struct kmem_cache *, unsigned long))
+__kmem_cache_create(const char *name, size_t size, size_t align,
+		    unsigned long flags, kmem_ctor_fn ctor, kmem_dtor_fn dtor,
+		    mempool_t *mempool, struct kmem_cache_operations *ops)
 {
 	size_t left_over, slab_size, ralign;
 	struct kmem_cache *cachep = NULL;
@@ -1810,7 +1827,8 @@ kmem_cache_create (const char *name, siz
 		goto oops;
 	memset(cachep, 0, sizeof(struct kmem_cache));
 
-	cachep->ops = &pagealloc_ops;
+	cachep->mempool = mempool;
+	cachep->ops = ops;
 #if DEBUG
 	cachep->obj_size = size;
 
@@ -1970,8 +1988,26 @@ kmem_cache_create (const char *name, siz
 
 	return cachep;
 }
+
+struct kmem_cache *
+kmem_cache_create(const char *name, size_t size, size_t align,
+		  unsigned long flags, kmem_ctor_fn ctor, kmem_dtor_fn dtor)
+{
+	return __kmem_cache_create(name, size, align, flags, ctor, dtor,
+				   NULL, &pagealloc_ops);
+}
 EXPORT_SYMBOL(kmem_cache_create);
 
+struct kmem_cache *
+kmem_cache_create_mempool(const char *name, size_t size, size_t align,
+			  unsigned long flags, kmem_ctor_fn ctor,
+			  kmem_dtor_fn dtor, mempool_t *mempool)
+{
+	return __kmem_cache_create(name, size, align, flags, ctor, dtor,
+				   mempool, &mempool_ops);
+}
+EXPORT_SYMBOL(kmem_cache_create_mempool);
+
 #if DEBUG
 static void check_irq_off(void)
 {


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

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux