diff options
Diffstat (limited to 'lib/debugobjects.c')
-rw-r--r-- | lib/debugobjects.c | 79 |
1 files changed, 58 insertions, 21 deletions
diff --git a/lib/debugobjects.c b/lib/debugobjects.c index a78b7c6e042c..d11808ca4bc4 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c | |||
@@ -79,30 +79,29 @@ static const char *obj_states[ODEBUG_STATE_MAX] = { | |||
79 | [ODEBUG_STATE_NOTAVAILABLE] = "not available", | 79 | [ODEBUG_STATE_NOTAVAILABLE] = "not available", |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static int fill_pool(void) | 82 | static void fill_pool(void) |
83 | { | 83 | { |
84 | gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; | 84 | gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; |
85 | struct debug_obj *new; | 85 | struct debug_obj *new; |
86 | unsigned long flags; | 86 | unsigned long flags; |
87 | 87 | ||
88 | if (likely(obj_pool_free >= ODEBUG_POOL_MIN_LEVEL)) | 88 | if (likely(obj_pool_free >= ODEBUG_POOL_MIN_LEVEL)) |
89 | return obj_pool_free; | 89 | return; |
90 | 90 | ||
91 | if (unlikely(!obj_cache)) | 91 | if (unlikely(!obj_cache)) |
92 | return obj_pool_free; | 92 | return; |
93 | 93 | ||
94 | while (obj_pool_free < ODEBUG_POOL_MIN_LEVEL) { | 94 | while (obj_pool_free < ODEBUG_POOL_MIN_LEVEL) { |
95 | 95 | ||
96 | new = kmem_cache_zalloc(obj_cache, gfp); | 96 | new = kmem_cache_zalloc(obj_cache, gfp); |
97 | if (!new) | 97 | if (!new) |
98 | return obj_pool_free; | 98 | return; |
99 | 99 | ||
100 | raw_spin_lock_irqsave(&pool_lock, flags); | 100 | raw_spin_lock_irqsave(&pool_lock, flags); |
101 | hlist_add_head(&new->node, &obj_pool); | 101 | hlist_add_head(&new->node, &obj_pool); |
102 | obj_pool_free++; | 102 | obj_pool_free++; |
103 | raw_spin_unlock_irqrestore(&pool_lock, flags); | 103 | raw_spin_unlock_irqrestore(&pool_lock, flags); |
104 | } | 104 | } |
105 | return obj_pool_free; | ||
106 | } | 105 | } |
107 | 106 | ||
108 | /* | 107 | /* |
@@ -268,12 +267,16 @@ static void debug_print_object(struct debug_obj *obj, char *msg) | |||
268 | * Try to repair the damage, so we have a better chance to get useful | 267 | * Try to repair the damage, so we have a better chance to get useful |
269 | * debug output. | 268 | * debug output. |
270 | */ | 269 | */ |
271 | static void | 270 | static int |
272 | debug_object_fixup(int (*fixup)(void *addr, enum debug_obj_state state), | 271 | debug_object_fixup(int (*fixup)(void *addr, enum debug_obj_state state), |
273 | void * addr, enum debug_obj_state state) | 272 | void * addr, enum debug_obj_state state) |
274 | { | 273 | { |
274 | int fixed = 0; | ||
275 | |||
275 | if (fixup) | 276 | if (fixup) |
276 | debug_objects_fixups += fixup(addr, state); | 277 | fixed = fixup(addr, state); |
278 | debug_objects_fixups += fixed; | ||
279 | return fixed; | ||
277 | } | 280 | } |
278 | 281 | ||
279 | static void debug_object_is_on_stack(void *addr, int onstack) | 282 | static void debug_object_is_on_stack(void *addr, int onstack) |
@@ -386,6 +389,9 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr) | |||
386 | struct debug_bucket *db; | 389 | struct debug_bucket *db; |
387 | struct debug_obj *obj; | 390 | struct debug_obj *obj; |
388 | unsigned long flags; | 391 | unsigned long flags; |
392 | struct debug_obj o = { .object = addr, | ||
393 | .state = ODEBUG_STATE_NOTAVAILABLE, | ||
394 | .descr = descr }; | ||
389 | 395 | ||
390 | if (!debug_objects_enabled) | 396 | if (!debug_objects_enabled) |
391 | return; | 397 | return; |
@@ -425,8 +431,9 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr) | |||
425 | * let the type specific code decide whether this is | 431 | * let the type specific code decide whether this is |
426 | * true or not. | 432 | * true or not. |
427 | */ | 433 | */ |
428 | debug_object_fixup(descr->fixup_activate, addr, | 434 | if (debug_object_fixup(descr->fixup_activate, addr, |
429 | ODEBUG_STATE_NOTAVAILABLE); | 435 | ODEBUG_STATE_NOTAVAILABLE)) |
436 | debug_print_object(&o, "activate"); | ||
430 | } | 437 | } |
431 | 438 | ||
432 | /** | 439 | /** |
@@ -563,6 +570,44 @@ out_unlock: | |||
563 | } | 570 | } |
564 | 571 | ||
565 | /** | 572 | /** |
573 | * debug_object_assert_init - debug checks when object should be init-ed | ||
574 | * @addr: address of the object | ||
575 | * @descr: pointer to an object specific debug description structure | ||
576 | */ | ||
577 | void debug_object_assert_init(void *addr, struct debug_obj_descr *descr) | ||
578 | { | ||
579 | struct debug_bucket *db; | ||
580 | struct debug_obj *obj; | ||
581 | unsigned long flags; | ||
582 | |||
583 | if (!debug_objects_enabled) | ||
584 | return; | ||
585 | |||
586 | db = get_bucket((unsigned long) addr); | ||
587 | |||
588 | raw_spin_lock_irqsave(&db->lock, flags); | ||
589 | |||
590 | obj = lookup_object(addr, db); | ||
591 | if (!obj) { | ||
592 | struct debug_obj o = { .object = addr, | ||
593 | .state = ODEBUG_STATE_NOTAVAILABLE, | ||
594 | .descr = descr }; | ||
595 | |||
596 | raw_spin_unlock_irqrestore(&db->lock, flags); | ||
597 | /* | ||
598 | * Maybe the object is static. Let the type specific | ||
599 | * code decide what to do. | ||
600 | */ | ||
601 | if (debug_object_fixup(descr->fixup_assert_init, addr, | ||
602 | ODEBUG_STATE_NOTAVAILABLE)) | ||
603 | debug_print_object(&o, "assert_init"); | ||
604 | return; | ||
605 | } | ||
606 | |||
607 | raw_spin_unlock_irqrestore(&db->lock, flags); | ||
608 | } | ||
609 | |||
610 | /** | ||
566 | * debug_object_active_state - debug checks object usage state machine | 611 | * debug_object_active_state - debug checks object usage state machine |
567 | * @addr: address of the object | 612 | * @addr: address of the object |
568 | * @descr: pointer to an object specific debug description structure | 613 | * @descr: pointer to an object specific debug description structure |
@@ -772,17 +817,9 @@ static int __init fixup_activate(void *addr, enum debug_obj_state state) | |||
772 | if (obj->static_init == 1) { | 817 | if (obj->static_init == 1) { |
773 | debug_object_init(obj, &descr_type_test); | 818 | debug_object_init(obj, &descr_type_test); |
774 | debug_object_activate(obj, &descr_type_test); | 819 | debug_object_activate(obj, &descr_type_test); |
775 | /* | 820 | return 0; |
776 | * Real code should return 0 here ! This is | ||
777 | * not a fixup of some bad behaviour. We | ||
778 | * merily call the debug_init function to keep | ||
779 | * track of the object. | ||
780 | */ | ||
781 | return 1; | ||
782 | } else { | ||
783 | /* Real code needs to emit a warning here */ | ||
784 | } | 821 | } |
785 | return 0; | 822 | return 1; |
786 | 823 | ||
787 | case ODEBUG_STATE_ACTIVE: | 824 | case ODEBUG_STATE_ACTIVE: |
788 | debug_object_deactivate(obj, &descr_type_test); | 825 | debug_object_deactivate(obj, &descr_type_test); |
@@ -921,7 +958,7 @@ static void __init debug_objects_selftest(void) | |||
921 | 958 | ||
922 | obj.static_init = 1; | 959 | obj.static_init = 1; |
923 | debug_object_activate(&obj, &descr_type_test); | 960 | debug_object_activate(&obj, &descr_type_test); |
924 | if (check_results(&obj, ODEBUG_STATE_ACTIVE, ++fixups, warnings)) | 961 | if (check_results(&obj, ODEBUG_STATE_ACTIVE, fixups, warnings)) |
925 | goto out; | 962 | goto out; |
926 | debug_object_init(&obj, &descr_type_test); | 963 | debug_object_init(&obj, &descr_type_test); |
927 | if (check_results(&obj, ODEBUG_STATE_INIT, ++fixups, ++warnings)) | 964 | if (check_results(&obj, ODEBUG_STATE_INIT, ++fixups, ++warnings)) |
@@ -1014,10 +1051,10 @@ static int __init debug_objects_replace_static_objects(void) | |||
1014 | cnt++; | 1051 | cnt++; |
1015 | } | 1052 | } |
1016 | } | 1053 | } |
1054 | local_irq_enable(); | ||
1017 | 1055 | ||
1018 | printk(KERN_DEBUG "ODEBUG: %d of %d active objects replaced\n", cnt, | 1056 | printk(KERN_DEBUG "ODEBUG: %d of %d active objects replaced\n", cnt, |
1019 | obj_pool_used); | 1057 | obj_pool_used); |
1020 | local_irq_enable(); | ||
1021 | return 0; | 1058 | return 0; |
1022 | free: | 1059 | free: |
1023 | hlist_for_each_entry_safe(obj, node, tmp, &objects, node) { | 1060 | hlist_for_each_entry_safe(obj, node, tmp, &objects, node) { |