Merge tag 'for-linux-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
[linux-2.6-microblaze.git] / mm / slub.c
index 69742ab..f5baf42 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3423,6 +3423,7 @@ static inline int calculate_order(unsigned int size)
        unsigned int order;
        unsigned int min_objects;
        unsigned int max_objects;
+       unsigned int nr_cpus;
 
        /*
         * Attempt to find best configuration for a slab. This
@@ -3433,8 +3434,21 @@ static inline int calculate_order(unsigned int size)
         * we reduce the minimum objects required in a slab.
         */
        min_objects = slub_min_objects;
-       if (!min_objects)
-               min_objects = 4 * (fls(num_online_cpus()) + 1);
+       if (!min_objects) {
+               /*
+                * Some architectures will only update present cpus when
+                * onlining them, so don't trust the number if it's just 1. But
+                * we also don't want to use nr_cpu_ids always, as on some other
+                * architectures, there can be many possible cpus, but never
+                * onlined. Here we compromise between trying to avoid too high
+                * order on systems that appear larger than they are, and too
+                * low order on systems that appear smaller than they are.
+                */
+               nr_cpus = num_present_cpus();
+               if (nr_cpus <= 1)
+                       nr_cpus = nr_cpu_ids;
+               min_objects = 4 * (fls(nr_cpus) + 1);
+       }
        max_objects = order_objects(slub_max_order, size);
        min_objects = min(min_objects, max_objects);
 
@@ -3919,6 +3933,46 @@ int __kmem_cache_shutdown(struct kmem_cache *s)
        return 0;
 }
 
+void kmem_obj_info(struct kmem_obj_info *kpp, void *object, struct page *page)
+{
+       void *base;
+       int __maybe_unused i;
+       unsigned int objnr;
+       void *objp;
+       void *objp0;
+       struct kmem_cache *s = page->slab_cache;
+       struct track __maybe_unused *trackp;
+
+       kpp->kp_ptr = object;
+       kpp->kp_page = page;
+       kpp->kp_slab_cache = s;
+       base = page_address(page);
+       objp0 = kasan_reset_tag(object);
+#ifdef CONFIG_SLUB_DEBUG
+       objp = restore_red_left(s, objp0);
+#else
+       objp = objp0;
+#endif
+       objnr = obj_to_index(s, page, objp);
+       kpp->kp_data_offset = (unsigned long)((char *)objp0 - (char *)objp);
+       objp = base + s->size * objnr;
+       kpp->kp_objp = objp;
+       if (WARN_ON_ONCE(objp < base || objp >= base + page->objects * s->size || (objp - base) % s->size) ||
+           !(s->flags & SLAB_STORE_USER))
+               return;
+#ifdef CONFIG_SLUB_DEBUG
+       trackp = get_track(s, objp, TRACK_ALLOC);
+       kpp->kp_ret = (void *)trackp->addr;
+#ifdef CONFIG_STACKTRACE
+       for (i = 0; i < KS_ADDRS_COUNT && i < TRACK_ADDRS_COUNT; i++) {
+               kpp->kp_stack[i] = (void *)trackp->addrs[i];
+               if (!kpp->kp_stack[i])
+                       break;
+       }
+#endif
+#endif
+}
+
 /********************************************************************
  *             Kmalloc subsystem
  *******************************************************************/
@@ -5625,10 +5679,8 @@ 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) {
-               kobject_put(&s->kobj);
+       if (err)
                goto out;
-       }
 
        err = sysfs_create_group(&s->kobj, &slab_attr_group);
        if (err)