ARM: 8985/1: efi/decompressor: deal with HYP mode boot gracefully
[linux-2.6-microblaze.git] / mm / slub.c
index 6589b41..b8f798b 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -259,7 +259,7 @@ static inline void *freelist_ptr(const struct kmem_cache *s, void *ptr,
         * freepointer to be restored incorrectly.
         */
        return (void *)((unsigned long)ptr ^ s->random ^
-                       (unsigned long)kasan_reset_tag((void *)ptr_addr));
+                       swab((unsigned long)kasan_reset_tag((void *)ptr_addr)));
 #else
        return ptr;
 #endif
@@ -449,6 +449,7 @@ static DEFINE_SPINLOCK(object_map_lock);
  * not vanish from under us.
  */
 static unsigned long *get_map(struct kmem_cache *s, struct page *page)
+       __acquires(&object_map_lock)
 {
        void *p;
        void *addr = page_address(page);
@@ -465,7 +466,7 @@ static unsigned long *get_map(struct kmem_cache *s, struct page *page)
        return object_map;
 }
 
-static void put_map(unsigned long *map)
+static void put_map(unsigned long *map) __releases(&object_map_lock)
 {
        VM_BUG_ON(map != object_map);
        lockdep_assert_held(&object_map_lock);
@@ -550,15 +551,32 @@ static void print_section(char *level, char *text, u8 *addr,
        metadata_access_disable();
 }
 
+/*
+ * See comment in calculate_sizes().
+ */
+static inline bool freeptr_outside_object(struct kmem_cache *s)
+{
+       return s->offset >= s->inuse;
+}
+
+/*
+ * Return offset of the end of info block which is inuse + free pointer if
+ * not overlapping with object.
+ */
+static inline unsigned int get_info_end(struct kmem_cache *s)
+{
+       if (freeptr_outside_object(s))
+               return s->inuse + sizeof(void *);
+       else
+               return s->inuse;
+}
+
 static struct track *get_track(struct kmem_cache *s, void *object,
        enum track_item alloc)
 {
        struct track *p;
 
-       if (s->offset)
-               p = object + s->offset + sizeof(void *);
-       else
-               p = object + s->inuse;
+       p = object + get_info_end(s);
 
        return p + alloc;
 }
@@ -661,6 +679,20 @@ static void slab_fix(struct kmem_cache *s, char *fmt, ...)
        va_end(args);
 }
 
