linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks
@ 2010-05-11 23:32 Paul E. McKenney
  2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 01/11] Debugobjects transition check Paul E. McKenney
                   ` (10 more replies)
  0 siblings, 11 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet

Hello!

This patchset pulls Mathieu's debugobject-specific commits out of the
earlier patchbomb (http://lkml.org/lkml/2010/5/4/298):

1.	Add transition-check capability to debugobjects.
2.	Add init_rcu_head_on_stack() and destroy_rcu_head_on_stack() APIs.
3.	Remove rcu_head initializations from RCU, except for those
	for on-stack rcu_head structures, which must use the APIs
	introduced in #2 above.
4-9.	Ditto for powerpc, block, staging, fs, mm, and selinux.
10.	Remove the old rcu_head initialization APIs.
11.	Add the debugobjects workings to RCU, enabled by
	CONFIG_DEBUG_OBJECTS_RCU_HEAD.

These have been reordered and consolidated to reduce inter-commit
dependencies.

							Thanx, Paul

 b/arch/powerpc/mm/pgtable.c                   |    1 
 b/block/cfq-iosched.c                         |    1 
 b/block/genhd.c                               |    1 
 b/drivers/staging/batman-adv/hard-interface.c |    1 
 b/fs/file.c                                   |    3 
 b/fs/fs-writeback.c                           |   31 +++-
 b/fs/partitions/check.c                       |    1 
 b/include/linux/debugobjects.h                |   11 +
 b/include/linux/init_task.h                   |    1 
 b/include/linux/rcupdate.h                    |    8 +
 b/kernel/rcupdate.c                           |  170 ++++++++++++++++++++++++++
 b/kernel/rcutiny.c                            |    6 
 b/kernel/rcutorture.c                         |    2 
 b/kernel/rcutree.c                            |    4 
 b/kernel/rcutree_plugin.h                     |    2 
 b/lib/Kconfig.debug                           |    6 
 b/lib/debugobjects.c                          |   59 ++++++++-
 b/mm/backing-dev.c                            |    1 
 b/mm/slob.c                                   |    1 
 b/security/selinux/avc.c                      |    1 
 b/security/selinux/netnode.c                  |    2 
 include/linux/rcupdate.h                      |   55 +++++++-
 kernel/rcutiny.c                              |    2 
 kernel/rcutree.c                              |    2 
 24 files changed, 344 insertions(+), 28 deletions(-)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 01/11] Debugobjects transition check
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
@ 2010-05-11 23:32 ` Paul E. McKenney
  2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 02/11] rcu head introduce rcu head init on stack Paul E. McKenney
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Mathieu Desnoyers, Paul E. McKenney,
	Alexey Dobriyan

From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>

Implement a basic state machine checker in the debugobjects.

This state machine checker detects races and inconsistencies within the "active"
life of a debugobject. The checker only keeps track of the current state; all
the state machine logic is kept at the object instance level.

The checker works by adding a supplementary "unsigned int astate" field to the
debug_obj structure. It keeps track of the current "active state" of the object.

The only constraints that are imposed on the states by the debugobjects system
is that:

- activation of an object sets the current active state to 0,
- deactivation of an object expects the current active state to be 0.

For the rest of the states, the state mapping is determined by the specific
object instance. Therefore, the logic keeping track of the state machine is
within the specialized instance, without any need to know about it at the
debugobject level.

The current object active state is changed by calling:

debug_object_active_state(addr, descr, expect, next)

where "expect" is the expected state and "next" is the next state to move to if
the expected state is found. A warning is generated if the expected is not
found.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: David S. Miller <davem@davemloft.net>
CC: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
CC: akpm@linux-foundation.org
CC: mingo@elte.hu
CC: laijs@cn.fujitsu.com
CC: dipankar@in.ibm.com
CC: josh@joshtriplett.org
CC: dvhltc@us.ibm.com
CC: niv@us.ibm.com
CC: peterz@infradead.org
CC: rostedt@goodmis.org
CC: Valdis.Kletnieks@vt.edu
CC: dhowells@redhat.com
CC: eric.dumazet@gmail.com
CC: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
 include/linux/debugobjects.h |   11 ++++++++
 lib/debugobjects.c           |   59 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/include/linux/debugobjects.h b/include/linux/debugobjects.h
index 8c243aa..597692f 100644
--- a/include/linux/debugobjects.h
+++ b/include/linux/debugobjects.h
@@ -20,12 +20,14 @@ struct debug_obj_descr;
  * struct debug_obj - representaion of an tracked object
  * @node:	hlist node to link the object into the tracker list
  * @state:	tracked object state
+ * @astate:	current active state
  * @object:	pointer to the real object
  * @descr:	pointer to an object type specific debug description structure
  */
 struct debug_obj {
 	struct hlist_node	node;
 	enum debug_obj_state	state;
+	unsigned int		astate;
 	void			*object;
 	struct debug_obj_descr	*descr;
 };
@@ -60,6 +62,15 @@ extern void debug_object_deactivate(void *addr, struct debug_obj_descr *descr);
 extern void debug_object_destroy   (void *addr, struct debug_obj_descr *descr);
 extern void debug_object_free      (void *addr, struct debug_obj_descr *descr);
 
+/*
+ * Active state:
+ * - Set at 0 upon initialization.
+ * - Must return to 0 before deactivation.
+ */
+extern void
+debug_object_active_state(void *addr, struct debug_obj_descr *descr,
+			  unsigned int expect, unsigned int next);
+
 extern void debug_objects_early_init(void);
 extern void debug_objects_mem_init(void);
 #else
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index b862b30..076464f 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)
 		obj->object = addr;
 		obj->descr  = descr;
 		obj->state  = ODEBUG_STATE_NONE;
