]> err.no Git - linux-2.6/blobdiff - mm/slab.c
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
[linux-2.6] / mm / slab.c
index 4bd8a53091b745174dd645564088411d5b002319..a684778b2b41af38e06aa47e5fe66a7a988ad4c7 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -775,6 +775,9 @@ static inline struct kmem_cache *__find_general_cachep(size_t size,
         */
        BUG_ON(malloc_sizes[INDEX_AC].cs_cachep == NULL);
 #endif
+       if (!size)
+               return ZERO_SIZE_PTR;
+
        while (size > csizep->cs_size)
                csizep++;
 
@@ -1160,7 +1163,7 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb,
        struct kmem_cache *cachep;
        struct kmem_list3 *l3 = NULL;
        int node = cpu_to_node(cpu);
-       int memsize = sizeof(struct kmem_list3);
+       const int memsize = sizeof(struct kmem_list3);
 
        switch (action) {
        case CPU_LOCK_ACQUIRE:
@@ -1481,7 +1484,7 @@ void __init kmem_cache_init(void)
                                        sizes[INDEX_AC].cs_size,
                                        ARCH_KMALLOC_MINALIGN,
                                        ARCH_KMALLOC_FLAGS|SLAB_PANIC,
-                                       NULL, NULL);
+                                       NULL);
 
        if (INDEX_AC != INDEX_L3) {
                sizes[INDEX_L3].cs_cachep =
@@ -1489,7 +1492,7 @@ void __init kmem_cache_init(void)
                                sizes[INDEX_L3].cs_size,
                                ARCH_KMALLOC_MINALIGN,
                                ARCH_KMALLOC_FLAGS|SLAB_PANIC,
-                               NULL, NULL);
+                               NULL);
        }
 
        slab_early_init = 0;
@@ -1507,7 +1510,7 @@ void __init kmem_cache_init(void)
                                        sizes->cs_size,
                                        ARCH_KMALLOC_MINALIGN,
                                        ARCH_KMALLOC_FLAGS|SLAB_PANIC,
-                                       NULL, NULL);
+                                       NULL);
                }
 #ifdef CONFIG_ZONE_DMA
                sizes->cs_dmacachep = kmem_cache_create(
@@ -1516,7 +1519,7 @@ void __init kmem_cache_init(void)
                                        ARCH_KMALLOC_MINALIGN,
                                        ARCH_KMALLOC_FLAGS|SLAB_CACHE_DMA|
                                                SLAB_PANIC,
-                                       NULL, NULL);
+                                       NULL);
 #endif
                sizes++;
                names++;
@@ -2098,12 +2101,10 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep)
  * @align: The required alignment for the objects.
  * @flags: SLAB flags
  * @ctor: A constructor for the objects.
- * @dtor: A destructor for the objects (not implemented anymore).
  *
  * Returns a ptr to the cache on success, NULL on failure.
  * Cannot be called within a int, but can be interrupted.
- * The @ctor is run when new pages are allocated by the cache
- * and the @dtor is run before the pages are handed back.
+ * The @ctor is run when new pages are allocated by the cache.
  *
  * @name must be valid until the cache is destroyed. This implies that
  * the module calling this has to destroy the cache before getting unloaded.
@@ -2123,8 +2124,7 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep)
 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))
