summaryrefslogtreecommitdiffstats
path: root/lib/debugobjects.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/debugobjects.c')
-rw-r--r--lib/debugobjects.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 7ea19fa63561..ede96c659552 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -32,6 +32,14 @@
32#define ODEBUG_CHUNK_SIZE (1 << ODEBUG_CHUNK_SHIFT) 32#define ODEBUG_CHUNK_SIZE (1 << ODEBUG_CHUNK_SHIFT)
33#define ODEBUG_CHUNK_MASK (~(ODEBUG_CHUNK_SIZE - 1)) 33#define ODEBUG_CHUNK_MASK (~(ODEBUG_CHUNK_SIZE - 1))
34 34
35/*
36 * We limit the freeing of debug objects via workqueue at a maximum
37 * frequency of 10Hz and about 1024 objects for each freeing operation.
38 * So it is freeing at most 10k debug objects per second.
39 */
40#define ODEBUG_FREE_WORK_MAX 1024
41#define ODEBUG_FREE_WORK_DELAY DIV_ROUND_UP(HZ, 10)
42
35struct debug_bucket { 43struct debug_bucket {
36 struct hlist_head list; 44 struct hlist_head list;
37 raw_spinlock_t lock; 45 raw_spinlock_t lock;
@@ -68,6 +76,7 @@ static int obj_pool_min_free = ODEBUG_POOL_SIZE;
68static int obj_pool_free = ODEBUG_POOL_SIZE; 76static int obj_pool_free = ODEBUG_POOL_SIZE;
69static int obj_pool_used; 77static int obj_pool_used;
70static int obj_pool_max_used; 78static int obj_pool_max_used;
79static bool obj_freeing;
71/* The number of objs on the global free list */ 80/* The number of objs on the global free list */
72static int obj_nr_tofree; 81static int obj_nr_tofree;
73 82
@@ -91,7 +100,7 @@ static int debug_objects_allocated;
91static int debug_objects_freed; 100static int debug_objects_freed;
92 101
93static void free_obj_work(struct work_struct *work); 102static void free_obj_work(struct work_struct *work);
94static DECLARE_WORK(debug_obj_work, free_obj_work); 103static DECLARE_DELAYED_WORK(debug_obj_work, free_obj_work);
95 104
96static int __init enable_object_debug(char *str) 105static int __init enable_object_debug(char *str)
97{ 106{
@@ -282,13 +291,19 @@ static void free_obj_work(struct work_struct *work)
282 unsigned long flags; 291 unsigned long flags;
283 HLIST_HEAD(tofree); 292 HLIST_HEAD(tofree);
284 293
294 WRITE_ONCE(obj_freeing, false);
285 if (!raw_spin_trylock_irqsave(&pool_lock, flags)) 295 if (!raw_spin_trylock_irqsave(&pool_lock, flags))
286 return; 296 return;
287 297
298 if (obj_pool_free >= debug_objects_pool_size)
299 goto free_objs;
300
288 /* 301 /*
289 * The objs on the pool list might be allocated before the work is 302 * The objs on the pool list might be allocated before the work is
290 * run, so recheck if pool list it full or not, if not fill pool 303 * run, so recheck if pool list it full or not, if not fill pool
291 * list from the global free list. 304 * list from the global free list. As it is likely that a workload
305 * may be gearing up to use more and more objects, don't free any
306 * of them until the next round.
292 */ 307 */
293 while (obj_nr_tofree && obj_pool_free < debug_objects_pool_size) { 308 while (obj_nr_tofree && obj_pool_free < debug_objects_pool_size) {
294 obj = hlist_entry(obj_to_free.first, typeof(*obj), node); 309 obj = hlist_entry(obj_to_free.first, typeof(*obj), node);
@@ -297,7 +312,10 @@ static void free_obj_work(struct work_struct *work)
297 obj_pool_free++; 312 obj_pool_free++;
298 obj_nr_tofree--; 313 obj_nr_tofree--;
299 } 314 }
315 raw_spin_unlock_irqrestore(&pool_lock, flags);
316 return;
300 317
318free_objs:
301 /* 319 /*
302 * Pool list is already full and there are still objs on the free 320 * Pool list is already full and there are still objs on the free
303 * list. Move remaining free objs to a temporary list to free the 321 * list. Move remaining free objs to a temporary list to free the
@@ -316,7 +334,7 @@ static void free_obj_work(struct work_struct *work)
316 } 334 }
317} 335}
318 336
319static bool __free_object(struct debug_obj *obj) 337static void __free_object(struct debug_obj *obj)
320{ 338{
321 struct debug_obj *objs[ODEBUG_BATCH_SIZE]; 339 struct debug_obj *objs[ODEBUG_BATCH_SIZE];
322 struct debug_percpu_free *percpu_pool; 340 struct debug_percpu_free *percpu_pool;
@@ -336,7 +354,7 @@ static bool __free_object(struct debug_obj *obj)
336 hlist_add_head(&obj->node, &percpu_pool->free_objs); 354 hlist_add_head(&obj->node, &percpu_pool->free_objs);
337 percpu_pool->obj_free++; 355 percpu_pool->obj_free++;
338 local_irq_restore(flags); 356 local_irq_restore(flags);
339 return false; 357 return;
340 } 358 }
341 359
342 /* 360 /*
@@ -352,7 +370,8 @@ static bool __free_object(struct debug_obj *obj)
352 370
353free_to_obj_pool: 371free_to_obj_pool:
354 raw_spin_lock(&pool_lock); 372 raw_spin_lock(&pool_lock);
355 work = (obj_pool_free > debug_objects_pool_size) && obj_cache; 373 work = (obj_pool_free > debug_objects_pool_size) && obj_cache &&
374 (obj_nr_tofree < ODEBUG_FREE_WORK_MAX);
356 obj_pool_used--; 375 obj_pool_used--;
357 376
358 if (work) { 377 if (work) {
@@ -366,6 +385,21 @@ free_to_obj_pool:
366 &obj_to_free); 385 &obj_to_free);
367 } 386 }
368 } 387 }
388
389 if ((obj_pool_free > debug_objects_pool_size) &&
390 (obj_nr_tofree < ODEBUG_FREE_WORK_MAX)) {
391 int i;
392
393 /*
394 * Free one more batch of objects from obj_pool.
395 */
396 for (i = 0; i < ODEBUG_BATCH_SIZE; i++) {
397 obj = __alloc_object(&obj_pool);
398 hlist_add_head(&obj->node, &obj_to_free);
399 obj_pool_free--;
400 obj_nr_tofree++;
401 }
402 }
369 } else { 403 } else {
370 obj_pool_free++; 404 obj_pool_free++;
371 hlist_add_head(&obj->node, &obj_pool); 405 hlist_add_head(&obj->node, &obj_pool);
@@ -380,7 +414,6 @@ free_to_obj_pool:
380 } 414 }
381 raw_spin_unlock(&pool_lock); 415 raw_spin_unlock(&pool_lock);
382 local_irq_restore(flags); 416 local_irq_restore(flags);
383 return work;
384} 417}
385 418
386/* 419/*
@@ -389,8 +422,11 @@ free_to_obj_pool:
389 */ 422 */
390static void free_object(struct debug_obj *obj) 423static void free_object(struct debug_obj *obj)
391{ 424{
392 if (__free_object(obj)) 425 __free_object(obj);
393 schedule_work(&debug_obj_work); 426 if (!obj_freeing && obj_nr_tofree) {
427 WRITE_ONCE(obj_freeing, true);
428 schedule_delayed_work(&debug_obj_work, ODEBUG_FREE_WORK_DELAY);
429 }
394} 430}
395 431
396/* 432/*
@@ -880,7 +916,6 @@ static void __debug_check_no_obj_freed(const void *address, unsigned long size)
880 struct hlist_node *tmp; 916 struct hlist_node *tmp;
881 struct debug_obj *obj; 917 struct debug_obj *obj;
882 int cnt, objs_checked = 0; 918 int cnt, objs_checked = 0;
883 bool work = false;
884 919
885 saddr = (unsigned long) address; 920 saddr = (unsigned long) address;
886 eaddr = saddr + size; 921 eaddr = saddr + size;
@@ -911,7 +946,7 @@ repeat:
911 goto repeat; 946 goto repeat;
912 default: 947 default:
913 hlist_del(&obj->node); 948 hlist_del(&obj->node);
914 work |= __free_object(obj); 949 __free_object(obj);
915 break; 950 break;
916 } 951 }
917 } 952 }
@@ -927,8 +962,10 @@ repeat:
927 debug_objects_maxchecked = objs_checked; 962 debug_objects_maxchecked = objs_checked;
928 963
929 /* Schedule work to actually kmem_cache_free() objects */ 964 /* Schedule work to actually kmem_cache_free() objects */
930 if (work) 965 if (!obj_freeing && obj_nr_tofree) {
931 schedule_work(&debug_obj_work); 966 WRITE_ONCE(obj_freeing, true);
967 schedule_delayed_work(&debug_obj_work, ODEBUG_FREE_WORK_DELAY);
968 }
932} 969}
933 970
934void debug_check_no_obj_freed(const void *address, unsigned long size) 971void debug_check_no_obj_freed(const void *address, unsigned long size)