aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig.debug14
-rw-r--r--lib/btree.c3
-rw-r--r--lib/debugobjects.c63
-rw-r--r--lib/rwsem.c5
4 files changed, 76 insertions, 9 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 231384012a14..d85be90d5888 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -512,6 +512,18 @@ config PROVE_RCU
512 512
513 Say N if you are unsure. 513 Say N if you are unsure.
514 514
515config PROVE_RCU_REPEATEDLY
516 bool "RCU debugging: don't disable PROVE_RCU on first splat"
517 depends on PROVE_RCU
518 default n
519 help
520 By itself, PROVE_RCU will disable checking upon issuing the
521 first warning (or "splat"). This feature prevents such
522 disabling, allowing multiple RCU-lockdep warnings to be printed
523 on a single reboot.
524
525 Say N if you are unsure.
526
515config LOCKDEP 527config LOCKDEP
516 bool 528 bool
517 depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT 529 depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
@@ -793,7 +805,7 @@ config RCU_CPU_STALL_DETECTOR
793config RCU_CPU_STALL_VERBOSE 805config RCU_CPU_STALL_VERBOSE
794 bool "Print additional per-task information for RCU_CPU_STALL_DETECTOR" 806 bool "Print additional per-task information for RCU_CPU_STALL_DETECTOR"
795 depends on RCU_CPU_STALL_DETECTOR && TREE_PREEMPT_RCU 807 depends on RCU_CPU_STALL_DETECTOR && TREE_PREEMPT_RCU
796 default n 808 default y
797 help 809 help
798 This option causes RCU to printk detailed per-task information 810 This option causes RCU to printk detailed per-task information
799 for any tasks that are stalling the current RCU grace period. 811 for any tasks that are stalling the current RCU grace period.
diff --git a/lib/btree.c b/lib/btree.c
index 41859a820218..c9c6f0351526 100644
--- a/lib/btree.c
+++ b/lib/btree.c
@@ -95,7 +95,8 @@ static unsigned long *btree_node_alloc(struct btree_head *head, gfp_t gfp)
95 unsigned long *node; 95 unsigned long *node;
96 96
97 node = mempool_alloc(head->mempool, gfp); 97 node = mempool_alloc(head->mempool, gfp);
98 memset(node, 0, NODESIZE); 98 if (likely(node))
99 memset(node, 0, NODESIZE);
99 return node; 100 return node;
100} 101}
101 102
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index b862b30369ff..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 */
569void
570debug_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
557static void __debug_check_no_obj_freed(const void *address, unsigned long size) 610static void __debug_check_no_obj_freed(const void *address, unsigned long size)
558{ 611{
@@ -774,7 +827,7 @@ static int __init fixup_free(void *addr, enum debug_obj_state state)
774 } 827 }
775} 828}
776 829
777static int 830static int __init
778check_results(void *addr, enum debug_obj_state state, int fixups, int warnings) 831check_results(void *addr, enum debug_obj_state state, int fixups, int warnings)
779{ 832{
780 struct debug_bucket *db; 833 struct debug_bucket *db;
@@ -917,7 +970,7 @@ void __init debug_objects_early_init(void)
917/* 970/*
918 * Convert the statically allocated objects to dynamic ones: 971 * Convert the statically allocated objects to dynamic ones:
919 */ 972 */
920static int debug_objects_replace_static_objects(void) 973static int __init debug_objects_replace_static_objects(void)
921{ 974{
922 struct debug_bucket *db = obj_hash; 975 struct debug_bucket *db = obj_hash;
923 struct hlist_node *node, *tmp; 976 struct hlist_node *node, *tmp;
diff --git a/lib/rwsem.c b/lib/rwsem.c
index 3e3365e5665e..ceba8e28807a 100644
--- a/lib/rwsem.c
+++ b/lib/rwsem.c
@@ -136,9 +136,10 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading)
136 out: 136 out:
137 return sem; 137 return sem;
138 138
139 /* undo the change to count, but check for a transition 1->0 */ 139 /* undo the change to the active count, but check for a transition
140 * 1->0 */
140 undo: 141 undo:
141 if (rwsem_atomic_update(-RWSEM_ACTIVE_BIAS, sem) != 0) 142 if (rwsem_atomic_update(-RWSEM_ACTIVE_BIAS, sem) & RWSEM_ACTIVE_MASK)
142 goto out; 143 goto out;
143 goto try_again; 144 goto try_again;
144} 145}