+static bool freelist_corrupted(struct kmem_cache *s, struct page *page,
+                              void *freelist, void *nextfree)
+{
+       if ((s->flags & SLAB_CONSISTENCY_CHECKS) &&
+           !check_valid_pointer(s, page, nextfree)) {
+               object_err(s, page, freelist, "Freechain corrupt");
+               freelist = NULL;
+               slab_fix(s, "Isolate corrupted freechain");
+               return true;
+       }
+
+       return false;
+}
+
 static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
 {
        unsigned int off;       /* Offset of last byte */
@@ -685,10 +717,7 @@ static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
                print_section(KERN_ERR, "Redzone ", p + s->object_size,
                        s->inuse - s->object_size);
 
-       if (s->offset)
-               off = s->offset + sizeof(void *);
-       else
-               off = s->inuse;
+       off = get_info_end(s);
 
        if (s->flags & SLAB_STORE_USER)
                off += 2 * sizeof(struct track);
@@ -781,7 +810,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
  * object address
  *     Bytes of the object to be managed.
  *     If the freepointer may overlay the object then the free
- *     pointer is the first word of the object.
+ *     pointer is at the middle of the object.
  *
  *     Poisoning uses 0x6b (POISON_FREE) and the last byte is
  *     0xa5 (POISON_END)
@@ -815,11 +844,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
 
 static int check_pad_bytes(struct kmem_cache *s, struct page *page, u8 *p)
 {
-       unsigned long off = s->inuse;   /* The end of info */
-
-       if (s->offset)
-               /* Freepointer is placed after the object. */
-               off += sizeof(void *);
+       unsigned long off = get_info_end(s);    /* The end of info */
 
        if (s->flags & SLAB_STORE_USER)
                /* We also have user information there */
@@ -906,7 +931,7 @@ static int check_object(struct kmem_cache *s, struct page *page,
                check_pad_bytes(s, page, p);
        }
 
-       if (!s->offset && val == SLUB_RED_ACTIVE)
+       if (!freeptr_outside_object(s) && val == SLUB_RED_ACTIVE)
                /*
                 * Object and freepointer overlap. Cannot check
                 * freepointer while object is allocated.
@@ -1399,6 +1424,11 @@ static inline void inc_slabs_node(struct kmem_cache *s, int node,
 static inline void dec_slabs_node(struct kmem_cache *s, int node,
                                                        int objects) {}
 
+static bool freelist_corrupted(struct kmem_cache *s, struct page *page,
+                              void *freelist, void *nextfree)
+{
+       return false;
+}
 #endif /* CONFIG_SLUB_DEBUG */
 
 /*
@@ -1908,7 +1938,7 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags,
        struct zonelist *zonelist;
        struct zoneref *z;
        struct zone *zone;
-       enum zone_type high_zoneidx = gfp_zone(flags);
+       enum zone_type highest_zoneidx = gfp_zone(flags);
        void *object;
        unsigned int cpuset_mems_cookie;
 
@@ -1937,7 +1967,7 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags,
        do {
                cpuset_mems_cookie = read_mems_allowed_begin();
                zonelist = node_zonelist(mempolicy_slab_node(), flags);
-               for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) {
+               for_each_zone_zonelist(zone, z, zonelist, highest_zoneidx) {
                        struct kmem_cache_node *n;
 
                        n = get_node(s, zone_to_nid(zone));
@@ -1983,7 +2013,7 @@ static void *get_partial(struct kmem_cache *s, gfp_t flags, int node,
 
 #ifdef CONFIG_PREEMPTION
 /*
- * Calculate the next globally unique transaction for disambiguiation
+ * Calculate the next globally unique transaction for disambiguation
  * during cmpxchg. The transactions start with the cpu number and are then
  * incremented by CONFIG_NR_CPUS.
  */
@@ -2082,6 +2112,14 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page,
                void *prior;
                unsigned long counters;
 
+               /*
+                * If 'nextfree' is invalid, it is possible that the object at
+                * 'freelist' is already corrupted.  So isolate all objects
+                * starting at 'freelist'.
+                */
+               if (freelist_corrupted(s, page, freelist, nextfree))
+                       break;
+
                do {
                        prior = page->freelist;
                        counters = page->counters;
@@ -2205,11 +2243,11 @@ static void unfreeze_partials(struct kmem_cache *s,
        struct kmem_cache_node *n = NULL, *n2 = NULL;
        struct page *page, *discard_page = NULL;
 
-       while ((page = c->partial)) {
+       while ((page = slub_percpu_partial(c))) {
                struct page new;
                struct page old;
 
-               c->partial = page->next;
+               slub_set_percpu_partial(c, page);
 
                n2 = get_node(s, page_to_nid(page));
                if (n != n2) {
@@ -2282,7 +2320,7 @@ static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
                if (oldpage) {
                        pobjects = oldpage->pobjects;
                        pages = oldpage->pages;
-                       if (drain && pobjects > s->cpu_partial) {
+                       if (drain && pobjects > slub_cpu_partial(s)) {
                                unsigned long flags;
                                /*
                                 * partial array is full. Move the existing
@@ -2307,7 +2345,7 @@ static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
 
        } while (this_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page)
                                                                != oldpage);
-       if (unlikely(!s->cpu_partial)) {
+       if (unlikely(!slub_cpu_partial(s))) {
                unsigned long flags;
 
                local_irq_save(flags);
@@ -3512,15 +3550,15 @@ static void set_cpu_partial(struct kmem_cache *s)
         *    50% to keep some capacity around for frees.
         */
        if (!kmem_cache_has_cpu_partial(s))
-               s->cpu_partial = 0;
+               slub_set_cpu_partial(s, 0);
        else if (s->size >= PAGE_SIZE)
-               s->cpu_partial = 2;
+               slub_set_cpu_partial(s, 2);
        else if (s->size >= 1024)
-               s->cpu_partial = 6;
+               slub_set_cpu_partial(s, 6);
        else if (s->size >= 256)
-               s->cpu_partial = 13;
+               slub_set_cpu_partial(s, 13);
        else
-               s->cpu_partial = 30;
+               slub_set_cpu_partial(s, 30);
 #endif
 }
 
@@ -3532,6 +3570,7 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
 {
        slab_flags_t flags = s->flags;
        unsigned int size = s->object_size;
+       unsigned int freepointer_area;
        unsigned int order;
 
        /*
@@ -3540,6 +3579,13 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
         * the possible location of the free pointer.
         */
        size = ALIGN(size, sizeof(void *));
+       /*
+        * This is the area of the object where a freepointer can be
+        * safely written. If redzoning adds more to the inuse size, we
+        * can't use that portion for writing the freepointer, so
+        * s->offset must be limited within this for the general case.
+        */
+       freepointer_area = size;
 
 #ifdef CONFIG_SLUB_DEBUG
        /*
@@ -3578,9 +3624,21 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
                 *
                 * This is the case if we do RCU, have a constructor or
                 * destructor or are poisoning the objects.
+                *
+                * The assumption that s->offset >= s->inuse means free
+                * pointer is outside of the object is used in the
+                * freeptr_outside_object() function. If that is no
+                * longer true, the function needs to be modified.
                 */
                s->offset = size;
                size += sizeof(void *);
+       } else if (freepointer_area > sizeof(void *)) {
+               /*
+                * Store freelist pointer near middle of object to keep
+                * it away from the edges of the object to avoid small
+                * sized over/underflows from neighboring allocations.
+                */
+               s->offset = ALIGN(freepointer_area / 2, sizeof(void *));
        }
 
 #ifdef CONFIG_SLUB_DEBUG
@@ -3708,12 +3766,14 @@ error:
 }
 
 static void list_slab_objects(struct kmem_cache *s, struct page *page,
-                                                       const char *text)
+                             const char *text, unsigned long *map)
 {
 #ifdef CONFIG_SLUB_DEBUG
        void *addr = page_address(page);
        void *p;
-       unsigned long *map;
+
+       if (!map)
+               return;
 
        slab_err(s, page, text, s->name);
        slab_lock(page);
@@ -3726,8 +3786,6 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page,
                        print_tracking(s, p);
                }
        }
-       put_map(map);
-
        slab_unlock(page);
 #endif
 }
@@ -3741,6 +3799,11 @@ static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)
 {
        LIST_HEAD(discard);
        struct page *page, *h;
+       unsigned long *map = NULL;
+
+#ifdef CONFIG_SLUB_DEBUG
+       map = bitmap_alloc(oo_objects(s->max), GFP_KERNEL);
+#endif
 
        BUG_ON(irqs_disabled());
        spin_lock_irq(&n->list_lock);
@@ -3750,11 +3813,16 @@ static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)
                        list_add(&page->slab_list, &discard);
                } else {
                        list_slab_objects(s, page,
-                       "Objects remaining in %s on __kmem_cache_shutdown()");
+                         "Objects remaining in %s on __kmem_cache_shutdown()",
+                         map);
                }
        }
        spin_unlock_irq(&n->list_lock);
 
+#ifdef CONFIG_SLUB_DEBUG
+       bitmap_free(map);
+#endif
+
        list_for_each_entry_safe(page, h, &discard, slab_list)
                discard_slab(s, page);
 }
