Freeing the per CPU pool of the unplugged CPU directly is suboptimal as the objects can be reused in the real pool if there is room. Aside of that this gets the accounting wrong. Use the regular free path, which allows reuse and has the accounting correct.
Showing the changes to lib/debugobjects.c (1 of 1 file). Show all
Unified · Split
| @@ -430,27 +430,28 @@ static void free_object(struct debug_obj *obj) · 429 unmodified lines | |||
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | #ifdef CONFIG_HOTPLUG_CPU | 432 | #ifdef CONFIG_HOTPLUG_CPU |
| 433 | static int object_cpu_offline(unsigned int cpu) | 433 | static void put_objects(struct hlist_head *list) |
| 434 | { | 434 | { |
| 435 | struct debug_percpu_free *percpu_pool; | ||
| 436 | struct hlist_node *tmp; | 435 | struct hlist_node *tmp; |
| 437 | struct debug_obj *obj; | 436 | struct debug_obj *obj; |
| 438 | unsigned long flags; | ||
| 439 | 437 | ||
| 440 | /* Remote access is safe as the CPU is dead already */ | 438 | /* |
| 441 | percpu_pool = per_cpu_ptr(&percpu_obj_pool, cpu); | 439 | * Using free_object() puts the objects into reuse or schedules |
| 442 | hlist_for_each_entry_safe(obj, tmp, &percpu_pool->free_objs, node) { | 440 | * them for freeing and it get's all the accounting correct. |
| 441 | */ | ||
| 442 | hlist_for_each_entry_safe(obj, tmp, list, node) { | ||
| 443 | hlist_del(&obj->node); | 443 | hlist_del(&obj->node); |
| 444 | kmem_cache_free(obj_cache, obj); | 444 | free_object(obj); |
| 445 | } | 445 | } |
| 446 | } | ||
| 446 | 447 | ||
| 447 | raw_spin_lock_irqsave(&pool_lock, flags); | 448 | static int object_cpu_offline(unsigned int cpu) |
| 448 | obj_pool_used -= percpu_pool->obj_free; | 449 | { |
| 449 | debug_objects_freed += percpu_pool->obj_free; | 450 | /* Remote access is safe as the CPU is dead already */ |
| 450 | raw_spin_unlock_irqrestore(&pool_lock, flags); | 451 | struct debug_percpu_free *pcp = per_cpu_ptr(&percpu_obj_pool, cpu); |
| 451 | |||
| 452 | percpu_pool->obj_free = 0; | ||
| 453 | 452 | ||
| 453 | put_objects(&pcp->free_objs); | ||
| 454 | pcp->obj_free = 0; | ||
| 454 | return 0; | 455 | return 0; |
| 455 | } | 456 | } |
| 456 | #endif | 457 | #endif |