aboutsummaryrefslogtreecommitdiffstats
path: root/lib/debugobjects.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/debugobjects.c')
-rw-r--r--lib/debugobjects.c75
1 files changed, 38 insertions, 37 deletions
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 2755a3bd16a1..a9a8996d286a 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -9,6 +9,7 @@
9 */ 9 */
10#include <linux/debugobjects.h> 10#include <linux/debugobjects.h>
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/sched.h>
12#include <linux/seq_file.h> 13#include <linux/seq_file.h>
13#include <linux/debugfs.h> 14#include <linux/debugfs.h>
14#include <linux/hash.h> 15#include <linux/hash.h>
@@ -25,14 +26,14 @@
25 26
26struct debug_bucket { 27struct debug_bucket {
27 struct hlist_head list; 28 struct hlist_head list;
28 spinlock_t lock; 29 raw_spinlock_t lock;
29}; 30};
30 31
31static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE]; 32static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE];
32 33
33static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE] __initdata; 34static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE] __initdata;
34 35
35static DEFINE_SPINLOCK(pool_lock); 36static DEFINE_RAW_SPINLOCK(pool_lock);
36 37
37static HLIST_HEAD(obj_pool); 38static HLIST_HEAD(obj_pool);
38 39
@@ -95,10 +96,10 @@ static int fill_pool(void)
95 if (!new) 96 if (!new)
96 return obj_pool_free; 97 return obj_pool_free;
97 98
98 spin_lock_irqsave(&pool_lock, flags); 99 raw_spin_lock_irqsave(&pool_lock, flags);
99 hlist_add_head(&new->node, &obj_pool); 100 hlist_add_head(&new->node, &obj_pool);
100 obj_pool_free++; 101 obj_pool_free++;
101 spin_unlock_irqrestore(&pool_lock, flags); 102 raw_spin_unlock_irqrestore(&pool_lock, flags);
102 } 103 }
103 return obj_pool_free; 104 return obj_pool_free;
104} 105}
@@ -132,7 +133,7 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
132{ 133{
133 struct debug_obj *obj = NULL; 134 struct debug_obj *obj = NULL;
134 135
135 spin_lock(&pool_lock); 136 raw_spin_lock(&pool_lock);
136 if (obj_pool.first) { 137 if (obj_pool.first) {
137 obj = hlist_entry(obj_pool.first, typeof(*obj), node); 138 obj = hlist_entry(obj_pool.first, typeof(*obj), node);
138 139
@@ -151,7 +152,7 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
151 if (obj_pool_free < obj_pool_min_free) 152 if (obj_pool_free < obj_pool_min_free)
152 obj_pool_min_free = obj_pool_free; 153 obj_pool_min_free = obj_pool_free;
153 } 154 }
154 spin_unlock(&pool_lock); 155 raw_spin_unlock(&pool_lock);
155 156
156 return obj; 157 return obj;
157} 158}
@@ -164,7 +165,7 @@ static void free_obj_work(struct work_struct *work)
164 struct debug_obj *obj; 165 struct debug_obj *obj;
165 unsigned long flags; 166 unsigned long flags;
166 167
167 spin_lock_irqsave(&pool_lock, flags); 168 raw_spin_lock_irqsave(&pool_lock, flags);
168 while (obj_pool_free > ODEBUG_POOL_SIZE) { 169 while (obj_pool_free > ODEBUG_POOL_SIZE) {
169 obj = hlist_entry(obj_pool.first, typeof(*obj), node); 170 obj = hlist_entry(obj_pool.first, typeof(*obj), node);
170 hlist_del(&obj->node); 171 hlist_del(&obj->node);
@@ -173,11 +174,11 @@ static void free_obj_work(struct work_struct *work)
173 * We release pool_lock across kmem_cache_free() to 174 * We release pool_lock across kmem_cache_free() to
174 * avoid contention on pool_lock. 175 * avoid contention on pool_lock.
175 */ 176 */
176 spin_unlock_irqrestore(&pool_lock, flags); 177 raw_spin_unlock_irqrestore(&pool_lock, flags);
177 kmem_cache_free(obj_cache, obj); 178 kmem_cache_free(obj_cache, obj);
178 spin_lock_irqsave(&pool_lock, flags); 179 raw_spin_lock_irqsave(&pool_lock, flags);
179 } 180 }
180 spin_unlock_irqrestore(&pool_lock, flags); 181 raw_spin_unlock_irqrestore(&pool_lock, flags);
181} 182}
182 183
183/* 184/*
@@ -189,7 +190,7 @@ static void free_object(struct debug_obj *obj)
189 unsigned long flags; 190 unsigned long flags;
190 int sched = 0; 191 int sched = 0;
191 192
192 spin_lock_irqsave(&pool_lock, flags); 193 raw_spin_lock_irqsave(&pool_lock, flags);
193 /* 194 /*
194 * schedule work when the pool is filled and the cache is 195 * schedule work when the pool is filled and the cache is
195 * initialized: 196 * initialized:
@@ -199,7 +200,7 @@ static void free_object(struct debug_obj *obj)
199 hlist_add_head(&obj->node, &obj_pool); 200 hlist_add_head(&obj->node, &obj_pool);
200 obj_pool_free++; 201 obj_pool_free++;
201 obj_pool_used--; 202 obj_pool_used--;
202 spin_unlock_irqrestore(&pool_lock, flags); 203 raw_spin_unlock_irqrestore(&pool_lock, flags);
203 if (sched) 204 if (sched)
204 schedule_work(&debug_obj_work); 205 schedule_work(&debug_obj_work);
205} 206}
@@ -220,9 +221,9 @@ static void debug_objects_oom(void)
220 printk(KERN_WARNING "ODEBUG: Out of memory. ODEBUG disabled\n"); 221 printk(KERN_WARNING "ODEBUG: Out of memory. ODEBUG disabled\n");
221 222
222 for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) { 223 for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) {
223 spin_lock_irqsave(&db->lock, flags); 224 raw_spin_lock_irqsave(&db->lock, flags);
224 hlist_move_list(&db->list, &freelist); 225 hlist_move_list(&db->list, &freelist);
225 spin_unlock_irqrestore(&db->lock, flags); 226 raw_spin_unlock_irqrestore(&db->lock, flags);
226 227
227 /* Now free them */ 228 /* Now free them */
228 hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) { 229 hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) {
@@ -302,14 +303,14 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack)
302 303
303 db = get_bucket((unsigned long) addr); 304 db = get_bucket((unsigned long) addr);
304 305
305 spin_lock_irqsave(&db->lock, flags); 306 raw_spin_lock_irqsave(&db->lock, flags);
306 307
307 obj = lookup_object(addr, db); 308 obj = lookup_object(addr, db);
308 if (!obj) { 309 if (!obj) {
309 obj = alloc_object(addr, db, descr); 310 obj = alloc_object(addr, db, descr);
310 if (!obj) { 311 if (!obj) {
311 debug_objects_enabled = 0; 312 debug_objects_enabled = 0;
312 spin_unlock_irqrestore(&db->lock, flags); 313 raw_spin_unlock_irqrestore(&db->lock, flags);
313 debug_objects_oom(); 314 debug_objects_oom();
314 return; 315 return;
315 } 316 }
@@ -326,7 +327,7 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack)
326 case ODEBUG_STATE_ACTIVE: 327 case ODEBUG_STATE_ACTIVE:
327 debug_print_object(obj, "init"); 328 debug_print_object(obj, "init");
328 state = obj->state; 329 state = obj->state;
329 spin_unlock_irqrestore(&db->lock, flags); 330 raw_spin_unlock_irqrestore(&db->lock, flags);
330 debug_object_fixup(descr->fixup_init, addr, state); 331 debug_object_fixup(descr->fixup_init, addr, state);
331 return; 332 return;
332 333
@@ -337,7 +338,7 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack)
337 break; 338 break;
338 } 339 }
339 340
340 spin_unlock_irqrestore(&db->lock, flags); 341 raw_spin_unlock_irqrestore(&db->lock, flags);
341} 342}
342 343
343/** 344/**
@@ -384,7 +385,7 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr)
384 385
385 db = get_bucket((unsigned long) addr); 386 db = get_bucket((unsigned long) addr);
386 387
387 spin_lock_irqsave(&db->lock, flags); 388 raw_spin_lock_irqsave(&db->lock, flags);
388 389
389 obj = lookup_object(addr, db); 390 obj = lookup_object(addr, db);
390 if (obj) { 391 if (obj) {
@@ -397,7 +398,7 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr)
397 case ODEBUG_STATE_ACTIVE: 398 case ODEBUG_STATE_ACTIVE:
398 debug_print_object(obj, "activate"); 399 debug_print_object(obj, "activate");
399 state = obj->state; 400 state = obj->state;
400 spin_unlock_irqrestore(&db->lock, flags); 401 raw_spin_unlock_irqrestore(&db->lock, flags);
401 debug_object_fixup(descr->fixup_activate, addr, state); 402 debug_object_fixup(descr->fixup_activate, addr, state);
402 return; 403 return;
403 404
@@ -407,11 +408,11 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr)
407 default: 408 default:
408 break; 409 break;
409 } 410 }
410 spin_unlock_irqrestore(&db->lock, flags); 411 raw_spin_unlock_irqrestore(&db->lock, flags);
411 return; 412 return;
412 } 413 }
413 414
414 spin_unlock_irqrestore(&db->lock, flags); 415 raw_spin_unlock_irqrestore(&db->lock, flags);
415 /* 416 /*
416 * This happens when a static object is activated. We 417 * This happens when a static object is activated. We
417 * let the type specific code decide whether this is 418 * let the type specific code decide whether this is
@@ -437,7 +438,7 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr)
437 438
438 db = get_bucket((unsigned long) addr); 439 db = get_bucket((unsigned long) addr);
439 440
440 spin_lock_irqsave(&db->lock, flags); 441 raw_spin_lock_irqsave(&db->lock, flags);
441 442
442 obj = lookup_object(addr, db); 443 obj = lookup_object(addr, db);
443 if (obj) { 444 if (obj) {
@@ -462,7 +463,7 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr)
462 debug_print_object(&o, "deactivate"); 463 debug_print_object(&o, "deactivate");
463 } 464 }
464 465
465 spin_unlock_irqrestore(&db->lock, flags); 466 raw_spin_unlock_irqrestore(&db->lock, flags);
466} 467}
467 468
468/** 469/**
@@ -482,7 +483,7 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr)
482 483
483 db = get_bucket((unsigned long) addr); 484 db = get_bucket((unsigned long) addr);
484 485
485 spin_lock_irqsave(&db->lock, flags); 486 raw_spin_lock_irqsave(&db->lock, flags);
486 487
487 obj = lookup_object(addr, db); 488 obj = lookup_object(addr, db);
488 if (!obj) 489 if (!obj)
@@ -497,7 +498,7 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr)
497 case ODEBUG_STATE_ACTIVE: 498 case ODEBUG_STATE_ACTIVE:
498 debug_print_object(obj, "destroy"); 499 debug_print_object(obj, "destroy");
499 state = obj->state; 500 state = obj->state;
500 spin_unlock_irqrestore(&db->lock, flags); 501 raw_spin_unlock_irqrestore(&db->lock, flags);
501 debug_object_fixup(descr->fixup_destroy, addr, state); 502 debug_object_fixup(descr->fixup_destroy, addr, state);
502 return; 503 return;
503 504
@@ -508,7 +509,7 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr)
508 break; 509 break;
509 } 510 }
510out_unlock: 511out_unlock:
511 spin_unlock_irqrestore(&db->lock, flags); 512 raw_spin_unlock_irqrestore(&db->lock, flags);
512} 513}
513 514
514/** 515/**
@@ -528,7 +529,7 @@ void debug_object_free(void *addr, struct debug_obj_descr *descr)
528 529
529 db = get_bucket((unsigned long) addr); 530 db = get_bucket((unsigned long) addr);
530 531
531 spin_lock_irqsave(&db->lock, flags); 532 raw_spin_lock_irqsave(&db->lock, flags);
532 533
533 obj = lookup_object(addr, db); 534 obj = lookup_object(addr, db);
534 if (!obj) 535 if (!obj)
@@ -538,17 +539,17 @@ void debug_object_free(void *addr, struct debug_obj_descr *descr)
538 case ODEBUG_STATE_ACTIVE: 539 case ODEBUG_STATE_ACTIVE:
539 debug_print_object(obj, "free"); 540 debug_print_object(obj, "free");
540 state = obj->state; 541 state = obj->state;
541 spin_unlock_irqrestore(&db->lock, flags); 542 raw_spin_unlock_irqrestore(&db->lock, flags);
542 debug_object_fixup(descr->fixup_free, addr, state); 543 debug_object_fixup(descr->fixup_free, addr, state);
543 return; 544 return;
544 default: 545 default:
545 hlist_del(&obj->node); 546 hlist_del(&obj->node);
546 spin_unlock_irqrestore(&db->lock, flags); 547 raw_spin_unlock_irqrestore(&db->lock, flags);
547 free_object(obj); 548 free_object(obj);
548 return; 549 return;
549 } 550 }
550out_unlock: 551out_unlock:
551 spin_unlock_irqrestore(&db->lock, flags); 552 raw_spin_unlock_irqrestore(&db->lock, flags);
552} 553}
553 554
554#ifdef CONFIG_DEBUG_OBJECTS_FREE 555#ifdef CONFIG_DEBUG_OBJECTS_FREE
@@ -574,7 +575,7 @@ static void __debug_check_no_obj_freed(const void *address, unsigned long size)
574 575
575repeat: 576repeat:
576 cnt = 0; 577 cnt = 0;
577 spin_lock_irqsave(&db->lock, flags); 578 raw_spin_lock_irqsave(&db->lock, flags);
578 hlist_for_each_entry_safe(obj, node, tmp, &db->list, node) { 579 hlist_for_each_entry_safe(obj, node, tmp, &db->list, node) {
579 cnt++; 580 cnt++;
580 oaddr = (unsigned long) obj->object; 581 oaddr = (unsigned long) obj->object;
@@ -586,7 +587,7 @@ repeat:
586 debug_print_object(obj, "free"); 587 debug_print_object(obj, "free");
587 descr = obj->descr; 588 descr = obj->descr;
588 state = obj->state; 589 state = obj->state;
589 spin_unlock_irqrestore(&db->lock, flags); 590 raw_spin_unlock_irqrestore(&db->lock, flags);
590 debug_object_fixup(descr->fixup_free, 591 debug_object_fixup(descr->fixup_free,
591 (void *) oaddr, state); 592 (void *) oaddr, state);
592 goto repeat; 593 goto repeat;
@@ -596,7 +597,7 @@ repeat:
596 break; 597 break;
597 } 598 }
598 } 599 }
599 spin_unlock_irqrestore(&db->lock, flags); 600 raw_spin_unlock_irqrestore(&db->lock, flags);
600 601
601 /* Now free them */ 602 /* Now free them */
602 hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) { 603 hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) {
@@ -782,7 +783,7 @@ check_results(void *addr, enum debug_obj_state state, int fixups, int warnings)
782 783
783 db = get_bucket((unsigned long) addr); 784 db = get_bucket((unsigned long) addr);
784 785
785 spin_lock_irqsave(&db->lock, flags); 786 raw_spin_lock_irqsave(&db->lock, flags);
786 787
787 obj = lookup_object(addr, db); 788 obj = lookup_object(addr, db);
788 if (!obj && state != ODEBUG_STATE_NONE) { 789 if (!obj && state != ODEBUG_STATE_NONE) {
@@ -806,7 +807,7 @@ check_results(void *addr, enum debug_obj_state state, int fixups, int warnings)
806 } 807 }
807 res = 0; 808 res = 0;
808out: 809out:
809 spin_unlock_irqrestore(&db->lock, flags); 810 raw_spin_unlock_irqrestore(&db->lock, flags);
810 if (res) 811 if (res)
811 debug_objects_enabled = 0; 812 debug_objects_enabled = 0;
812 return res; 813 return res;
@@ -906,7 +907,7 @@ void __init debug_objects_early_init(void)
906 int i; 907 int i;
907 908
908 for (i = 0; i < ODEBUG_HASH_SIZE; i++) 909 for (i = 0; i < ODEBUG_HASH_SIZE; i++)
909 spin_lock_init(&obj_hash[i].lock); 910 raw_spin_lock_init(&obj_hash[i].lock);
910 911
911 for (i = 0; i < ODEBUG_POOL_SIZE; i++) 912 for (i = 0; i < ODEBUG_POOL_SIZE; i++)
912 hlist_add_head(&obj_static_pool[i].node, &obj_pool); 913 hlist_add_head(&obj_static_pool[i].node, &obj_pool);