sparc64: Fix stack dumping and tracing when function graph is enabled.
[safe/jmp/linux-2.6] / mm / slub.c
index bd4a9e9..7d6c8b1 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
  * Set of flags that will prevent slab merging
  */
 #define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
-               SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE)
+               SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE | \
+               SLAB_FAILSLAB)
 
 #define SLUB_MERGE_SAME (SLAB_DEBUG_FREE | SLAB_RECLAIM_ACCOUNT | \
                SLAB_CACHE_DMA | SLAB_NOTRACK)
@@ -1004,6 +1005,9 @@ static int __init setup_slub_debug(char *str)
                case 't':
                        slub_debug |= SLAB_TRACE;
                        break;
+               case 'a':
+                       slub_debug |= SLAB_FAILSLAB;
+                       break;
                default:
                        printk(KERN_ERR "slub_debug option '%c' "
                                "unknown. skipped\n", *str);
@@ -1700,7 +1704,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
        lockdep_trace_alloc(gfpflags);
        might_sleep_if(gfpflags & __GFP_WAIT);
 
-       if (should_failslab(s->objsize, gfpflags))
+       if (should_failslab(s->objsize, gfpflags, s->flags))
                return NULL;
 
        local_irq_save(flags);
@@ -2071,7 +2075,7 @@ static inline int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
                 * Boot time creation of the kmalloc array. Use static per cpu data
                 * since the per cpu allocator is not available yet.
                 */
-               s->cpu_slab = per_cpu_var(kmalloc_percpu) + (s - kmalloc_caches);
+               s->cpu_slab = kmalloc_percpu + (s - kmalloc_caches);
        else
                s->cpu_slab =  alloc_percpu(struct kmem_cache_cpu);
 
@@ -2382,6 +2386,9 @@ int kmem_ptr_validate(struct kmem_cache *s, const void *object)
 {
        struct page *page;
 
+       if (!kern_ptr_validate(object, s->size))
+               return 0;
+
        page = get_object_page(object);
 
        if (!page || s != page->slab)
@@ -2956,7 +2963,7 @@ static void slab_mem_offline_callback(void *arg)
                        /*
                         * if n->nr_slabs > 0, slabs still exist on the node
                         * that is going down. We were unable to free them,
-                        * and offline_pages() function shoudn't call this
+                        * and offline_pages() function shouldn't call this
                         * callback. So, we must fail.
                         */
                        BUG_ON(slabs_node(s, offline_node));
@@ -4017,6 +4024,23 @@ static ssize_t trace_store(struct kmem_cache *s, const char *buf,
 }
 SLAB_ATTR(trace);
 
+#ifdef CONFIG_FAILSLAB
+static ssize_t failslab_show(struct kmem_cache *s, char *buf)
+{
+       return sprintf(buf, "%d\n", !!(s->flags & SLAB_FAILSLAB));
+}
+
+static ssize_t failslab_store(struct kmem_cache *s, const char *buf,
+                                                       size_t length)
+{
+       s->flags &= ~SLAB_FAILSLAB;
+       if (buf[0] == '1')
+               s->flags |= SLAB_FAILSLAB;
+       return length;
+}
+SLAB_ATTR(failslab);
+#endif
+
 static ssize_t reclaim_account_show(struct kmem_cache *s, char *buf)
 {
        return sprintf(buf, "%d\n", !!(s->flags & SLAB_RECLAIM_ACCOUNT));
@@ -4313,6 +4337,10 @@ static struct attribute *slab_attrs[] = {
        &deactivate_remote_frees_attr.attr,
        &order_fallback_attr.attr,
 #endif
+#ifdef CONFIG_FAILSLAB
+       &failslab_attr.attr,
+#endif
+
        NULL
 };
 
@@ -4365,7 +4393,7 @@ static void kmem_cache_release(struct kobject *kobj)
        kfree(s);
 }
 
-static struct sysfs_ops slab_sysfs_ops = {
+static const struct sysfs_ops slab_sysfs_ops = {
        .show = slab_attr_show,
        .store = slab_attr_store,
 };
@@ -4384,7 +4412,7 @@ static int uevent_filter(struct kset *kset, struct kobject *kobj)
        return 0;
 }
 
-static struct kset_uevent_ops slab_uevent_ops = {
+static const struct kset_uevent_ops slab_uevent_ops = {
        .filter = uevent_filter,
 };