[PATCH v3] debugobjects: call debug_objects_mem_init eariler

From: Qian Cai
Date: Mon Nov 26 2018 - 05:24:45 EST


The current value of the early boot static pool size, 1024 is not big
enough for systems with large number of CPUs with timer or/and workqueue
objects selected. As the results, systems have 60+ CPUs with both timer
and workqueue objects enabled could trigger "ODEBUG: Out of memory.
ODEBUG disabled".

Some debug objects are allocated during the early boot. Enabling some
options like timers or workqueue objects may increase the size required
significantly with large number of CPUs. For example,

CONFIG_DEBUG_OBJECTS_TIMERS:
No. CPUs x 2 (worker pool) objects:
start_kernel
workqueue_init_early
init_worker_pool
init_timer_key
debug_object_init

plus No. CPUs objects (CONFIG_HIGH_RES_TIMERS):
sched_init
hrtick_rq_init
hrtimer_init

CONFIG_DEBUG_OBJECTS_WORK:
No. CPUs objects:
vmalloc_init
__init_work

plus No. CPUs x 6 (workqueue) objects:
workqueue_init_early
alloc_workqueue
__alloc_workqueue_key
alloc_and_link_pwqs
init_pwq

Also, plus No. CPUs objects:
perf_event_init
__init_srcu_struct
init_srcu_struct_fields
init_srcu_struct_nodes
__init_work

However, none of the things are actually used or required before
debug_objects_mem_init() is invoked, so just move the call right
before vmalloc_init().

According to tglx,
"the reason why the call is at this place in start_kernel() is
historical. It's because back in the days when debugobjects were added
the memory allocator was enabled way later than today."

Suggested-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Signed-off-by: Qian Cai <cai@xxxxxx>
---

Changes since v2:
* Restored an accidentally deleted comment.

since v1:
* Added some comments about interrupts.

init/main.c | 2 +-
lib/debugobjects.c | 8 +++-----
2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/init/main.c b/init/main.c
index ee147103ba1b..2b7b7fe173c9 100644
--- a/init/main.c
+++ b/init/main.c
@@ -521,6 +521,7 @@ static void __init mm_init(void)
mem_init();
kmem_cache_init();
pgtable_init();
+ debug_objects_mem_init();
vmalloc_init();
ioremap_huge_init();
/* Should be run before the first non-init thread is created */
@@ -697,7 +698,6 @@ asmlinkage __visible void __init start_kernel(void)
#endif
page_ext_init();
kmemleak_init();
- debug_objects_mem_init();
setup_per_cpu_pageset();
numa_policy_init();
acpi_early_init();
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 70935ed91125..eab7727b46ed 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -1133,11 +1133,10 @@ static int __init debug_objects_replace_static_objects(void)
}

/*
- * When debug_objects_mem_init() is called we know that only
- * one CPU is up, so disabling interrupts is enough
- * protection. This avoids the lockdep hell of lock ordering.
+ * debug_objects_mem_init() is now called early that only one CPU is up
+ * and interrupts have been disabled, so it is safe to replace the
+ * active object references.
*/
- local_irq_disable();

/* Remove the statically allocated objects from the pool */
hlist_for_each_entry_safe(obj, tmp, &obj_pool, node)
@@ -1158,7 +1157,6 @@ static int __init debug_objects_replace_static_objects(void)
cnt++;
}
}
- local_irq_enable();

pr_debug("%d of %d active objects replaced\n",
cnt, obj_pool_used);
--
2.17.2 (Apple Git-113)