From eabb7f1ace53e127309407b2b5e74e8199e85270 Mon Sep 17 00:00:00 2001 From: wuchi Date: Sat, 11 Jun 2022 21:06:34 +0800 Subject: lib/debugobjects: fix stat count and optimize debug_objects_mem_init 1. Var debug_objects_allocated tracks valid kmem_cache_alloc calls, so track it in debug_objects_replace_static_objects. Do similar things in object_cpu_offline. 2. In debug_objects_mem_init, there is no need to call function cpuhp_setup_state_nocalls when debug_objects_enabled = 0 (out of memory). Link: https://lkml.kernel.org/r/20220611130634.99741-1-wuchi.zero@gmail.com Fixes: 634d61f45d6f ("debugobjects: Percpu pool lookahead freeing/allocation") Fixes: c4b73aabd098 ("debugobjects: Track number of kmem_cache_alloc/kmem_cache_free done") Signed-off-by: wuchi Reviewed-by: Waiman Long Cc: Thomas Gleixner Cc: Christoph Hellwig Cc: Kees Cook Signed-off-by: Andrew Morton --- lib/debugobjects.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib/debugobjects.c') diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 337d797a7141..6f8e5dd1dcd0 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -437,6 +437,7 @@ static int object_cpu_offline(unsigned int cpu) struct debug_percpu_free *percpu_pool; struct hlist_node *tmp; struct debug_obj *obj; + unsigned long flags; /* Remote access is safe as the CPU is dead already */ percpu_pool = per_cpu_ptr(&percpu_obj_pool, cpu); @@ -444,6 +445,12 @@ static int object_cpu_offline(unsigned int cpu) hlist_del(&obj->node); kmem_cache_free(obj_cache, obj); } + + raw_spin_lock_irqsave(&pool_lock, flags); + obj_pool_used -= percpu_pool->obj_free; + debug_objects_freed += percpu_pool->obj_free; + raw_spin_unlock_irqrestore(&pool_lock, flags); + percpu_pool->obj_free = 0; return 0; @@ -1318,6 +1325,8 @@ static int __init debug_objects_replace_static_objects(void) hlist_add_head(&obj->node, &objects); } + debug_objects_allocated += i; + /* * 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 @@ -1386,6 +1395,7 @@ void __init debug_objects_mem_init(void) debug_objects_enabled = 0; kmem_cache_destroy(obj_cache); pr_warn("out of memory.\n"); + return; } else debug_objects_selftest(); -- cgit v1.2.3 From c4db2d3b70e586c7c856c891f4f7052e8d789a06 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 19 May 2022 13:22:01 -0700 Subject: debugobjects: Print object pointer in debug_print_object() Delayed kobject debugging (CONFIG_DEBUG_KOBJECT_RELEASE) prints the kobject pointer that's being released in kobject_release() before scheduling a randomly delayed work to do the actual release work. If the caller of kobject_put() frees the kobject upon return then this will typically emit a debugobject warning about freeing an active timer. Usually the release function is the function that does the kfree() of the struct containing the kobject. For example the following print is seen kobject: 'queue' (ffff888114236190): kobject_release, parent 0000000000000000 (delayed 1000) ------------[ cut here ]------------ ODEBUG: free active (active state 0) object type: timer_list hint: kobject_delayed_cleanup+0x0/0x390 but the kobject printk cannot be matched with the debug object printk because it could be any number of kobjects that was released around that time. The random delay for the work doesn't help either. Print the address of the object being tracked to help to figure out which kobject is the problem here. Note that this does not use %px here to match the other %p usage in debugobject debugging. Due to %p usage it is required to disable pointer hashing to correlate the two pointer printks. Signed-off-by: Stephen Boyd Signed-off-by: Thomas Gleixner Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20220519202201.2348343-1-swboyd@chromium.org --- lib/debugobjects.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/debugobjects.c') diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 337d797a7141..4c670d3b6965 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -500,9 +500,9 @@ static void debug_print_object(struct debug_obj *obj, char *msg) descr->debug_hint(obj->object) : NULL; limit++; WARN(1, KERN_ERR "ODEBUG: %s %s (active state %u) " - "object type: %s hint: %pS\n", + "object: %p object type: %s hint: %pS\n", msg, obj_states[obj->state], obj->astate, - descr->name, hint); + obj->object, descr->name, hint); } debug_objects_warnings++; } -- cgit v1.2.3