+		obj->astate = 0;
 		hlist_del(&obj->node);
 
 		hlist_add_head(&obj->node, &b->list);
@@ -252,8 +253,10 @@ static void debug_print_object(struct debug_obj *obj, char *msg)
 
 	if (limit < 5 && obj->descr != descr_test) {
 		limit++;
-		WARN(1, KERN_ERR "ODEBUG: %s %s object type: %s\n", msg,
-		       obj_states[obj->state], obj->descr->name);
+		WARN(1, KERN_ERR "ODEBUG: %s %s (active state %u) "
+				 "object type: %s\n",
+			msg, obj_states[obj->state], obj->astate,
+			obj->descr->name);
 	}
 	debug_objects_warnings++;
 }
@@ -447,7 +450,10 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr)
 		case ODEBUG_STATE_INIT:
 		case ODEBUG_STATE_INACTIVE:
 		case ODEBUG_STATE_ACTIVE:
-			obj->state = ODEBUG_STATE_INACTIVE;
+			if (!obj->astate)
+				obj->state = ODEBUG_STATE_INACTIVE;
+			else
+				debug_print_object(obj, "deactivate");
 			break;
 
 		case ODEBUG_STATE_DESTROYED:
@@ -553,6 +559,53 @@ out_unlock:
 	raw_spin_unlock_irqrestore(&db->lock, flags);
 }
 
+/**
+ * debug_object_active_state - debug checks object usage state machine
+ * @addr:	address of the object
+ * @descr:	pointer to an object specific debug description structure
+ * @expect:	expected state
+ * @next:	state to move to if expected state is found
+ */
+void
+debug_object_active_state(void *addr, struct debug_obj_descr *descr,
+			  unsigned int expect, unsigned int next)
+{
+	struct debug_bucket *db;
+	struct debug_obj *obj;
+	unsigned long flags;
+
+	if (!debug_objects_enabled)
+		return;
+
+	db = get_bucket((unsigned long) addr);
+
+	raw_spin_lock_irqsave(&db->lock, flags);
+
+	obj = lookup_object(addr, db);
+	if (obj) {
+		switch (obj->state) {
+		case ODEBUG_STATE_ACTIVE:
+			if (obj->astate == expect)
+				obj->astate = next;
+			else
+				debug_print_object(obj, "active_state");
+			break;
+
+		default:
+			debug_print_object(obj, "active_state");
+			break;
+		}
+	} else {
+		struct debug_obj o = { .object = addr,
+				       .state = ODEBUG_STATE_NOTAVAILABLE,
+				       .descr = descr };
+
+		debug_print_object(&o, "active_state");
+	}
+
+	raw_spin_unlock_irqrestore(&db->lock, flags);
+}
+
 #ifdef CONFIG_DEBUG_OBJECTS_FREE
 static void __debug_check_no_obj_freed(const void *address, unsigned long size)
 {
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 02/11] rcu head introduce rcu head init on stack
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
  2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 01/11] Debugobjects transition check Paul E. McKenney
@ 2010-05-11 23:32 ` Paul E. McKenney
  2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 03/11] rcu: remove all rcu head initializations, except on_stack initializations Paul E. McKenney
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Mathieu Desnoyers, Paul E. McKenney,
	David S. Miller, Alexey Dobriyan

From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>

PEM:
o     Would it be possible to make this bisectable as follows?

      a.      Insert a new patch after current patch 4/6 that
              defines destroy_rcu_head_on_stack(),
              init_rcu_head_on_stack(), and init_rcu_head() with
              their !CONFIG_DEBUG_OBJECTS_RCU_HEAD definitions.

This patch performs this transition.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
CC: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
CC: David S. Miller <davem@davemloft.net>
CC: akpm@linux-foundation.org
CC: mingo@elte.hu
CC: laijs@cn.fujitsu.com
CC: dipankar@in.ibm.com
CC: josh@joshtriplett.org
CC: dvhltc@us.ibm.com
CC: niv@us.ibm.com
CC: tglx@linutronix.de
CC: peterz@infradead.org
CC: rostedt@goodmis.org
CC: Valdis.Kletnieks@vt.edu
CC: dhowells@redhat.com
CC: eric.dumazet@gmail.com
CC: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
 include/linux/rcupdate.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 23be3a7..b653b4a 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -79,6 +79,14 @@ extern void rcu_init(void);
        (ptr)->next = NULL; (ptr)->func = NULL; \
 } while (0)
 
+static inline void init_rcu_head_on_stack(struct rcu_head *head)
+{
+}
+
+static inline void destroy_rcu_head_on_stack(struct rcu_head *head)
+{
+}
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
 extern struct lockdep_map rcu_lock_map;
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 03/11] rcu: remove all rcu head initializations, except on_stack initializations
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
  2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 01/11] Debugobjects transition check Paul E. McKenney
  2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 02/11] rcu head introduce rcu head init on stack Paul E. McKenney
@ 2010-05-11 23:32 ` Paul E. McKenney
  2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 04/11] powerpc: remove all rcu head initializations Paul E. McKenney
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Paul E. McKenney, Mathieu Desnoyers

Remove all rcu head inits. We don't care about the RCU head state before passing
it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
keep track of objects on stack.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
 include/linux/init_task.h |    1 -
 kernel/rcutiny.c          |    6 ++++++
 kernel/rcutorture.c       |    2 ++
 kernel/rcutree.c          |    4 ++++
 kernel/rcutree_plugin.h   |    2 ++
 5 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index b1ed1cd..7996fc2 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -49,7 +49,6 @@ extern struct group_info init_groups;
 		{ .first = &init_task.pids[PIDTYPE_PGID].node },	\
 		{ .first = &init_task.pids[PIDTYPE_SID].node },		\
 	},								\
