Merge branches 'slab/fixes', 'slob/fixes', 'slub/cleanups' and 'slub/fixes' into...
authorPekka Enberg <penberg@cs.helsinki.fi>
Wed, 4 Aug 2010 19:04:43 +0000 (22:04 +0300)
committerPekka Enberg <penberg@cs.helsinki.fi>
Wed, 4 Aug 2010 19:04:43 +0000 (22:04 +0300)
1  2  3  4  5 
mm/slub.c

diff --combined mm/slub.c
index 578f68f3c51f76ed3c2ff21b5ff2545d2ab64c0d,578f68f3c51f76ed3c2ff21b5ff2545d2ab64c0d,578f68f3c51f76ed3c2ff21b5ff2545d2ab64c0d,fb6518efe1ed4ebfa511158229dc37ec45b9ee58,39d39653239b182d26b6edfba1f352e0937476fc..fba51d6d4cc44ee659e634eb65fb2e764063c8ac
+++ b/mm/slub.c
      *                         the fast path and disables lockless freelists.
      */
     
+++ +#define SLAB_DEBUG_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
+++ +           SLAB_TRACE | SLAB_DEBUG_FREE)
+++ +
+++ +static inline int kmem_cache_debug(struct kmem_cache *s)
+++ +{
     #ifdef CONFIG_SLUB_DEBUG
--- -#define SLABDEBUG 1
+++ +   return unlikely(s->flags & SLAB_DEBUG_FLAGS);
     #else
--- -#define SLABDEBUG 0
+++ +   return 0;
     #endif
+++ +}
     
     /*
      * Issues still to be resolved:
     #define MAX_OBJS_PER_PAGE  65535 /* since page.objects is u16 */
     
     /* Internal SLUB flags */
--- -#define __OBJECT_POISON            0x80000000 /* Poison object */
--- -#define __SYSFS_ADD_DEFERRED       0x40000000 /* Not yet visible via sysfs */
+++ +#define __OBJECT_POISON            0x80000000UL /* Poison object */
+++ +#define __SYSFS_ADD_DEFERRED       0x40000000UL /* Not yet visible via sysfs */
     
     static int kmem_size = sizeof(struct kmem_cache);
     
@@@@@@ -1073,7 -1073,7 -1073,7 -1079,7 -1073,7 +1079,7 @@@@@@ static inline struct page *alloc_slab_p
     
        flags |= __GFP_NOTRACK;
     
--- -   if (node == -1)
+++ +   if (node == NUMA_NO_NODE)
                return alloc_pages(flags, order);
        else
                return alloc_pages_exact_node(node, flags, order);
@@@@@@ -1157,9 -1157,9 -1157,9 -1163,6 -1157,9 +1163,6 @@@@@@ static struct page *new_slab(struct kme
        inc_slabs_node(s, page_to_nid(page), page->objects);
        page->slab = s;
        page->flags |= 1 << PG_slab;
--- -   if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON |
--- -                   SLAB_STORE_USER | SLAB_TRACE))
--- -           __SetPageSlubDebug(page);
     
        start = page_address(page);
     