@@ -4377,6 +4445,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
 
        return ret;
 }
+EXPORT_SYMBOL(__kmalloc_track_caller);
 
 #ifdef CONFIG_NUMA
 void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
@@ -4407,6 +4476,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
 
        return ret;
 }
+EXPORT_SYMBOL(__kmalloc_node_track_caller);
 #endif
 
 #ifdef CONFIG_SYSFS
@@ -5623,7 +5693,8 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s)
                 */
                if (buffer)
                        buf = buffer;
-               else if (root_cache->max_attr_size < ARRAY_SIZE(mbuf))
+               else if (root_cache->max_attr_size < ARRAY_SIZE(mbuf) &&
+                        !IS_ENABLED(CONFIG_SLUB_STATS))
                        buf = mbuf;
                else {
                        buffer = (char *) get_zeroed_page(GFP_KERNEL);
@@ -5657,19 +5728,6 @@ static struct kobj_type slab_ktype = {
        .release = kmem_cache_release,
 };
 
-static int uevent_filter(struct kset *kset, struct kobject *kobj)
-{
-       struct kobj_type *ktype = get_ktype(kobj);
-
-       if (ktype == &slab_ktype)
-               return 1;
-       return 0;
-}
-
-static const struct kset_uevent_ops slab_uevent_ops = {
-       .filter = uevent_filter,
-};
-
 static struct kset *slab_kset;
 
 static inline struct kset *cache_kset(struct kmem_cache *s)
@@ -5737,7 +5795,6 @@ static void sysfs_slab_remove_workfn(struct work_struct *work)
 #ifdef CONFIG_MEMCG
        kset_unregister(s->memcg_kset);
 #endif
-       kobject_uevent(&s->kobj, KOBJ_REMOVE);
 out:
        kobject_put(&s->kobj);
 }
@@ -5778,8 +5835,10 @@ static int sysfs_slab_add(struct kmem_cache *s)
 
        s->kobj.kset = kset;
        err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name);
-       if (err)
+       if (err) {
+               kobject_put(&s->kobj);
                goto out;
+       }
 
        err = sysfs_create_group(&s->kobj, &slab_attr_group);
        if (err)
@@ -5795,7 +5854,6 @@ static int sysfs_slab_add(struct kmem_cache *s)
        }
 #endif
 
-       kobject_uevent(&s->kobj, KOBJ_ADD);
        if (!unmergeable) {
                /* Setup first alias */
                sysfs_slab_alias(s, s->name);
@@ -5876,7 +5934,7 @@ static int __init slab_sysfs_init(void)
 
        mutex_lock(&slab_mutex);
 
-       slab_kset = kset_create_and_add("slab", &slab_uevent_ops, kernel_kobj);
+       slab_kset = kset_create_and_add("slab", NULL, kernel_kobj);
        if (!slab_kset) {
                mutex_unlock(&slab_mutex);
                pr_err("Cannot register slab subsystem.\n");