-	.rcu		= RCU_HEAD_INIT,				\
 	.level		= 0,						\
 	.numbers	= { {						\
 		.nr		= 0,					\
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
index b1804ff..38729d3 100644
--- a/kernel/rcutiny.c
+++ b/kernel/rcutiny.c
@@ -245,11 +245,13 @@ void rcu_barrier(void)
 {
 	struct rcu_synchronize rcu;
 
+	init_rcu_head_on_stack(&rcu.head);
 	init_completion(&rcu.completion);
 	/* Will wake me after RCU finished. */
 	call_rcu(&rcu.head, wakeme_after_rcu);
 	/* Wait for it. */
 	wait_for_completion(&rcu.completion);
+	destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier);
 
@@ -257,11 +259,13 @@ void rcu_barrier_bh(void)
 {
 	struct rcu_synchronize rcu;
 
+	init_rcu_head_on_stack(&rcu.head);
 	init_completion(&rcu.completion);
 	/* Will wake me after RCU finished. */
 	call_rcu_bh(&rcu.head, wakeme_after_rcu);
 	/* Wait for it. */
 	wait_for_completion(&rcu.completion);
+	destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier_bh);
 
@@ -269,11 +273,13 @@ void rcu_barrier_sched(void)
 {
 	struct rcu_synchronize rcu;
 
+	init_rcu_head_on_stack(&rcu.head);
 	init_completion(&rcu.completion);
 	/* Will wake me after RCU finished. */
 	call_rcu_sched(&rcu.head, wakeme_after_rcu);
 	/* Wait for it. */
 	wait_for_completion(&rcu.completion);
+	destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier_sched);
 
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 58df55b..077defb 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -464,9 +464,11 @@ static void rcu_bh_torture_synchronize(void)
 {
 	struct rcu_bh_torture_synchronize rcu;
 
+	init_rcu_head_on_stack(&rcu.head);
 	init_completion(&rcu.completion);
 	call_rcu_bh(&rcu.head, rcu_bh_torture_wakeme_after_cb);
 	wait_for_completion(&rcu.completion);
+	destroy_rcu_head_on_stack(&rcu.head);
 }
 
 static struct rcu_torture_ops rcu_bh_ops = {
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index ba69969..d443734 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1484,11 +1484,13 @@ void synchronize_sched(void)
 	if (rcu_blocking_is_gp())
 		return;
 
+	init_rcu_head_on_stack(&rcu.head);
 	init_completion(&rcu.completion);
 	/* Will wake me after RCU finished. */
 	call_rcu_sched(&rcu.head, wakeme_after_rcu);
 	/* Wait for it. */
 	wait_for_completion(&rcu.completion);
+	destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(synchronize_sched);
 
@@ -1508,11 +1510,13 @@ void synchronize_rcu_bh(void)
 	if (rcu_blocking_is_gp())
 		return;
 
+	init_rcu_head_on_stack(&rcu.head);
 	init_completion(&rcu.completion);
 	/* Will wake me after RCU finished. */
 	call_rcu_bh(&rcu.head, wakeme_after_rcu);
 	/* Wait for it. */
 	wait_for_completion(&rcu.completion);
+	destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
 
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index ac7d80f..0e4f420 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -557,11 +557,13 @@ void synchronize_rcu(void)
 	if (!rcu_scheduler_active)
 		return;
 
+	init_rcu_head_on_stack(&rcu.head);
 	init_completion(&rcu.completion);
 	/* Will wake me after RCU finished. */
 	call_rcu(&rcu.head, wakeme_after_rcu);
 	/* Wait for it. */
 	wait_for_completion(&rcu.completion);
+	destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu);
 
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 04/11] powerpc: remove all rcu head initializations
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
                   ` (2 preceding siblings ...)
  2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 03/11] rcu: remove all rcu head initializations, except on_stack initializations Paul E. McKenney
@ 2010-05-11 23:32 ` Paul E. McKenney
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 05/11] block: " Paul E. McKenney
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Paul E. McKenney, Mathieu Desnoyers,
	Benjamin Herrenschmidt, Paul Mackerras

Remove all rcu head inits. We don't care about the RCU head state before passing
it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
keep track of objects on stack.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
 arch/powerpc/mm/pgtable.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index ebc2f38..2c7e801 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -92,7 +92,6 @@ static void pte_free_rcu_callback(struct rcu_head *head)
 
 static void pte_free_submit(struct pte_freelist_batch *batch)
 {
-	INIT_RCU_HEAD(&batch->rcu);
 	call_rcu(&batch->rcu, pte_free_rcu_callback);
 }
 
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 05/11] block: remove all rcu head initializations
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
                   ` (3 preceding siblings ...)
  2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 04/11] powerpc: remove all rcu head initializations Paul E. McKenney
@ 2010-05-11 23:33 ` Paul E. McKenney
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 06/11] staging: " Paul E. McKenney
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Paul E. McKenney, Mathieu Desnoyers, Jens Axboe

Remove all rcu head inits. We don't care about the RCU head state before passing
it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
keep track of objects on stack.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Jens Axboe <jens.axboe@oracle.com>
---
 block/cfq-iosched.c |    1 -
 block/genhd.c       |    1 -
 2 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 5f127cf..702d006 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -3743,7 +3743,6 @@ static void *cfq_init_queue(struct request_queue *q)
 	 * second, in order to have larger depth for async operations.
 	 */
 	cfqd->last_delayed_sync = jiffies - HZ;
-	INIT_RCU_HEAD(&cfqd->rcu);
 	return cfqd;
 }
 