@@@@@@ -1186,14 -1186,14 -1186,14 -1189,13 -1186,14 +1189,13 @@@@@@ static void __free_slab(struct kmem_cac
        int order = compound_order(page);
        int pages = 1 << order;
     
--- -   if (unlikely(SLABDEBUG && PageSlubDebug(page))) {
+++ +   if (kmem_cache_debug(s)) {
                void *p;
     
                slab_pad_check(s, page);
                for_each_object(p, s, page_address(page),
                                                page->objects)
                        check_object(s, page, p, 0);
--- -           __ClearPageSlubDebug(page);
        }
     
        kmemcheck_free_shadow(page, compound_order(page));
@@@@@@ -1387,10 -1387,10 -1387,10 -1389,10 -1387,10 +1389,10 @@@@@@ static struct page *get_any_partial(str
     static struct page *get_partial(struct kmem_cache *s, gfp_t flags, int node)
     {
        struct page *page;
--- -   int searchnode = (node == -1) ? numa_node_id() : node;
+++ +   int searchnode = (node == NUMA_NO_NODE) ? numa_node_id() : node;
     
        page = get_partial_node(get_node(s, searchnode));
----    if (page || (flags & __GFP_THISNODE))
++++    if (page || node != -1)
                return page;
     
        return get_any_partial(s, flags);
@@@@@@ -1415,8 -1415,8 -1415,8 -1417,7 -1415,8 +1417,7 @@@@@@ static void unfreeze_slab(struct kmem_c
                        stat(s, tail ? DEACTIVATE_TO_TAIL : DEACTIVATE_TO_HEAD);
                } else {
                        stat(s, DEACTIVATE_FULL);
--- -                   if (SLABDEBUG && PageSlubDebug(page) &&
--- -                                           (s->flags & SLAB_STORE_USER))
+++ +                   if (kmem_cache_debug(s) && (s->flags & SLAB_STORE_USER))
                                add_full(n, page);
                }
                slab_unlock(page);
@@@@@@ -1515,7 -1515,7 -1515,7 -1516,7 -1515,7 +1516,7 @@@@@@ static void flush_all(struct kmem_cach
     static inline int node_match(struct kmem_cache_cpu *c, int node)
     {
     #ifdef CONFIG_NUMA
--- -   if (node != -1 && c->node != node)
+++ +   if (node != NUMA_NO_NODE && c->node != node)
                return 0;
     #endif
        return 1;
@@@@@@ -1624,7 -1624,7 -1624,7 -1625,7 -1624,7 +1625,7 @@@@@@ load_freelist
        object = c->page->freelist;
        if (unlikely(!object))
                goto another_slab;
--- -   if (unlikely(SLABDEBUG && PageSlubDebug(c->page)))
+++ +   if (kmem_cache_debug(s))
                goto debug;
     
        c->freelist = get_freepointer(s, object);
@@@@@@ -1727,7 -1727,7 -1727,7 -1728,7 -1727,7 +1728,7 @@@@@@ static __always_inline void *slab_alloc
     
     void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
     {
--- -   void *ret = slab_alloc(s, gfpflags, -1, _RET_IP_);
+++ +   void *ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
     
        trace_kmem_cache_alloc(_RET_IP_, ret, s->objsize, s->size, gfpflags);
     
@@@@@@ -1738,7 -1738,7 -1738,7 -1739,7 -1738,7 +1739,7 @@@@@@ EXPORT_SYMBOL(kmem_cache_alloc)
     #ifdef CONFIG_TRACING
     void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags)
     {
--- -   return slab_alloc(s, gfpflags, -1, _RET_IP_);
+++ +   return slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
     }
     EXPORT_SYMBOL(kmem_cache_alloc_notrace);
     #endif
@@@@@@ -1783,7 -1783,7 -1783,7 -1784,7 -1783,7 +1784,7 @@@@@@ static void __slab_free(struct kmem_cac
        stat(s, FREE_SLOWPATH);
        slab_lock(page);
     
--- -   if (unlikely(SLABDEBUG && PageSlubDebug(page)))
+++ +   if (kmem_cache_debug(s))
                goto debug;
     
     checks_ok:
@@@@@@ -2490,7 -2490,7 -2490,7 -2491,6 -2490,7 +2491,6 @@@@@@ void kmem_cache_destroy(struct kmem_cac
        s->refcount--;
        if (!s->refcount) {
                list_del(&s->list);
--- -           up_write(&slub_lock);
                if (kmem_cache_close(s)) {
                        printk(KERN_ERR "SLUB %s: %s called for cache that "
                                "still has objects.\n", s->name, __func__);
                if (s->flags & SLAB_DESTROY_BY_RCU)
                        rcu_barrier();
                sysfs_slab_remove(s);
--- -   } else
--- -           up_write(&slub_lock);
+++ +   }
+++ +   up_write(&slub_lock);
     }
     EXPORT_SYMBOL(kmem_cache_destroy);
     
@@@@@@ -2728,7 -2728,7 -2728,7 -2728,7 -2728,7 +2728,7 @@@@@@ void *__kmalloc(size_t size, gfp_t flag
        if (unlikely(ZERO_OR_NULL_PTR(s)))
                return s;
     
--- -   ret = slab_alloc(s, flags, -1, _RET_IP_);
+++ +   ret = slab_alloc(s, flags, NUMA_NO_NODE, _RET_IP_);
     
        trace_kmalloc(_RET_IP_, ret, size, s->size, flags);
     
@@@@@@ -3118,9 -3118,9 -3118,9 -3118,12 -3118,9 +3118,12 @@@@@@ void __init kmem_cache_init(void
        slab_state = UP;
     
        /* Provide the correct kmalloc names now that the caches are up */
--- -   for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++)
--- -           kmalloc_caches[i]. name =
--- -                   kasprintf(GFP_NOWAIT, "kmalloc-%d", 1 << i);
+++ +   for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++) {
+++ +           char *s = kasprintf(GFP_NOWAIT, "kmalloc-%d", 1 << i);
+++ +
+++ +           BUG_ON(!s);
+++ +           kmalloc_caches[i].name = s;
+++ +   }
     
     #ifdef CONFIG_SMP
        register_cpu_notifier(&slab_notifier);
@@@@@@ -3223,14 -3223,14 -3223,14 -3226,12 -3223,14 +3226,12 @@@@@@ struct kmem_cache *kmem_cache_create(co
                 */
                s->objsize = max(s->objsize, (int)size);
                s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
--- -           up_write(&slub_lock);
     
                if (sysfs_slab_alias(s, name)) {
--- -                   down_write(&slub_lock);
                        s->refcount--;
--- -                   up_write(&slub_lock);
                        goto err;
                }
+++ +           up_write(&slub_lock);
                return s;
        }
     
                if (kmem_cache_open(s, GFP_KERNEL, name,
                                size, align, flags, ctor)) {
                        list_add(&s->list, &slab_caches);
--- -                   up_write(&slub_lock);
                        if (sysfs_slab_add(s)) {
--- -                           down_write(&slub_lock);
                                list_del(&s->list);
--- -                           up_write(&slub_lock);
                                kfree(s);
                                goto err;
                        }
+++ +                   up_write(&slub_lock);
                        return s;
                }
                kfree(s);
@@@@@@ -3312,7 -3312,7 -3312,7 -3311,7 -3312,7 +3311,7 @@@@@@ void *__kmalloc_track_caller(size_t siz
        if (unlikely(ZERO_OR_NULL_PTR(s)))
                return s;
     
--- -   ret = slab_alloc(s, gfpflags, -1, caller);
+++ +   ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, caller);
     
        /* Honor the call site pointer we recieved. */
        trace_kmalloc(caller, ret, size, s->size, gfpflags);
@@@@@@ -3395,16 -3395,16 -3395,16 -3394,6 -3395,16 +3394,6 @@@@@@ static void validate_slab_slab(struct k
        } else
                printk(KERN_INFO "SLUB %s: Skipped busy slab 0x%p\n",
                        s->name, page);
--- -
--- -   if (s->flags & DEBUG_DEFAULT_FLAGS) {
--- -           if (!PageSlubDebug(page))
--- -                   printk(KERN_ERR "SLUB %s: SlubDebug not set "
--- -                           "on slab 0x%p\n", s->name, page);
--- -   } else {
--- -           if (PageSlubDebug(page))
--- -                   printk(KERN_ERR "SLUB %s: SlubDebug set on "
--- -                           "slab 0x%p\n", s->name, page);
--- -   }
     }
     
     static int validate_slab_node(struct kmem_cache *s,
@@@@@@ -4504,6 -4504,6 -4504,6 -4493,13 -4504,6 +4493,13 @@@@@@ static int sysfs_slab_add(struct kmem_c
     
     static void sysfs_slab_remove(struct kmem_cache *s)
     {
+++ +   if (slab_state < SYSFS)
+++ +           /*
+++ +            * Sysfs has not been setup yet so no need to remove the
+++ +            * cache from sysfs.
+++ +            */
+++ +           return;
+++ +
        kobject_uevent(&s->kobj, KOBJ_REMOVE);
        kobject_del(&s->kobj);
        kobject_put(&s->kobj);
@@@@@@ -4549,8 -4549,8 -4549,8 -4545,11 -4549,8 +4545,11 @@@@@@ static int __init slab_sysfs_init(void
        struct kmem_cache *s;
        int err;
     
+++ +   down_write(&slub_lock);
+++ +
        slab_kset = kset_create_and_add("slab", &slab_uevent_ops, kernel_kobj);
        if (!slab_kset) {
+++ +           up_write(&slub_lock);
                printk(KERN_ERR "Cannot register slab subsystem.\n");
                return -ENOSYS;
        }
                kfree(al);
        }
     
+++ +   up_write(&slub_lock);
        resiliency_test();
        return 0;
     }