+       void (*ctor)(void*, struct kmem_cache *, unsigned long))
 {
        size_t left_over, slab_size, ralign;
        struct kmem_cache *cachep = NULL, *pc;
@@ -2133,7 +2133,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
         * Sanity checks... these are all serious usage bugs.
         */
        if (!name || in_interrupt() || (size < BYTES_PER_WORD) ||
-           size > KMALLOC_MAX_SIZE || dtor) {
+           size > KMALLOC_MAX_SIZE) {
                printk(KERN_ERR "%s: Early error in slab %s\n", __FUNCTION__,
                                name);
                BUG();
@@ -2351,7 +2351,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
                 * this should not happen at all.
                 * But leave a BUG_ON for some lucky dude.
                 */
-               BUG_ON(!cachep->slabp_cache);
+               BUG_ON(ZERO_OR_NULL_PTR(cachep->slabp_cache));
        }
        cachep->ctor = ctor;
        cachep->name = name;
@@ -2743,7 +2743,7 @@ static int cache_grow(struct kmem_cache *cachep,
         * Be lazy and only check for valid flags here,  keeping it out of the
         * critical path in kmem_cache_alloc().
         */
-       BUG_ON(flags & ~(GFP_DMA | GFP_LEVEL_MASK));
+       BUG_ON(flags & ~(GFP_DMA | __GFP_ZERO | GFP_LEVEL_MASK));
 
        local_flags = (flags & GFP_LEVEL_MASK);
        /* Take the l3 list lock to change the colour_next on this node */
@@ -2776,7 +2776,7 @@ static int cache_grow(struct kmem_cache *cachep,
         * 'nodeid'.
         */
        if (!objp)
-               objp = kmem_getpages(cachep, flags, nodeid);
+               objp = kmem_getpages(cachep, local_flags, nodeid);
        if (!objp)
                goto failed;
 
@@ -3389,6 +3389,9 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
        local_irq_restore(save_flags);
        ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
 
+       if (unlikely((flags & __GFP_ZERO) && ptr))
+               memset(ptr, 0, obj_size(cachep));
+
        return ptr;
 }
 
@@ -3440,6 +3443,9 @@ __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
        objp = cache_alloc_debugcheck_after(cachep, flags, objp, caller);
        prefetchw(objp);
 
+       if (unlikely((flags & __GFP_ZERO) && objp))
+               memset(objp, 0, obj_size(cachep));
+
        return objp;
 }
 
@@ -3580,23 +3586,6 @@ void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 }
 EXPORT_SYMBOL(kmem_cache_alloc);
 
-/**
- * kmem_cache_zalloc - Allocate an object. The memory is set to zero.
- * @cache: The cache to allocate from.
- * @flags: See kmalloc().
- *
- * Allocate an object from this cache and set the allocated memory to zero.
- * The flags are only relevant if the cache has no available objects.
- */
-void *kmem_cache_zalloc(struct kmem_cache *cache, gfp_t flags)
-{
-       void *ret = __cache_alloc(cache, flags, __builtin_return_address(0));
-       if (ret)
-               memset(ret, 0, obj_size(cache));
-       return ret;
-}
-EXPORT_SYMBOL(kmem_cache_zalloc);
-
 /**
  * kmem_ptr_validate - check if an untrusted pointer might
  *     be a slab entry.
@@ -3653,8 +3642,8 @@ __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller)
        struct kmem_cache *cachep;
 
        cachep = kmem_find_general_cachep(size, flags);
-       if (unlikely(cachep == NULL))
-               return NULL;
+       if (unlikely(ZERO_OR_NULL_PTR(cachep)))
+               return cachep;
        return kmem_cache_alloc_node(cachep, flags, node);
 }
 
@@ -3698,8 +3687,8 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
         * functions.
         */
        cachep = __find_general_cachep(size, flags);
-       if (unlikely(cachep == NULL))
-               return NULL;
+       if (unlikely(ZERO_OR_NULL_PTR(cachep)))
+               return cachep;
        return __cache_alloc(cachep, flags, caller);
 }
 
@@ -3760,7 +3749,7 @@ void kfree(const void *objp)
        struct kmem_cache *c;
        unsigned long flags;
 
-       if (unlikely(!objp))
+       if (unlikely(ZERO_OR_NULL_PTR(objp)))
                return;
        local_irq_save(flags);
        kfree_debugcheck(objp);
@@ -4352,7 +4341,7 @@ static void show_symbol(struct seq_file *m, unsigned long address)
 {
 #ifdef CONFIG_KALLSYMS
        unsigned long offset, size;
-       char modname[MODULE_NAME_LEN + 1], name[KSYM_NAME_LEN + 1];
+       char modname[MODULE_NAME_LEN], name[KSYM_NAME_LEN];
 
        if (lookup_symbol_attrs(address, &size, &offset, modname, name) == 0) {
                seq_printf(m, "%s+%#lx/%#lx", name, offset, size);
@@ -4447,7 +4436,7 @@ const struct seq_operations slabstats_op = {
  */
 size_t ksize(const void *objp)
 {
-       if (unlikely(objp == NULL))
+       if (unlikely(ZERO_OR_NULL_PTR(objp)))
                return 0;
 
        return obj_size(virt_to_cache(objp));