[PATCH] slab: optimize constant-size kzalloc calls
authorPekka Enberg <penberg@cs.helsinki.fi>
Sat, 25 Mar 2006 11:06:43 +0000 (03:06 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sat, 25 Mar 2006 16:22:49 +0000 (08:22 -0800)
As suggested by Eric Dumazet, optimize kzalloc() calls that pass a
compile-time constant size.  Please note that the patch increases kernel
text slightly (~200 bytes for defconfig on x86).

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
include/linux/slab.h
mm/util.c

index 1216b09e07b10956f96267af18b249dded70b820..15e1d9736b1bb9fc130b27a81fdb8109b7fe02b5 100644 (file)
@@ -110,7 +110,30 @@ found:
        return __kmalloc(size, flags);
 }
 
-extern void *kzalloc(size_t, gfp_t);
+extern void *__kzalloc(size_t, gfp_t);
+
+static inline void *kzalloc(size_t size, gfp_t flags)
+{
+       if (__builtin_constant_p(size)) {
+               int i = 0;
+#define CACHE(x) \
+               if (size <= x) \
+                       goto found; \
+               else \
+                       i++;
+#include "kmalloc_sizes.h"
+#undef CACHE
+               {
+                       extern void __you_cannot_kzalloc_that_much(void);
+                       __you_cannot_kzalloc_that_much();
+               }
+found:
+               return kmem_cache_zalloc((flags & GFP_DMA) ?
+                       malloc_sizes[i].cs_dmacachep :
+                       malloc_sizes[i].cs_cachep, flags);
+       }
+       return __kzalloc(size, flags);
+}
 
 /**
  * kcalloc - allocate memory for an array. The memory is set to zero.
@@ -161,14 +184,14 @@ void *kmem_cache_zalloc(struct kmem_cache *, gfp_t);
 void kmem_cache_free(struct kmem_cache *c, void *b);
 const char *kmem_cache_name(struct kmem_cache *);
 void *kmalloc(size_t size, gfp_t flags);
-void *kzalloc(size_t size, gfp_t flags);
+void *__kzalloc(size_t size, gfp_t flags);
 void kfree(const void *m);
 unsigned int ksize(const void *m);
 unsigned int kmem_cache_size(struct kmem_cache *c);
 
 static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
 {
-       return kzalloc(n * size, flags);
+       return __kzalloc(n * size, flags);
 }
 
 #define kmem_cache_shrink(d) (0)
@@ -176,6 +199,7 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
 #define kmem_ptr_validate(a, b) (0)
 #define kmem_cache_alloc_node(c, f, n) kmem_cache_alloc(c, f)
 #define kmalloc_node(s, f, n) kmalloc(s, f)
+#define kzalloc(s, f) __kzalloc(s, f)
 #define ____kmalloc kmalloc
 
 #endif /* CONFIG_SLOB */
index b68d3d7d0359b0ab84d171ce7a97bae1a5073596..7368479220b3b4c3d8c12a9306bb18221d9a99b9 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -5,18 +5,18 @@
 #include <asm/uaccess.h>
 
 /**
- * kzalloc - allocate memory. The memory is set to zero.
+ * __kzalloc - allocate memory. The memory is set to zero.
  * @size: how many bytes of memory are required.
  * @flags: the type of memory to allocate.
  */
-void *kzalloc(size_t size, gfp_t flags)
+void *__kzalloc(size_t size, gfp_t flags)
 {
        void *ret = ____kmalloc(size, flags);
        if (ret)
                memset(ret, 0, size);
        return ret;
 }
-EXPORT_SYMBOL(kzalloc);
+EXPORT_SYMBOL(__kzalloc);
 
 /*
  * kstrdup - allocate space for and copy an existing string