diff --git a/block/genhd.c b/block/genhd.c
index d13ba76..27e85a2 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -987,7 +987,6 @@ int disk_expand_part_tbl(struct gendisk *disk, int partno)
 	if (!new_ptbl)
 		return -ENOMEM;
 
-	INIT_RCU_HEAD(&new_ptbl->rcu_head);
 	new_ptbl->len = target;
 
 	for (i = 0; i < len; i++)
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 06/11] staging: remove all rcu head initializations
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
                   ` (4 preceding siblings ...)
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 05/11] block: " Paul E. McKenney
@ 2010-05-11 23:33 ` Paul E. McKenney
  2010-05-11 23:45   ` Greg KH
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 07/11] fs: remove all rcu head initializations, except on_stack initializations Paul E. McKenney
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Paul E. McKenney, Mathieu Desnoyers,
	Greg Kroah-Hartman

Remove all rcu head inits. We don't care about the RCU head state before passing
it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
keep track of objects on stack.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/staging/batman-adv/hard-interface.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c
index befd488..96ea0e5 100644
--- a/drivers/staging/batman-adv/hard-interface.c
+++ b/drivers/staging/batman-adv/hard-interface.c
@@ -301,7 +301,6 @@ int hardif_add_interface(char *dev, int if_num)
 	batman_if->if_num = if_num;
 	batman_if->dev = dev;
 	batman_if->if_active = IF_INACTIVE;
-	INIT_RCU_HEAD(&batman_if->rcu);
 
 	printk(KERN_INFO "batman-adv:Adding interface: %s\n", dev);
 	avail_ifs++;
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 07/11] fs: remove all rcu head initializations, except on_stack initializations
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
                   ` (5 preceding siblings ...)
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 06/11] staging: " Paul E. McKenney
@ 2010-05-11 23:33 ` Paul E. McKenney
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 08/11] mm: remove all rcu head initializations Paul E. McKenney
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Paul E. McKenney, Mathieu Desnoyers, Alexander Viro,
	Andries Brouwer

Remove all rcu head inits. We don't care about the RCU head state before passing
it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
keep track of objects on stack.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Andries Brouwer <aeb@cwi.nl>
---
 fs/file.c             |    3 ---
 fs/fs-writeback.c     |   31 ++++++++++++++++++++++++++-----
 fs/partitions/check.c |    1 -
 3 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index 34bb7f7..cccaead 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -178,7 +178,6 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
 	fdt->open_fds = (fd_set *)data;
 	data += nr / BITS_PER_BYTE;
 	fdt->close_on_exec = (fd_set *)data;
-	INIT_RCU_HEAD(&fdt->rcu);
 	fdt->next = NULL;
 
 	return fdt;
@@ -312,7 +311,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
 	new_fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init;
 	new_fdt->open_fds = (fd_set *)&newf->open_fds_init;
 	new_fdt->fd = &newf->fd_array[0];
-	INIT_RCU_HEAD(&new_fdt->rcu);
 	new_fdt->next = NULL;
 
 	spin_lock(&oldf->file_lock);
@@ -430,7 +428,6 @@ struct files_struct init_files = {
 		.fd		= &init_files.fd_array[0],
 		.close_on_exec	= (fd_set *)&init_files.close_on_exec_init,
 		.open_fds	= (fd_set *)&init_files.open_fds_init,
-		.rcu		= RCU_HEAD_INIT,
 	},
 	.file_lock	= __SPIN_LOCK_UNLOCKED(init_task.file_lock),
 };
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 4b37f7c..ea38c65 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -75,12 +75,33 @@ static inline bool bdi_work_on_stack(struct bdi_work *work)
 	return test_bit(WS_ONSTACK_B, &work->state);
 }
 
-static inline void bdi_work_init(struct bdi_work *work,
-				 struct wb_writeback_args *args)
+static inline void __bdi_work_init(struct bdi_work *work,
+				   struct wb_writeback_args *args,
+				   int on_stack)
 {
-	INIT_RCU_HEAD(&work->rcu_head);
 	work->args = *args;
 	work->state = WS_USED;
+	if (on_stack) {
+		work->state |= WS_ONSTACK;
+		init_rcu_head_on_stack(&work->rcu_head);
+	}
+}
+
+static inline void bdi_work_init(struct bdi_work *work,
+				 struct wb_writeback_args *args)
+{
+	__bdi_work_init(work, args, false);
+}
+
+static inline void bdi_work_init_on_stack(struct bdi_work *work,
+					  struct wb_writeback_args *args)
+{
+	__bdi_work_init(work, args, true);
+}
+
+static inline void bdi_destroy_work_on_stack(struct bdi_work *work)
+{
+	destroy_rcu_head_on_stack(&work->rcu_head);
 }
 
 /**
@@ -233,11 +254,11 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi,
 	};
 	struct bdi_work work;
 
-	bdi_work_init(&work, &args);
-	work.state |= WS_ONSTACK;
+	bdi_work_init_on_stack(&work, &args);
 
 	bdi_queue_work(bdi, &work);
 	bdi_wait_on_work_clear(&work);
+	bdi_destroy_work_on_stack(&work);
 }
 
 /**
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index e238ab2..7444e6f 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -456,7 +456,6 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
 	}
 
 	/* everything is up and running, commence */
-	INIT_RCU_HEAD(&p->rcu_head);
 	rcu_assign_pointer(ptbl->part[partno], p);
 
 	/* suppress uevent if the disk supresses it */
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 08/11] mm: remove all rcu head initializations
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
                   ` (6 preceding siblings ...)
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 07/11] fs: remove all rcu head initializations, except on_stack initializations Paul E. McKenney
@ 2010-05-11 23:33 ` Paul E. McKenney
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 09/11] selinux: " Paul E. McKenney
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Paul E. McKenney, Mathieu Desnoyers,
	Cc: Christoph Lameter, Pekka Enberg, Matt Mackall

Remove all rcu head inits. We don't care about the RCU head state before passing
it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
keep track of objects on stack.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Cc: Christoph Lameter <cl@linux-foundation.org>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
 mm/backing-dev.c |    1 -
 mm/slob.c        |    1 -
 2 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 707d0dc..f03d8d6 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -663,7 +663,6 @@ int bdi_init(struct backing_dev_info *bdi)
 	bdi->max_ratio = 100;
 	bdi->max_prop_frac = PROP_FRAC_BASE;
 	spin_lock_init(&bdi->wb_lock);
-	INIT_RCU_HEAD(&bdi->rcu_head);
 	INIT_LIST_HEAD(&bdi->bdi_list);
 	INIT_LIST_HEAD(&bdi->wb_list);
 	INIT_LIST_HEAD(&bdi->work_list);
diff --git a/mm/slob.c b/mm/slob.c
index 837ebd6..6de238d 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -647,7 +647,6 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
 	if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {
 		struct slob_rcu *slob_rcu;
 		slob_rcu = b + (c->size - sizeof(struct slob_rcu));
-		INIT_RCU_HEAD(&slob_rcu->head);
 		slob_rcu->size = c->size;
 		call_rcu(&slob_rcu->head, kmem_rcu_free);
 	} else {
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 09/11] selinux: remove all rcu head initializations
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
                   ` (7 preceding siblings ...)
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 08/11] mm: remove all rcu head initializations Paul E. McKenney
@ 2010-05-11 23:33 ` Paul E. McKenney
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 10/11] rcu head remove init Paul E. McKenney
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 11/11] tree/tiny rcu: Add debug RCU head objects (v5) Paul E. McKenney
  10 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Paul E. McKenney, Mathieu Desnoyers,
	Stephen Smalley, Eric Paris

Remove all rcu head inits. We don't care about the RCU head state before passing
it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
keep track of objects on stack.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Reviewed-by: James Morris <jmorris@namei.org>
Cc: Eric Paris <eparis@parisplace.org>
---
 security/selinux/avc.c     |    1 -
 security/selinux/netnode.c |    2 --
 2 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 989fef8..bf4e3bc 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -288,7 +288,6 @@ static struct avc_node *avc_alloc_node(void)
 	if (!node)
 		goto out;
 
-	INIT_RCU_HEAD(&node->rhead);
 	INIT_HLIST_NODE(&node->list);
 	avc_cache_stats_incr(allocations);
 
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index dc92792..65ebfe9 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -183,8 +183,6 @@ static void sel_netnode_insert(struct sel_netnode *node)
 		BUG();
 	}
 
-	INIT_RCU_HEAD(&node->rcu);
-
 	/* we need to impose a limit on the growth of the hash table so check
 	 * this bucket to make sure it is within the specified bounds */
 	list_add_rcu(&node->list, &sel_netnode_hash[idx].list);
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 10/11] rcu head remove init
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
                   ` (8 preceding siblings ...)
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 09/11] selinux: " Paul E. McKenney
@ 2010-05-11 23:33 ` Paul E. McKenney
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 11/11] tree/tiny rcu: Add debug RCU head objects (v5) Paul E. McKenney
  10 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Mathieu Desnoyers, David S. Miller,
	Paul E. McKenney, Alexey Dobriyan

From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>

RCU heads really don't need to be initialized. Their state before call_rcu()
really does not matter.

We need to keep init/destroy_rcu_head_on_stack() though, since we want
debugobjects to be able to keep track of these objects.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
CC: David S. Miller <davem@davemloft.net>
CC: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
CC: akpm@linux-foundation.org
CC: mingo@elte.hu
CC: laijs@cn.fujitsu.com
CC: dipankar@in.ibm.com
CC: josh@joshtriplett.org
CC: dvhltc@us.ibm.com
CC: niv@us.ibm.com
CC: tglx@linutronix.de
CC: peterz@infradead.org
CC: rostedt@goodmis.org
CC: Valdis.Kletnieks@vt.edu
CC: dhowells@redhat.com
CC: eric.dumazet@gmail.com
CC: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
 include/linux/rcupdate.h |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index b653b4a..3a1a70d 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -73,12 +73,6 @@ extern void rcu_init(void);
 #error "Unknown RCU implementation specified to kernel configuration"
 #endif
 
-#define RCU_HEAD_INIT	{ .next = NULL, .func = NULL }
-#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT
-#define INIT_RCU_HEAD(ptr) do { \
-       (ptr)->next = NULL; (ptr)->func = NULL; \
-} while (0)
-
 static inline void init_rcu_head_on_stack(struct rcu_head *head)
 {
 }
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RFC tip/core/rcu 11/11] tree/tiny rcu: Add debug RCU head objects (v5)
  2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
                   ` (9 preceding siblings ...)
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 10/11] rcu head remove init Paul E. McKenney
@ 2010-05-11 23:33 ` Paul E. McKenney
  10 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-11 23:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, dvhltc,
	niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
	eric.dumazet, Mathieu Desnoyers, David S. Miller,
	Paul E. McKenney, Alexey Dobriyan

From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>

Helps finding racy users of call_rcu(), which results in hangs because list
entries are overwritten and/or skipped.

Changelog since v4:
- Bissectability is now OK
- Now generate a WARN_ON_ONCE() for non-initialized rcu_head passed to
  call_rcu(). Statically initialized objects are detected with
  object_is_static().
- Rename rcu_head_init_on_stack to init_rcu_head_on_stack.
- Remove init_rcu_head() completely.

Changelog since v3:
- Include comments from Lai Jiangshan

This new patch version is based on the debugobjects with the newly introduced
"active state" tracker.

Non-initialized entries are all considered as "statically initialized". An
activation fixup (triggered by call_rcu()) takes care of performing the debug
object initialization without issuing any warning. Since we cannot increase the
size of struct rcu_head, I don't see much room to put an identifier for
statically initialized rcu_head structures. So for now, we have to live without
"activation without explicit init" detection. But the main purpose of this debug
option is to detect double-activations (double call_rcu() use of a rcu_head
before the callback is executed), which is correctly addressed here.

This also detects potential internal RCU callback corruption, which would cause
the callbacks to be executed twice.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
CC: David S. Miller <davem@davemloft.net>
CC: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
CC: akpm@linux-foundation.org
CC: mingo@elte.hu
CC: laijs@cn.fujitsu.com
CC: dipankar@in.ibm.com
CC: josh@joshtriplett.org
CC: dvhltc@us.ibm.com
CC: niv@us.ibm.com
CC: tglx@linutronix.de
CC: peterz@infradead.org
CC: rostedt@goodmis.org
CC: Valdis.Kletnieks@vt.edu
CC: dhowells@redhat.com
CC: eric.dumazet@gmail.com
CC: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
 include/linux/rcupdate.h |   49 +++++++++++++
 kernel/rcupdate.c        |  170 ++++++++++++++++++++++++++++++++++++++++++++++
 kernel/rcutiny.c         |    2 +
 kernel/rcutree.c         |    2 +
 lib/Kconfig.debug        |    6 ++
 5 files changed, 229 insertions(+), 0 deletions(-)

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 3a1a70d..2f9e56c 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -40,6 +40,7 @@
 #include <linux/seqlock.h>
 #include <linux/lockdep.h>
 #include <linux/completion.h>
+#include <linux/debugobjects.h>
 
 #ifdef CONFIG_RCU_TORTURE_TEST
 extern int rcutorture_runnable; /* for sysctl */
@@ -73,6 +74,16 @@ extern void rcu_init(void);
 #error "Unknown RCU implementation specified to kernel configuration"
 #endif
 
+/*
+ * init_rcu_head_on_stack()/destroy_rcu_head_on_stack() are needed for dynamic
+ * initialization and destruction of rcu_head on the stack. rcu_head structures
+ * allocated dynamically in the heap or defined statically don't need any
+ * initialization.
+ */
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+extern void init_rcu_head_on_stack(struct rcu_head *head);
+extern void destroy_rcu_head_on_stack(struct rcu_head *head);
+#else /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
 static inline void init_rcu_head_on_stack(struct rcu_head *head)
 {
 }
@@ -80,6 +91,7 @@ static inline void init_rcu_head_on_stack(struct rcu_head *head)
 static inline void destroy_rcu_head_on_stack(struct rcu_head *head)
 {
 }
+#endif	/* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
@@ -511,4 +523,41 @@ extern void call_rcu(struct rcu_head *head,
 extern void call_rcu_bh(struct rcu_head *head,
 			void (*func)(struct rcu_head *head));
 
+/*
+ * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
+ * by call_rcu() and rcu callback execution, and are therefore not part of the
+ * RCU API. Leaving in rcupdate.h because they are used by all RCU flavors.
+ */
+
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+# define STATE_RCU_HEAD_READY	0
+# define STATE_RCU_HEAD_QUEUED	1
+
+extern struct debug_obj_descr rcuhead_debug_descr;
+
+static inline void debug_rcu_head_queue(struct rcu_head *head)
+{
+	debug_object_activate(head, &rcuhead_debug_descr);
+	debug_object_active_state(head, &rcuhead_debug_descr,
+				  STATE_RCU_HEAD_READY,
+				  STATE_RCU_HEAD_QUEUED);
+}
+
+static inline void debug_rcu_head_unqueue(struct rcu_head *head)
+{
+	debug_object_active_state(head, &rcuhead_debug_descr,
+				  STATE_RCU_HEAD_QUEUED,
+				  STATE_RCU_HEAD_READY);
+	debug_object_deactivate(head, &rcuhead_debug_descr);
+}
+#else	/* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+static inline void debug_rcu_head_queue(struct rcu_head *head)
+{
+}
+
+static inline void debug_rcu_head_unqueue(struct rcu_head *head)
+{
+}
+#endif	/* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+
 #endif /* __LINUX_RCUPDATE_H */
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 72a8dc9..5ab5a91 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -114,3 +114,173 @@ int rcu_my_thread_group_empty(void)
 }
 EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty);
 #endif /* #ifdef CONFIG_PROVE_RCU */
+
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+static inline void debug_init_rcu_head(struct rcu_head *head)
+{
+	debug_object_init(head, &rcuhead_debug_descr);
+}
+
+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.
+		 */
+#ifndef CONFIG_PREEMPT
+		WARN_ON(1);
+		return 0;
+#else
+		if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
+		    irqs_disabled()) {
+			WARN_ON(1);
+			return 0;
+		}
+		rcu_barrier();
+		rcu_barrier_sched();
+		rcu_barrier_bh();
+		debug_object_init(head, &rcuhead_debug_descr);
+		return 1;
+#endif
+	default:
+		return 0;
+	}
+}
+
+/*
+ * fixup_activate is called when:
+ * - an active object is activated
+ * - an unknown object is activated (might be a statically initialized object)
+ * Activation is performed internally by call_rcu().
+ */
+static int rcuhead_fixup_activate(void *addr, enum debug_obj_state state)
+{
+	struct rcu_head *head = addr;
+
+	switch (state) {
+
+	case ODEBUG_STATE_NOTAVAILABLE:
+		/*
+		 * This is not really a fixup. We just make sure that it is
+		 * tracked in the object tracker.
+		 */
+		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.
+		 */
+#ifndef CONFIG_PREEMPT
+		WARN_ON(1);
+		return 0;
+#else
+		if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
+		    irqs_disabled()) {
+			WARN_ON(1);
+			return 0;
+		}
+		rcu_barrier();
+		rcu_barrier_sched();
+		rcu_barrier_bh();
+		debug_object_activate(head, &rcuhead_debug_descr);
+		return 1;
+#endif
+	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.
+		 */
+#ifndef CONFIG_PREEMPT
+		WARN_ON(1);
+		return 0;
+#else
+		if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
+		    irqs_disabled()) {
+			WARN_ON(1);
+			return 0;
+		}
+		rcu_barrier();
+		rcu_barrier_sched();
+		rcu_barrier_bh();
+		debug_object_free(head, &rcuhead_debug_descr);
+		return 1;
+#endif
+	default:
+		return 0;
+	}
+}
+
+/**
+ * init_rcu_head_on_stack() - initialize on-stack rcu_head for debugobjects
+ * @head: pointer to rcu_head structure to be initialized
+ *
+ * This function informs debugobjects of a new rcu_head structure that
+ * has been allocated as an auto variable on the stack.  This function
+ * is not required for rcu_head structures that are statically defined or
+ * that are dynamically allocated on the heap.  This function has no
+ * effect for !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds.
+ */
+void init_rcu_head_on_stack(struct rcu_head *head)
+{
+	debug_object_init_on_stack(head, &rcuhead_debug_descr);
+}
+EXPORT_SYMBOL_GPL(init_rcu_head_on_stack);
+
+/**
+ * destroy_rcu_head_on_stack() - destroy on-stack rcu_head for debugobjects
+ * @head: pointer to rcu_head structure to be initialized
+ *
+ * This function informs debugobjects that an on-stack rcu_head structure
+ * is about to go out of scope.  As with init_rcu_head_on_stack(), this
+ * function is not required for rcu_head structures that are statically
+ * defined or that are dynamically allocated on the heap.  Also as with
+ * init_rcu_head_on_stack(), this function has no effect for
+ * !CONFIG_DEBUG_OBJECTS_RCU_HEAD kernel builds.
+ */
+void destroy_rcu_head_on_stack(struct rcu_head *head)
+{
+	debug_object_free(head, &rcuhead_debug_descr);
+}
+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 */
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
index 38729d3..196ec02 100644
--- a/kernel/rcutiny.c
+++ b/kernel/rcutiny.c
@@ -169,6 +169,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
 	while (list) {
 		next = list->next;
 		prefetch(next);
+		debug_rcu_head_unqueue(list);
 		list->func(list);
 		list = next;
 	}
@@ -211,6 +212,7 @@ static void __call_rcu(struct rcu_head *head,
 {
 	unsigned long flags;
 
+	debug_rcu_head_queue(head);
 	head->func = func;
 	head->next = NULL;
 
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index d443734..d5bc439 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1112,6 +1112,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 	while (list) {
 		next = list->next;
 		prefetch(next);
+		debug_rcu_head_unqueue(list);
 		list->func(list);
 		list = next;
 		if (++count >= rdp->blimit)
@@ -1388,6 +1389,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
 	unsigned long flags;
 	struct rcu_data *rdp;
 
+	debug_rcu_head_queue(head);
 	head->func = func;
 	head->next = NULL;
 
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 930a9e5..8689646 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -307,6 +307,12 @@ config DEBUG_OBJECTS_WORK
 	  work queue routines to track the life time of work objects and
 	  validate the work operations.
 
+config DEBUG_OBJECTS_RCU_HEAD
+	bool "Debug RCU callbacks objects"
+	depends on DEBUG_OBJECTS
+	help
+	  Enable this to turn on debugging of RCU list heads (call_rcu() usage).
+
 config DEBUG_OBJECTS_ENABLE_DEFAULT
 	int "debug_objects bootup default value (0-1)"
         range 0 1
-- 
1.7.0.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH RFC tip/core/rcu 06/11] staging: remove all rcu head initializations
  2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 06/11] staging: " Paul E. McKenney
@ 2010-05-11 23:45   ` Greg KH
  2010-05-12  0:08     ` Paul E. McKenney
  0 siblings, 1 reply; 16+ messages in thread
From: Greg KH @ 2010-05-11 23:45 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: linux-kernel, mingo, laijs, dipankar, akpm, mathieu.desnoyers,
	josh, dvhltc, niv, tglx, peterz, rostedt, Valdis.Kletnieks,
	dhowells, eric.dumazet, Mathieu Desnoyers

On Tue, May 11, 2010 at 04:33:01PM -0700, Paul E. McKenney wrote:
> Remove all rcu head inits. We don't care about the RCU head state before passing
> it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
> keep track of objects on stack.
> 
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> Cc: Greg Kroah-Hartman <gregkh@suse.de>
> ---
>  drivers/staging/batman-adv/hard-interface.c |    1 -

Is this safe to apply to my tree now?  Or do you want to take it through
your tree as it depends on other stuff?

If your tree, no objection from me, feel free to add:
	Acked-by: Greg Kroah-Hartman <gregkh@suse.de>

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RFC tip/core/rcu 06/11] staging: remove all rcu head initializations
  2010-05-11 23:45   ` Greg KH
