]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - mm/slub.c
Merge branches 'topic/fixes', 'topic/cleanups' and 'topic/documentation' into for...
[linux-2.6.git] / mm / slub.c
index 5c8dbe3ae509a6b8defc9a4d157355ab4363aabd..ca95e45f04c3e41473001303df7c2f596ccba47d 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1595,6 +1595,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
        unsigned long flags;
        unsigned int objsize;
 
+       might_sleep_if(gfpflags & __GFP_WAIT);
        local_irq_save(flags);
        c = get_cpu_slab(s, smp_processor_id());
        objsize = c->objsize;
@@ -2932,8 +2933,10 @@ static int slab_memory_callback(struct notifier_block *self,
        case MEM_CANCEL_OFFLINE:
                break;
        }
-
-       ret = notifier_from_errno(ret);
+       if (ret)
+               ret = notifier_from_errno(ret);
+       else
+               ret = NOTIFY_OK;
        return ret;
 }
 
@@ -3122,8 +3125,12 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
                s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
                up_write(&slub_lock);
 
-               if (sysfs_slab_alias(s, name))
+               if (sysfs_slab_alias(s, name)) {
+                       down_write(&slub_lock);
+                       s->refcount--;
+                       up_write(&slub_lock);
                        goto err;
+               }
                return s;
        }
 
@@ -3133,8 +3140,13 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
                                size, align, flags, ctor)) {
                        list_add(&s->list, &slab_caches);
                        up_write(&slub_lock);
-                       if (sysfs_slab_add(s))
+                       if (sysfs_slab_add(s)) {
+                               down_write(&slub_lock);
+                               list_del(&s->list);
+                               up_write(&slub_lock);
+                               kfree(s);
                                goto err;
+                       }
                        return s;
                }
                kfree(s);
@@ -3596,7 +3608,7 @@ static int list_locations(struct kmem_cache *s, char *buf,
        for (i = 0; i < t.count; i++) {
                struct location *l = &t.loc[i];
 
-               if (len > PAGE_SIZE - 100)
+               if (len > PAGE_SIZE - KSYM_SYMBOL_LEN - 100)
                        break;
                len += sprintf(buf + len, "%7ld ", l->count);