diff options
Diffstat (limited to 'lib/debugobjects.c')
-rw-r--r-- | lib/debugobjects.c | 75 |
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 | ||
26 | struct debug_bucket { | 27 | struct 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 | ||
31 | static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE]; | 32 | static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE]; |
32 | 33 | ||
33 | static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE] __initdata; | 34 | static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE] __initdata; |
34 | 35 | ||
35 | static DEFINE_SPINLOCK(pool_lock); | 36 | static DEFINE_RAW_SPINLOCK(pool_lock); |
36 | 37 | ||
37 | static HLIST_HEAD(obj_pool); | 38 | static 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 | } |
510 | out_unlock: | 511 | out_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 | } |
550 | out_unlock: | 551 | out_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 | ||
575 | repeat: | 576 | repeat: |
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; |
808 | out: | 809 | out: |
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); |