@ 2010-05-12  0:08     ` Paul E. McKenney
  2010-05-14 20:16       ` Greg KH
  0 siblings, 1 reply; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-12  0:08 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-kernel, mingo, laijs, dipankar, akpm, mathieu.desnoyers,
	josh, dvhltc, niv, tglx, peterz, rostedt, Valdis.Kletnieks,
	dhowells, eric.dumazet, Mathieu Desnoyers

On Tue, May 11, 2010 at 04:45:23PM -0700, Greg KH wrote:
> On Tue, May 11, 2010 at 04:33:01PM -0700, Paul E. McKenney wrote:
> > Remove all rcu head inits. We don't care about the RCU head state before passing
> > it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
> > keep track of objects on stack.
> > 
> > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> > Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> > Cc: Greg Kroah-Hartman <gregkh@suse.de>
> > ---
> >  drivers/staging/batman-adv/hard-interface.c |    1 -
> 
> Is this safe to apply to my tree now?  Or do you want to take it through
> your tree as it depends on other stuff?

Because the rcu_head in this case is not in an auto (on-stack) variable,
this commit is safe to apply to your tree now.

Let me know when you have applied it, and I will happily remove it
from mine.  ;-)

							Thanx, Paul

> If your tree, no objection from me, feel free to add:
> 	Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
> 
> thanks,
> 
> greg k-h

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RFC tip/core/rcu 06/11] staging: remove all rcu head initializations
  2010-05-12  0:08     ` Paul E. McKenney
@ 2010-05-14 20:16       ` Greg KH
  2010-05-15 21:50         ` Paul E. McKenney
  0 siblings, 1 reply; 16+ messages in thread
From: Greg KH @ 2010-05-14 20:16 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Greg KH, linux-kernel, mingo, laijs, dipankar, akpm,
	mathieu.desnoyers, josh, dvhltc, niv, tglx, peterz, rostedt,
	Valdis.Kletnieks, dhowells, eric.dumazet, Mathieu Desnoyers

On Tue, May 11, 2010 at 05:08:21PM -0700, Paul E. McKenney wrote:
> On Tue, May 11, 2010 at 04:45:23PM -0700, Greg KH wrote:
> > On Tue, May 11, 2010 at 04:33:01PM -0700, Paul E. McKenney wrote:
> > > Remove all rcu head inits. We don't care about the RCU head state before passing
> > > it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
> > > keep track of objects on stack.
> > > 
> > > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> > > Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> > > Cc: Greg Kroah-Hartman <gregkh@suse.de>
> > > ---
> > >  drivers/staging/batman-adv/hard-interface.c |    1 -
> > 
> > Is this safe to apply to my tree now?  Or do you want to take it through
> > your tree as it depends on other stuff?
> 
> Because the rcu_head in this case is not in an auto (on-stack) variable,
> this commit is safe to apply to your tree now.
> 
> Let me know when you have applied it, and I will happily remove it
> from mine.  ;-)

Now queued up.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RFC tip/core/rcu 06/11] staging: remove all rcu head initializations
  2010-05-14 20:16       ` Greg KH
