diff options
Diffstat (limited to 'lib/debugobjects.c')
| -rw-r--r-- | lib/debugobjects.c | 59 | 
1 files changed, 56 insertions, 3 deletions
diff --git a/lib/debugobjects.c b/lib/debugobjects.c index bf007a43c053..deebcc57d4e6 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c  | |||
| @@ -141,6 +141,7 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) | |||
| 141 | obj->object = addr; | 141 | obj->object = addr; | 
| 142 | obj->descr = descr; | 142 | obj->descr = descr; | 
| 143 | obj->state = ODEBUG_STATE_NONE; | 143 | obj->state = ODEBUG_STATE_NONE; | 
| 144 | obj->astate = 0; | ||
| 144 | hlist_del(&obj->node); | 145 | hlist_del(&obj->node); | 
| 145 | 146 | ||
| 146 | hlist_add_head(&obj->node, &b->list); | 147 | hlist_add_head(&obj->node, &b->list); | 
| @@ -252,8 +253,10 @@ static void debug_print_object(struct debug_obj *obj, char *msg) | |||
| 252 | 253 | ||
| 253 | if (limit < 5 && obj->descr != descr_test) { | 254 | if (limit < 5 && obj->descr != descr_test) { | 
| 254 | limit++; | 255 | limit++; | 
| 255 | WARN(1, KERN_ERR "ODEBUG: %s %s object type: %s\n", msg, | 256 | WARN(1, KERN_ERR "ODEBUG: %s %s (active state %u) " | 
| 256 | obj_states[obj->state], obj->descr->name); | 257 | "object type: %s\n", | 
| 258 | msg, obj_states[obj->state], obj->astate, | ||
| 259 | obj->descr->name); | ||
| 257 | } | 260 | } | 
| 258 | debug_objects_warnings++; | 261 | debug_objects_warnings++; | 
| 259 | } | 262 | } | 
| @@ -447,7 +450,10 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr) | |||
| 447 | case ODEBUG_STATE_INIT: | 450 | case ODEBUG_STATE_INIT: | 
| 448 | case ODEBUG_STATE_INACTIVE: | 451 | case ODEBUG_STATE_INACTIVE: | 
| 449 | case ODEBUG_STATE_ACTIVE: | 452 | case ODEBUG_STATE_ACTIVE: | 
| 450 | obj->state = ODEBUG_STATE_INACTIVE; | 453 | if (!obj->astate) | 
| 454 | obj->state = ODEBUG_STATE_INACTIVE; | ||
| 455 | else | ||
| 456 | debug_print_object(obj, "deactivate"); | ||
| 451 | break; | 457 | break; | 
| 452 | 458 | ||
| 453 | case ODEBUG_STATE_DESTROYED: | 459 | case ODEBUG_STATE_DESTROYED: | 
| @@ -553,6 +559,53 @@ out_unlock: | |||
| 553 | raw_spin_unlock_irqrestore(&db->lock, flags); | 559 | raw_spin_unlock_irqrestore(&db->lock, flags); | 
| 554 | } | 560 | } | 
| 555 | 561 | ||
| 562 | /** | ||
| 563 | * debug_object_active_state - debug checks object usage state machine | ||
| 564 | * @addr: address of the object | ||
| 565 | * @descr: pointer to an object specific debug description structure | ||
| 566 | * @expect: expected state | ||
| 567 | * @next: state to move to if expected state is found | ||
| 568 | */ | ||
| 569 | void | ||
| 570 | debug_object_active_state(void *addr, struct debug_obj_descr *descr, | ||
| 571 | unsigned int expect, unsigned int next) | ||
| 572 | { | ||
| 573 | struct debug_bucket *db; | ||
| 574 | struct debug_obj *obj; | ||
| 575 | unsigned long flags; | ||
| 576 | |||
| 577 | if (!debug_objects_enabled) | ||
| 578 | return; | ||
| 579 | |||
| 580 | db = get_bucket((unsigned long) addr); | ||
| 581 | |||
| 582 | raw_spin_lock_irqsave(&db->lock, flags); | ||
| 583 | |||
| 584 | obj = lookup_object(addr, db); | ||
| 585 | if (obj) { | ||
| 586 | switch (obj->state) { | ||
| 587 | case ODEBUG_STATE_ACTIVE: | ||
| 588 | if (obj->astate == expect) | ||
| 589 | obj->astate = next; | ||
| 590 | else | ||
| 591 | debug_print_object(obj, "active_state"); | ||
| 592 | break; | ||
| 593 | |||
| 594 | default: | ||
| 595 | debug_print_object(obj, "active_state"); | ||
| 596 | break; | ||
| 597 | } | ||
| 598 | } else { | ||
| 599 | struct debug_obj o = { .object = addr, | ||
| 600 | .state = ODEBUG_STATE_NOTAVAILABLE, | ||
| 601 | .descr = descr }; | ||
| 602 | |||
| 603 | debug_print_object(&o, "active_state"); | ||
| 604 | } | ||
| 605 | |||
| 606 | raw_spin_unlock_irqrestore(&db->lock, flags); | ||
| 607 | } | ||
| 608 | |||
| 556 | #ifdef CONFIG_DEBUG_OBJECTS_FREE | 609 | #ifdef CONFIG_DEBUG_OBJECTS_FREE | 
| 557 | static void __debug_check_no_obj_freed(const void *address, unsigned long size) | 610 | static void __debug_check_no_obj_freed(const void *address, unsigned long size) | 
| 558 | { | 611 | { | 
