]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - mm/slub.c
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfashe...
[linux-2.6-omap-h63xx.git] / mm / slub.c
index c9ab68881b43ebe8525fb2fa1e943f9810229c21..6aea48942c29b3e2ada3a551d5382cc88e474539 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -323,7 +323,11 @@ static inline int slab_index(void *p, struct kmem_cache *s, void *addr)
 /*
  * Debug settings:
  */
+#ifdef CONFIG_SLUB_DEBUG_ON
+static int slub_debug = DEBUG_DEFAULT_FLAGS;
+#else
 static int slub_debug;
+#endif
 
 static char *slub_debug_slabs;
 
@@ -888,38 +892,57 @@ fail:
 
 static int __init setup_slub_debug(char *str)
 {
-       if (!str || *str != '=')
-               slub_debug = DEBUG_DEFAULT_FLAGS;
-       else {
-               str++;
-               if (*str == 0 || *str == ',')
-                       slub_debug = DEBUG_DEFAULT_FLAGS;
-               else
-               for( ;*str && *str != ','; str++)
-                       switch (*str) {
-                       case 'f' : case 'F' :
-                               slub_debug |= SLAB_DEBUG_FREE;
-                               break;
-                       case 'z' : case 'Z' :
-                               slub_debug |= SLAB_RED_ZONE;
-                               break;
-                       case 'p' : case 'P' :
-                               slub_debug |= SLAB_POISON;
-                               break;
-                       case 'u' : case 'U' :
-                               slub_debug |= SLAB_STORE_USER;
-                               break;
-                       case 't' : case 'T' :
-                               slub_debug |= SLAB_TRACE;
-                               break;
-                       default:
-                               printk(KERN_ERR "slub_debug option '%c' "
-                                       "unknown. skipped\n",*str);
-                       }
+       slub_debug = DEBUG_DEFAULT_FLAGS;
+       if (*str++ != '=' || !*str)
+               /*
+                * No options specified. Switch on full debugging.
+                */
+               goto out;
+
+       if (*str == ',')
+               /*
+                * No options but restriction on slabs. This means full
+                * debugging for slabs matching a pattern.
+                */
+               goto check_slabs;
+
+       slub_debug = 0;
+       if (*str == '-')
+               /*
+                * Switch off all debugging measures.
+                */
+               goto out;
+
+       /*
+        * Determine which debug features should be switched on
+        */
+       for ( ;*str && *str != ','; str++) {
+               switch (tolower(*str)) {
+               case 'f':
+                       slub_debug |= SLAB_DEBUG_FREE;
+                       break;
+               case 'z':
+                       slub_debug |= SLAB_RED_ZONE;
+                       break;
+               case 'p':
+                       slub_debug |= SLAB_POISON;
+                       break;
+               case 'u':
+                       slub_debug |= SLAB_STORE_USER;
+                       break;
+               case 't':
+                       slub_debug |= SLAB_TRACE;
+                       break;
+               default:
+                       printk(KERN_ERR "slub_debug option '%c' "
+                               "unknown. skipped\n",*str);
+               }
        }
 
+check_slabs:
        if (*str == ',')
                slub_debug_slabs = str + 1;
+out:
        return 1;
 }
 
@@ -1798,8 +1821,6 @@ static struct kmem_cache_node * __init early_kmem_cache_node_alloc(gfp_t gfpflag
        BUG_ON(kmalloc_caches->size < sizeof(struct kmem_cache_node));
 
        page = new_slab(kmalloc_caches, gfpflags | GFP_THISNODE, node);
-       /* new_slab() disables interupts */
-       local_irq_enable();
 
        BUG_ON(!page);
        n = page->freelist;
@@ -1811,6 +1832,12 @@ static struct kmem_cache_node * __init early_kmem_cache_node_alloc(gfp_t gfpflag
        init_kmem_cache_node(n);
        atomic_long_inc(&n->nr_slabs);
        add_partial(n, page);
+
+       /*
+        * new_slab() disables interupts. If we do not reenable interrupts here
+        * then bootup would continue with interrupts disabled.
+        */
+       local_irq_enable();
        return n;
 }
 
@@ -2016,7 +2043,6 @@ error:
                        s->offset, flags);
        return 0;
 }
-EXPORT_SYMBOL(kmem_cache_open);
 
 /*
  * Check if a given pointer is valid
@@ -2436,6 +2462,7 @@ EXPORT_SYMBOL(krealloc);
 void __init kmem_cache_init(void)
 {
        int i;
+       int caches = 0;
 
 #ifdef CONFIG_NUMA
        /*
@@ -2446,20 +2473,29 @@ void __init kmem_cache_init(void)
        create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node",
                sizeof(struct kmem_cache_node), GFP_KERNEL);
        kmalloc_caches[0].refcount = -1;
+       caches++;
 #endif
 
        /* Able to allocate the per node structures */
        slab_state = PARTIAL;
 
        /* Caches that are not of the two-to-the-power-of size */
-       create_kmalloc_cache(&kmalloc_caches[1],
+       if (KMALLOC_MIN_SIZE <= 64) {
+               create_kmalloc_cache(&kmalloc_caches[1],
                                "kmalloc-96", 96, GFP_KERNEL);
-       create_kmalloc_cache(&kmalloc_caches[2],
+               caches++;
+       }
+       if (KMALLOC_MIN_SIZE <= 128) {
+               create_kmalloc_cache(&kmalloc_caches[2],
                                "kmalloc-192", 192, GFP_KERNEL);
+               caches++;
+       }
 
-       for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++)
+       for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) {
                create_kmalloc_cache(&kmalloc_caches[i],
                        "kmalloc", 1 << i, GFP_KERNEL);
+               caches++;
+       }
 
        slab_state = UP;
 
@@ -2476,8 +2512,8 @@ void __init kmem_cache_init(void)
                                nr_cpu_ids * sizeof(struct page *);
 
        printk(KERN_INFO "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d,"
-               " Processors=%d, Nodes=%d\n",
-               KMALLOC_SHIFT_HIGH, cache_line_size(),
+               " CPUs=%d, Nodes=%d\n",
+               caches, cache_line_size(),
                slub_min_order, slub_max_order, slub_min_objects,
                nr_cpu_ids, nr_node_ids);
 }
@@ -2867,7 +2903,7 @@ static int alloc_loc_track(struct loc_track *t, unsigned long max)
 
        order = get_order(sizeof(struct location) * max);
 
-       l = (void *)__get_free_pages(GFP_KERNEL, order);
+       l = (void *)__get_free_pages(GFP_ATOMIC, order);
 
        if (!l)
                return 0;
@@ -3032,13 +3068,15 @@ static int list_locations(struct kmem_cache *s, char *buf,
                        n += sprintf(buf + n, " pid=%ld",
                                l->min_pid);
 
-               if (num_online_cpus() > 1 && !cpus_empty(l->cpus)) {
+               if (num_online_cpus() > 1 && !cpus_empty(l->cpus) &&
+                               n < PAGE_SIZE - 60) {
                        n += sprintf(buf + n, " cpus=");
                        n += cpulist_scnprintf(buf + n, PAGE_SIZE - n - 50,
                                        l->cpus);
                }
 
-               if (num_online_nodes() > 1 && !nodes_empty(l->nodes)) {
+               if (num_online_nodes() > 1 && !nodes_empty(l->nodes) &&
+                               n < PAGE_SIZE - 60) {
                        n += sprintf(buf + n, " nodes=");
                        n += nodelist_scnprintf(buf + n, PAGE_SIZE - n - 50,
                                        l->nodes);