@ 2010-05-15 21:50         ` Paul E. McKenney
  0 siblings, 0 replies; 16+ messages in thread
From: Paul E. McKenney @ 2010-05-15 21:50 UTC (permalink / raw)
  To: Greg KH
  Cc: Greg KH, linux-kernel, mingo, laijs, dipankar, akpm,
	mathieu.desnoyers, josh, dvhltc, niv, tglx, peterz, rostedt,
	Valdis.Kletnieks, dhowells, eric.dumazet, Mathieu Desnoyers

On Fri, May 14, 2010 at 01:16:40PM -0700, Greg KH wrote:
> On Tue, May 11, 2010 at 05:08:21PM -0700, Paul E. McKenney wrote:
> > On Tue, May 11, 2010 at 04:45:23PM -0700, Greg KH wrote:
> > > On Tue, May 11, 2010 at 04:33:01PM -0700, Paul E. McKenney wrote:
> > > > Remove all rcu head inits. We don't care about the RCU head state before passing
> > > > it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can
> > > > keep track of objects on stack.
> > > > 
> > > > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> > > > Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> > > > Cc: Greg Kroah-Hartman <gregkh@suse.de>
> > > > ---
> > > >  drivers/staging/batman-adv/hard-interface.c |    1 -
> > > 
> > > Is this safe to apply to my tree now?  Or do you want to take it through
> > > your tree as it depends on other stuff?
> > 
> > Because the rcu_head in this case is not in an auto (on-stack) variable,
> > this commit is safe to apply to your tree now.
> > 
> > Let me know when you have applied it, and I will happily remove it
> > from mine.  ;-)
> 
> Now queued up.

And happily removed from mine.

							Thanx, Paul

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2010-05-15 21:50 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-11 23:32 [PATCH tip/core/rcu 0/11] Add debugobjects checking to RCU callbacks Paul E. McKenney
2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 01/11] Debugobjects transition check Paul E. McKenney
2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 02/11] rcu head introduce rcu head init on stack Paul E. McKenney
2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 03/11] rcu: remove all rcu head initializations, except on_stack initializations Paul E. McKenney
2010-05-11 23:32 ` [PATCH RFC tip/core/rcu 04/11] powerpc: remove all rcu head initializations Paul E. McKenney
2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 05/11] block: " Paul E. McKenney
2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 06/11] staging: " Paul E. McKenney
2010-05-11 23:45   ` Greg KH
2010-05-12  0:08     ` Paul E. McKenney
2010-05-14 20:16       ` Greg KH
2010-05-15 21:50         ` Paul E. McKenney
2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 07/11] fs: remove all rcu head initializations, except on_stack initializations Paul E. McKenney
2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 08/11] mm: remove all rcu head initializations Paul E. McKenney
2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 09/11] selinux: " Paul E. McKenney
2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 10/11] rcu head remove init Paul E. McKenney
2010-05-11 23:33 ` [PATCH RFC tip/core/rcu 11/11] tree/tiny rcu: Add debug RCU head objects (v5) Paul E. McKenney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).