diff options
-rw-r--r-- | Documentation/DocBook/debugobjects.tmpl | 50 | ||||
-rw-r--r-- | include/linux/debugobjects.h | 6 | ||||
-rw-r--r-- | lib/debugobjects.c | 38 |
3 files changed, 94 insertions, 0 deletions
diff --git a/Documentation/DocBook/debugobjects.tmpl b/Documentation/DocBook/debugobjects.tmpl index 08ff908aa7a2..24979f691e3e 100644 --- a/Documentation/DocBook/debugobjects.tmpl +++ b/Documentation/DocBook/debugobjects.tmpl | |||
@@ -96,6 +96,7 @@ | |||
96 | <listitem><para>debug_object_deactivate</para></listitem> | 96 | <listitem><para>debug_object_deactivate</para></listitem> |
97 | <listitem><para>debug_object_destroy</para></listitem> | 97 | <listitem><para>debug_object_destroy</para></listitem> |
98 | <listitem><para>debug_object_free</para></listitem> | 98 | <listitem><para>debug_object_free</para></listitem> |
99 | <listitem><para>debug_object_assert_init</para></listitem> | ||
99 | </itemizedlist> | 100 | </itemizedlist> |
100 | Each of these functions takes the address of the real object and | 101 | Each of these functions takes the address of the real object and |
101 | a pointer to the object type specific debug description | 102 | a pointer to the object type specific debug description |
@@ -273,6 +274,26 @@ | |||
273 | debug checks. | 274 | debug checks. |
274 | </para> | 275 | </para> |
275 | </sect1> | 276 | </sect1> |
277 | |||
278 | <sect1 id="debug_object_assert_init"> | ||
279 | <title>debug_object_assert_init</title> | ||
280 | <para> | ||
281 | This function is called to assert that an object has been | ||
282 | initialized. | ||
283 | </para> | ||
284 | <para> | ||
285 | When the real object is not tracked by debugobjects, it calls | ||
286 | fixup_assert_init of the object type description structure | ||
287 | provided by the caller, with the hardcoded object state | ||
288 | ODEBUG_NOT_AVAILABLE. The fixup function can correct the problem | ||
289 | by calling debug_object_init and other specific initializing | ||
290 | functions. | ||
291 | </para> | ||
292 | <para> | ||
293 | When the real object is already tracked by debugobjects it is | ||
294 | ignored. | ||
295 | </para> | ||
296 | </sect1> | ||
276 | </chapter> | 297 | </chapter> |
277 | <chapter id="fixupfunctions"> | 298 | <chapter id="fixupfunctions"> |
278 | <title>Fixup functions</title> | 299 | <title>Fixup functions</title> |
@@ -381,6 +402,35 @@ | |||
381 | statistics. | 402 | statistics. |
382 | </para> | 403 | </para> |
383 | </sect1> | 404 | </sect1> |
405 | <sect1 id="fixup_assert_init"> | ||
406 | <title>fixup_assert_init</title> | ||
407 | <para> | ||
408 | This function is called from the debug code whenever a problem | ||
409 | in debug_object_assert_init is detected. | ||
410 | </para> | ||
411 | <para> | ||
412 | Called from debug_object_assert_init() with a hardcoded state | ||
413 | ODEBUG_STATE_NOTAVAILABLE when the object is not found in the | ||
414 | debug bucket. | ||
415 | </para> | ||
416 | <para> | ||
417 | The function returns 1 when the fixup was successful, | ||
418 | otherwise 0. The return value is used to update the | ||
419 | statistics. | ||
420 | </para> | ||
421 | <para> | ||
422 | Note, this function should make sure debug_object_init() is | ||
423 | called before returning. | ||
424 | </para> | ||
425 | <para> | ||
426 | The handling of statically initialized objects is a special | ||
427 | case. The fixup function should check if this is a legitimate | ||
428 | case of a statically initialized object or not. In this case only | ||
429 | debug_object_init() should be called to make the object known to | ||
430 | the tracker. Then the function should return 0 because this is not | ||
431 | a real fixup. | ||
432 | </para> | ||
433 | </sect1> | ||
384 | </chapter> | 434 | </chapter> |
385 | <chapter id="bugs"> | 435 | <chapter id="bugs"> |
386 | <title>Known Bugs And Assumptions</title> | 436 | <title>Known Bugs And Assumptions</title> |
diff --git a/include/linux/debugobjects.h b/include/linux/debugobjects.h index 65970b811e22..0e5f5785d9f2 100644 --- a/include/linux/debugobjects.h +++ b/include/linux/debugobjects.h | |||
@@ -46,6 +46,8 @@ struct debug_obj { | |||
46 | * fails | 46 | * fails |
47 | * @fixup_free: fixup function, which is called when the free check | 47 | * @fixup_free: fixup function, which is called when the free check |
48 | * fails | 48 | * fails |
49 | * @fixup_assert_init: fixup function, which is called when the assert_init | ||
50 | * check fails | ||
49 | */ | 51 | */ |
50 | struct debug_obj_descr { | 52 | struct debug_obj_descr { |
51 | const char *name; | 53 | const char *name; |
@@ -54,6 +56,7 @@ struct debug_obj_descr { | |||
54 | int (*fixup_activate) (void *addr, enum debug_obj_state state); | 56 | int (*fixup_activate) (void *addr, enum debug_obj_state state); |
55 | int (*fixup_destroy) (void *addr, enum debug_obj_state state); | 57 | int (*fixup_destroy) (void *addr, enum debug_obj_state state); |
56 | int (*fixup_free) (void *addr, enum debug_obj_state state); | 58 | int (*fixup_free) (void *addr, enum debug_obj_state state); |
59 | int (*fixup_assert_init)(void *addr, enum debug_obj_state state); | ||
57 | }; | 60 | }; |
58 | 61 | ||
59 | #ifdef CONFIG_DEBUG_OBJECTS | 62 | #ifdef CONFIG_DEBUG_OBJECTS |
@@ -64,6 +67,7 @@ extern void debug_object_activate (void *addr, struct debug_obj_descr *descr); | |||
64 | extern void debug_object_deactivate(void *addr, struct debug_obj_descr *descr); | 67 | extern void debug_object_deactivate(void *addr, struct debug_obj_descr *descr); |
65 | extern void debug_object_destroy (void *addr, struct debug_obj_descr *descr); | 68 | extern void debug_object_destroy (void *addr, struct debug_obj_descr *descr); |
66 | extern void debug_object_free (void *addr, struct debug_obj_descr *descr); | 69 | extern void debug_object_free (void *addr, struct debug_obj_descr *descr); |
70 | extern void debug_object_assert_init(void *addr, struct debug_obj_descr *descr); | ||
67 | 71 | ||
68 | /* | 72 | /* |
69 | * Active state: | 73 | * Active state: |
@@ -89,6 +93,8 @@ static inline void | |||
89 | debug_object_destroy (void *addr, struct debug_obj_descr *descr) { } | 93 | debug_object_destroy (void *addr, struct debug_obj_descr *descr) { } |
90 | static inline void | 94 | static inline void |
91 | debug_object_free (void *addr, struct debug_obj_descr *descr) { } | 95 | debug_object_free (void *addr, struct debug_obj_descr *descr) { } |
96 | static inline void | ||
97 | debug_object_assert_init(void *addr, struct debug_obj_descr *descr) { } | ||
92 | 98 | ||
93 | static inline void debug_objects_early_init(void) { } | 99 | static inline void debug_objects_early_init(void) { } |
94 | static inline void debug_objects_mem_init(void) { } | 100 | static inline void debug_objects_mem_init(void) { } |
diff --git a/lib/debugobjects.c b/lib/debugobjects.c index b7a530504b38..77cb245f8e7b 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c | |||
@@ -571,6 +571,44 @@ out_unlock: | |||
571 | } | 571 | } |
572 | 572 | ||
573 | /** | 573 | /** |
574 | * debug_object_assert_init - debug checks when object should be init-ed | ||
575 | * @addr: address of the object | ||
576 | * @descr: pointer to an object specific debug description structure | ||
577 | */ | ||
578 | void debug_object_assert_init(void *addr, struct debug_obj_descr *descr) | ||
579 | { | ||
580 | struct debug_bucket *db; | ||
581 | struct debug_obj *obj; | ||
582 | unsigned long flags; | ||
583 | |||
584 | if (!debug_objects_enabled) | ||
585 | return; | ||
586 | |||
587 | db = get_bucket((unsigned long) addr); | ||
588 | |||
589 | raw_spin_lock_irqsave(&db->lock, flags); | ||
590 | |||
591 | obj = lookup_object(addr, db); | ||
592 | if (!obj) { | ||
593 | struct debug_obj o = { .object = addr, | ||
594 | .state = ODEBUG_STATE_NOTAVAILABLE, | ||
595 | .descr = descr }; | ||
596 | |||
597 | raw_spin_unlock_irqrestore(&db->lock, flags); | ||
598 | /* | ||
599 | * Maybe the object is static. Let the type specific | ||
600 | * code decide what to do. | ||
601 | */ | ||
602 | if (debug_object_fixup(descr->fixup_assert_init, addr, | ||
603 | ODEBUG_STATE_NOTAVAILABLE)) | ||
604 | debug_print_object(&o, "assert_init"); | ||
605 | return; | ||
606 | } | ||
607 | |||
608 | raw_spin_unlock_irqrestore(&db->lock, flags); | ||
609 | } | ||
610 | |||
611 | /** | ||
574 | * debug_object_active_state - debug checks object usage state machine | 612 | * debug_object_active_state - debug checks object usage state machine |
575 | * @addr: address of the object | 613 | * @addr: address of the object |
576 | * @descr: pointer to an object specific debug description structure | 614 | * @descr: pointer to an object specific debug description structure |