]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
rcu: Simplify debug-objects fixups
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Tue, 23 Apr 2013 18:31:50 +0000 (11:31 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Mon, 27 May 2013 11:59:17 +0000 (04:59 -0700)
The current debug-objects fixups are complex and heavyweight, and the
fixups are not complete:  Even with the fixups, RCU's callback lists
can still be corrupted.  This commit therefore strips the fixups down
to their minimal form, eliminating two of the three.

It would be even better if (for example) call_rcu() simply leaked
any problematic callbacks, but for that to happen, the debug-objects
system would need to inform its caller of suspicious situations.
This is the subject of a later commit in this series.

Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
kernel/rcupdate.c

index cce6ba8bbace7f0793d008c725c9599a5ba8c1d1..7faee78a648d5fe98cad5b7c19888a7c4a71296f 100644 (file)
@@ -211,43 +211,6 @@ static inline void debug_rcu_head_free(struct rcu_head *head)
        debug_object_free(head, &rcuhead_debug_descr);
 }
 
-/*
- * fixup_init is called when:
- * - an active object is initialized
- */
-static int rcuhead_fixup_init(void *addr, enum debug_obj_state state)
-{
-       struct rcu_head *head = addr;
-
-       switch (state) {
-       case ODEBUG_STATE_ACTIVE:
-               /*
-                * Ensure that queued callbacks are all executed.
-                * If we detect that we are nested in a RCU read-side critical
-                * section, we should simply fail, otherwise we would deadlock.
-                * In !PREEMPT configurations, there is no way to tell if we are
-                * in a RCU read-side critical section or not, so we never
-                * attempt any fixup and just print a warning.
-                */
-#ifndef CONFIG_PREEMPT
-               WARN_ON_ONCE(1);
-               return 0;
-#endif
-               if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
-                   irqs_disabled()) {
-                       WARN_ON_ONCE(1);
-                       return 0;
-               }
-               rcu_barrier();
-               rcu_barrier_sched();
-               rcu_barrier_bh();
-               debug_object_init(head, &rcuhead_debug_descr);
-               return 1;
-       default:
-               return 0;
-       }
-}
-
 /*
  * fixup_activate is called when:
  * - an active object is activated
@@ -268,69 +231,8 @@ static int rcuhead_fixup_activate(void *addr, enum debug_obj_state state)
                debug_object_init(head, &rcuhead_debug_descr);
                debug_object_activate(head, &rcuhead_debug_descr);
                return 0;
-
-       case ODEBUG_STATE_ACTIVE:
-               /*
-                * Ensure that queued callbacks are all executed.
-                * If we detect that we are nested in a RCU read-side critical
-                * section, we should simply fail, otherwise we would deadlock.
-                * In !PREEMPT configurations, there is no way to tell if we are
-                * in a RCU read-side critical section or not, so we never
-                * attempt any fixup and just print a warning.
-                */
-#ifndef CONFIG_PREEMPT
-               WARN_ON_ONCE(1);
-               return 0;
-#endif
-               if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
-                   irqs_disabled()) {
-                       WARN_ON_ONCE(1);
-                       return 0;
-               }
-               rcu_barrier();
-               rcu_barrier_sched();
-               rcu_barrier_bh();
-               debug_object_activate(head, &rcuhead_debug_descr);
-               return 1;
        default:
-               return 0;
-       }
-}
-
-/*
- * fixup_free is called when:
- * - an active object is freed
- */
-static int rcuhead_fixup_free(void *addr, enum debug_obj_state state)
-{
-       struct rcu_head *head = addr;
-
-       switch (state) {
-       case ODEBUG_STATE_ACTIVE:
-               /*
-                * Ensure that queued callbacks are all executed.
-                * If we detect that we are nested in a RCU read-side critical
-                * section, we should simply fail, otherwise we would deadlock.
-                * In !PREEMPT configurations, there is no way to tell if we are
-                * in a RCU read-side critical section or not, so we never
-                * attempt any fixup and just print a warning.
-                */
-#ifndef CONFIG_PREEMPT
-               WARN_ON_ONCE(1);
-               return 0;
-#endif
-               if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
-                   irqs_disabled()) {
-                       WARN_ON_ONCE(1);
-                       return 0;
-               }
-               rcu_barrier();
-               rcu_barrier_sched();
-               rcu_barrier_bh();
-               debug_object_free(head, &rcuhead_debug_descr);
                return 1;
-       default:
-               return 0;
        }
 }
 
@@ -369,9 +271,7 @@ EXPORT_SYMBOL_GPL(destroy_rcu_head_on_stack);
 
 struct debug_obj_descr rcuhead_debug_descr = {
        .name = "rcu_head",
-       .fixup_init = rcuhead_fixup_init,
        .fixup_activate = rcuhead_fixup_activate,
-       .fixup_free = rcuhead_fixup_free,
 };
 EXPORT_SYMBOL_GPL(rcuhead_debug_descr);
 #endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */