All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 0/3] Catching del_timer_sync() on uninitialized timers
@ 2011-11-08  3:48 Stephen Boyd
  2011-11-08  3:48 ` [PATCHv2 1/3] debugobjects: Be smarter about static objects Stephen Boyd
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Stephen Boyd @ 2011-11-08  3:48 UTC (permalink / raw)
  To: linux-kernel; +Cc: Thomas Gleixner, John Stultz, Christine Chan, Andrew Morton

These are an update for previous patches sent by Christine. I've
reworked them to hopefully address Thomas' comments. The new
patch is the first patch, which tries to actually use debugobjects
code to print the warning instead of relying on users of the API
to do so (as suggested by Thomas).

Christine Chan (2):
  debugobjects: Extend to assert that an object is initialized
  kernel/timer.c: Use debugobjects to catch deletion of uninitialized
    timers

Stephen Boyd (1):
  debugobjects: Be smarter about static objects

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Christine Chan <cschan@codeaurora.org>
Cc: Andrew Morton <akpm@linux-foundation.org>

 Documentation/DocBook/debugobjects.tmpl |   50 +++++++++++++++++++++++++
 include/linux/debugobjects.h            |    6 +++
 kernel/timer.c                          |   62 ++++++++++++++++++++++++++++---
 lib/debugobjects.c                      |   53 ++++++++++++++++++++++++--
 4 files changed, 161 insertions(+), 10 deletions(-)

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

* [PATCHv2 1/3] debugobjects: Be smarter about static objects
  2011-11-08  3:48 [PATCHv2 0/3] Catching del_timer_sync() on uninitialized timers Stephen Boyd
@ 2011-11-08  3:48 ` Stephen Boyd
  2011-11-28 14:18   ` [tip:core/debugobjects] " tip-bot for Stephen Boyd
  2011-11-28 14:20   ` [tip:core/debugobjects] timer: Setup uninitialized timer with a stub callback tip-bot for Stephen Boyd
  2011-11-08  3:48 ` [PATCHv2 2/3] debugobjects: Extend to assert that an object is initialized Stephen Boyd
  2011-11-08  3:48 ` [PATCHv2 3/3] kernel/timer.c: Use debugobjects to catch deletion of uninitialized timers Stephen Boyd
  2 siblings, 2 replies; 12+ messages in thread
From: Stephen Boyd @ 2011-11-08  3:48 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Christine Chan, John Stultz, Thomas Gleixner

Remove the WARN_ON() in timer_fixup_activate() and actually use
the return code from fixup to tell the debugobjects code to print
a warning. This provides better diagnostic information via a nice
debugobjects warning instead of a simple WARN_ON(1) in the timer
code with no information as to what is wrong. We also assign a
dummy timer callback so that if the timer is actually set to
fire we don't oops.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: Christine Chan <cschan@codeaurora.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/timer.c     |    9 ++++++++-
 lib/debugobjects.c |   15 +++++++++++----
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/kernel/timer.c b/kernel/timer.c
index dbaa624..317087d 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -427,6 +427,12 @@ static int timer_fixup_init(void *addr, enum debug_obj_state state)
 	}
 }
 
+/* Stub timer callback for improperly used timers. */
+static void stub_timer(unsigned long data)
+{
+	WARN_ON(1);
+}
+
 /*
  * fixup_activate is called when:
  * - an active object is activated
@@ -450,7 +456,8 @@ static int timer_fixup_activate(void *addr, enum debug_obj_state state)
 			debug_object_activate(timer, &timer_debug_descr);
 			return 0;
 		} else {
-			WARN_ON_ONCE(1);
+			setup_timer(timer, stub_timer, 0);
+			return 1;
 		}
 		return 0;
 
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index a78b7c6..0b07cc5 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -268,12 +268,15 @@ static void debug_print_object(struct debug_obj *obj, char *msg)
  * Try to repair the damage, so we have a better chance to get useful
  * debug output.
  */
-static void
+static int
 debug_object_fixup(int (*fixup)(void *addr, enum debug_obj_state state),
 		   void * addr, enum debug_obj_state state)
 {
+	int fixed = 0;
 	if (fixup)
-		debug_objects_fixups += fixup(addr, state);
+		fixed = fixup(addr, state);
+	debug_objects_fixups += fixed;
+	return fixed;
 }
 
 static void debug_object_is_on_stack(void *addr, int onstack)
@@ -386,6 +389,9 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr)
 	struct debug_bucket *db;
 	struct debug_obj *obj;
 	unsigned long flags;
+	struct debug_obj o = { .object = addr,
+			       .state = ODEBUG_STATE_NOTAVAILABLE,
+			       .descr = descr };
 
 	if (!debug_objects_enabled)
 		return;
@@ -425,8 +431,9 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr)
 	 * let the type specific code decide whether this is
 	 * true or not.
 	 */
-	debug_object_fixup(descr->fixup_activate, addr,
-			   ODEBUG_STATE_NOTAVAILABLE);
+	if (debug_object_fixup(descr->fixup_activate, addr,
+			   ODEBUG_STATE_NOTAVAILABLE))
+		debug_print_object(&o, "activate");
 }
 
 /**
-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

* [PATCHv2 2/3] debugobjects: Extend to assert that an object is initialized
  2011-11-08  3:48 [PATCHv2 0/3] Catching del_timer_sync() on uninitialized timers Stephen Boyd
  2011-11-08  3:48 ` [PATCHv2 1/3] debugobjects: Be smarter about static objects Stephen Boyd
@ 2011-11-08  3:48 ` Stephen Boyd
  2011-11-28 14:19   ` [tip:core/debugobjects] " tip-bot for Christine Chan
  2011-11-08  3:48 ` [PATCHv2 3/3] kernel/timer.c: Use debugobjects to catch deletion of uninitialized timers Stephen Boyd
  2 siblings, 1 reply; 12+ messages in thread
From: Stephen Boyd @ 2011-11-08  3:48 UTC (permalink / raw)
  To: linux-kernel; +Cc: Christine Chan, Andrew Morton, Thomas Gleixner, John Stultz

From: Christine Chan <cschan@codeaurora.org>

Calling del_timer_sync() on an uninitialized timer leads to a
never ending loop in lock_timer_base() that spins checking for a
non-NULL timer base. Add an assertion to debugobjects to catch
usage of uninitialized objects so that we can initialize timers
in the del_timer_sync() path before it calls lock_timer_base().

Signed-off-by: Christine Chan <cschan@codeaurora.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[sboyd: Clarify commit message]
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 Documentation/DocBook/debugobjects.tmpl |   50 +++++++++++++++++++++++++++++++
 include/linux/debugobjects.h            |    6 ++++
 lib/debugobjects.c                      |   38 +++++++++++++++++++++++
 3 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/Documentation/DocBook/debugobjects.tmpl b/Documentation/DocBook/debugobjects.tmpl
index 08ff908..24979f6 100644
--- a/Documentation/DocBook/debugobjects.tmpl
+++ b/Documentation/DocBook/debugobjects.tmpl
@@ -96,6 +96,7 @@
 	<listitem><para>debug_object_deactivate</para></listitem>
 	<listitem><para>debug_object_destroy</para></listitem>
 	<listitem><para>debug_object_free</para></listitem>
+	<listitem><para>debug_object_assert_init</para></listitem>
       </itemizedlist>
       Each of these functions takes the address of the real object and
       a pointer to the object type specific debug description
@@ -273,6 +274,26 @@
 	debug checks.
       </para>
     </sect1>
+
+    <sect1 id="debug_object_assert_init">
+      <title>debug_object_assert_init</title>
+      <para>
+	This function is called to assert that an object has been
+	initialized.
+      </para>
+      <para>
+	When the real object is not tracked by debugobjects, it calls
+	fixup_assert_init of the object type description structure
+	provided by the caller, with the hardcoded object state
+	ODEBUG_NOT_AVAILABLE. The fixup function can correct the problem
+	by calling debug_object_init and other specific initializing
+	functions.
+      </para>
+      <para>
+	When the real object is already tracked by debugobjects it is
+	ignored.
+      </para>
+    </sect1>
   </chapter>
   <chapter id="fixupfunctions">
     <title>Fixup functions</title>
@@ -381,6 +402,35 @@
 	statistics.
       </para>
     </sect1>
+    <sect1 id="fixup_assert_init">
+      <title>fixup_assert_init</title>
+      <para>
+	This function is called from the debug code whenever a problem
+	in debug_object_assert_init is detected.
+      </para>
+      <para>
+	Called from debug_object_assert_init() with a hardcoded state
+	ODEBUG_STATE_NOTAVAILABLE when the object is not found in the
+	debug bucket.
+      </para>
+      <para>
+	The function returns 1 when the fixup was successful,
+	otherwise 0. The return value is used to update the
+	statistics.
+      </para>
+      <para>
+	Note, this function should make sure debug_object_init() is
+	called before returning.
+      </para>
+      <para>
+	The handling of statically initialized objects is a special
+	case. The fixup function should check if this is a legitimate
+	case of a statically initialized object or not. In this case only
+	debug_object_init() should be called to make the object known to
+	the tracker. Then the function should return 0 because this is not
+	a real fixup.
+      </para>
+    </sect1>
   </chapter>
   <chapter id="bugs">
     <title>Known Bugs And Assumptions</title>
diff --git a/include/linux/debugobjects.h b/include/linux/debugobjects.h
index 65970b8..0e5f578 100644
--- a/include/linux/debugobjects.h
+++ b/include/linux/debugobjects.h
@@ -46,6 +46,8 @@ struct debug_obj {
  *			fails
  * @fixup_free:		fixup function, which is called when the free check
  *			fails
+ * @fixup_assert_init:  fixup function, which is called when the assert_init
+ *			check fails
  */
 struct debug_obj_descr {
 	const char		*name;
@@ -54,6 +56,7 @@ struct debug_obj_descr {
 	int (*fixup_activate)	(void *addr, enum debug_obj_state state);
 	int (*fixup_destroy)	(void *addr, enum debug_obj_state state);
 	int (*fixup_free)	(void *addr, enum debug_obj_state state);
+	int (*fixup_assert_init)(void *addr, enum debug_obj_state state);
 };
 
 #ifdef CONFIG_DEBUG_OBJECTS
@@ -64,6 +67,7 @@ extern void debug_object_activate  (void *addr, struct debug_obj_descr *descr);
 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);
+extern void debug_object_assert_init(void *addr, struct debug_obj_descr *descr);
 
 /*
  * Active state:
@@ -89,6 +93,8 @@ static inline void
 debug_object_destroy   (void *addr, struct debug_obj_descr *descr) { }
 static inline void
 debug_object_free      (void *addr, struct debug_obj_descr *descr) { }
+static inline void
+debug_object_assert_init(void *addr, struct debug_obj_descr *descr) { }
 
 static inline void debug_objects_early_init(void) { }
 static inline void debug_objects_mem_init(void) { }
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 0b07cc5..be066fa 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -570,6 +570,44 @@ out_unlock:
 }
 
 /**
+ * debug_object_assert_init - debug checks when object should be init-ed
+ * @addr:	address of the object
+ * @descr:	pointer to an object specific debug description structure
+ */
+void debug_object_assert_init(void *addr, struct debug_obj_descr *descr)
+{
+	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) {
+		struct debug_obj o = { .object = addr,
+				       .state = ODEBUG_STATE_NOTAVAILABLE,
+				       .descr = descr };
+
+		raw_spin_unlock_irqrestore(&db->lock, flags);
+		/*
+		 * Maybe the object is static.  Let the type specific
+		 * code decide what to do.
+		 */
+		if (debug_object_fixup(descr->fixup_assert_init, addr,
+				ODEBUG_STATE_NOTAVAILABLE))
+			debug_print_object(&o, "assert_init");
+		return;
+	}
+
+	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
-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

* [PATCHv2 3/3] kernel/timer.c: Use debugobjects to catch deletion of uninitialized timers
  2011-11-08  3:48 [PATCHv2 0/3] Catching del_timer_sync() on uninitialized timers Stephen Boyd
  2011-11-08  3:48 ` [PATCHv2 1/3] debugobjects: Be smarter about static objects Stephen Boyd
  2011-11-08  3:48 ` [PATCHv2 2/3] debugobjects: Extend to assert that an object is initialized Stephen Boyd
@ 2011-11-08  3:48 ` Stephen Boyd
  2011-11-28 14:21   ` [tip:core/debugobjects] timer: " tip-bot for Christine Chan
  2 siblings, 1 reply; 12+ messages in thread
From: Stephen Boyd @ 2011-11-08  3:48 UTC (permalink / raw)
  To: linux-kernel; +Cc: Christine Chan, Andrew Morton, Thomas Gleixner, John Stultz

From: Christine Chan <cschan@codeaurora.org>

del_timer_sync() calls debug_object_assert_init() to assert that
a timer has been initialized before calling lock_timer_base().
lock_timer_base() would spin forever on a NULL(uninit-ed) base.
The check is added to del_timer() to prevent silent failure, even
though it would not get stuck in an infinite loop.

Signed-off-by: Christine Chan <cschan@codeaurora.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[sboyd: Remove WARN, intialize timer function]
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 kernel/timer.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/kernel/timer.c b/kernel/timer.c
index 317087d..5fc5a76 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -487,12 +487,40 @@ static int timer_fixup_free(void *addr, enum debug_obj_state state)
 	}
 }
 
+/*
+ * fixup_assert_init is called when:
+ * - an untracked/uninit-ed object is found
+ */
+static int timer_fixup_assert_init(void *addr, enum debug_obj_state state)
+{
+	struct timer_list *timer = addr;
+
+	switch (state) {
+	case ODEBUG_STATE_NOTAVAILABLE:
+		if (timer->entry.prev == TIMER_ENTRY_STATIC) {
+			/*
+			 * This is not really a fixup. The timer was
+			 * statically initialized. We just make sure that it
+			 * is tracked in the object tracker.
+			 */
+			debug_object_init(timer, &timer_debug_descr);
+			return 0;
+		} else {
+			setup_timer(timer, stub_timer, 0);
+			return 1;
+		}
+	default:
+		return 0;
+	}
+}
+
 static struct debug_obj_descr timer_debug_descr = {
-	.name		= "timer_list",
-	.debug_hint	= timer_debug_hint,
-	.fixup_init	= timer_fixup_init,
-	.fixup_activate	= timer_fixup_activate,
-	.fixup_free	= timer_fixup_free,
+	.name			= "timer_list",
+	.debug_hint		= timer_debug_hint,
+	.fixup_init		= timer_fixup_init,
+	.fixup_activate		= timer_fixup_activate,
+	.fixup_free		= timer_fixup_free,
+	.fixup_assert_init	= timer_fixup_assert_init,
 };
 
 static inline void debug_timer_init(struct timer_list *timer)
@@ -515,6 +543,11 @@ static inline void debug_timer_free(struct timer_list *timer)
 	debug_object_free(timer, &timer_debug_descr);
 }
 
+static inline void debug_timer_assert_init(struct timer_list *timer)
+{
+	debug_object_assert_init(timer, &timer_debug_descr);
+}
+
 static void __init_timer(struct timer_list *timer,
 			 const char *name,
 			 struct lock_class_key *key);
@@ -538,6 +571,7 @@ EXPORT_SYMBOL_GPL(destroy_timer_on_stack);
 static inline void debug_timer_init(struct timer_list *timer) { }
 static inline void debug_timer_activate(struct timer_list *timer) { }
 static inline void debug_timer_deactivate(struct timer_list *timer) { }
+static inline void debug_timer_assert_init(struct timer_list *timer) { }
 #endif
 
 static inline void debug_init(struct timer_list *timer)
@@ -559,6 +593,11 @@ static inline void debug_deactivate(struct timer_list *timer)
 	trace_timer_cancel(timer);
 }
 
+static inline void debug_assert_init(struct timer_list *timer)
+{
+	debug_timer_assert_init(timer);
+}
+
 static void __init_timer(struct timer_list *timer,
 			 const char *name,
 			 struct lock_class_key *key)
@@ -909,6 +948,8 @@ int del_timer(struct timer_list *timer)
 	unsigned long flags;
 	int ret = 0;
 
+	debug_assert_init(timer);
+
 	timer_stats_timer_clear_start_info(timer);
 	if (timer_pending(timer)) {
 		base = lock_timer_base(timer, &flags);
@@ -939,6 +980,8 @@ int try_to_del_timer_sync(struct timer_list *timer)
 	unsigned long flags;
 	int ret = -1;
 
+	debug_assert_init(timer);
+
 	base = lock_timer_base(timer, &flags);
 
 	if (base->running_timer == timer)
-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

* [tip:core/debugobjects] debugobjects: Be smarter about static objects
  2011-11-08  3:48 ` [PATCHv2 1/3] debugobjects: Be smarter about static objects Stephen Boyd
@ 2011-11-28 14:18   ` tip-bot for Stephen Boyd
  2011-12-13 10:38     ` Thomas Gleixner
  2011-11-28 14:20   ` [tip:core/debugobjects] timer: Setup uninitialized timer with a stub callback tip-bot for Stephen Boyd
  1 sibling, 1 reply; 12+ messages in thread
From: tip-bot for Stephen Boyd @ 2011-11-28 14:18 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, sboyd, john.stultz, akpm, cschan, tglx

Commit-ID:  feac18dda25134005909e7770c77464e65608bd8
Gitweb:     http://git.kernel.org/tip/feac18dda25134005909e7770c77464e65608bd8
Author:     Stephen Boyd <sboyd@codeaurora.org>
AuthorDate: Mon, 7 Nov 2011 19:48:26 -0800
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 23 Nov 2011 18:49:22 +0100

debugobjects: Be smarter about static objects

Make debugobjects use the return code from the fixup function. That
allows us better diagnostics in the activate check than relying on a
WARN_ON() in the object specific code.

[ tglx@linutronix.de: Split out the debugobjects vs. the timer change ]

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: Christine Chan <cschan@codeaurora.org>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Link: http://lkml.kernel.org/r/1320724108-20788-2-git-send-email-sboyd@codeaurora.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 lib/debugobjects.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index a78b7c6..b7a5305 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -268,12 +268,16 @@ static void debug_print_object(struct debug_obj *obj, char *msg)
  * Try to repair the damage, so we have a better chance to get useful
  * debug output.
  */
-static void
+static int
 debug_object_fixup(int (*fixup)(void *addr, enum debug_obj_state state),
 		   void * addr, enum debug_obj_state state)
 {
+	int fixed = 0;
+
 	if (fixup)
-		debug_objects_fixups += fixup(addr, state);
+		fixed = fixup(addr, state);
+	debug_objects_fixups += fixed;
+	return fixed;
 }
 
 static void debug_object_is_on_stack(void *addr, int onstack)
@@ -386,6 +390,9 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr)
 	struct debug_bucket *db;
 	struct debug_obj *obj;
 	unsigned long flags;
+	struct debug_obj o = { .object = addr,
+			       .state = ODEBUG_STATE_NOTAVAILABLE,
+			       .descr = descr };
 
 	if (!debug_objects_enabled)
 		return;
@@ -425,8 +432,9 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr)
 	 * let the type specific code decide whether this is
 	 * true or not.
 	 */
-	debug_object_fixup(descr->fixup_activate, addr,
-			   ODEBUG_STATE_NOTAVAILABLE);
+	if (debug_object_fixup(descr->fixup_activate, addr,
+			   ODEBUG_STATE_NOTAVAILABLE))
+		debug_print_object(&o, "activate");
 }
 
 /**

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

* [tip:core/debugobjects] debugobjects: Extend to assert that an object is initialized
  2011-11-08  3:48 ` [PATCHv2 2/3] debugobjects: Extend to assert that an object is initialized Stephen Boyd
@ 2011-11-28 14:19   ` tip-bot for Christine Chan
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Christine Chan @ 2011-11-28 14:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, john.stultz, hpa, mingo, akpm, cschan, tglx, sboyd

Commit-ID:  b84d435cc228e87951f3bbabf6cc4a5f25d5fb16
Gitweb:     http://git.kernel.org/tip/b84d435cc228e87951f3bbabf6cc4a5f25d5fb16
Author:     Christine Chan <cschan@codeaurora.org>
AuthorDate: Mon, 7 Nov 2011 19:48:27 -0800
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 23 Nov 2011 18:49:22 +0100

debugobjects: Extend to assert that an object is initialized

Calling del_timer_sync() on an uninitialized timer leads to a
never ending loop in lock_timer_base() that spins checking for a
non-NULL timer base. Add an assertion to debugobjects to catch
usage of uninitialized objects so that we can initialize timers
in the del_timer_sync() path before it calls lock_timer_base().

[ sboyd@codeaurora.org: Clarify commit message ]

Signed-off-by: Christine Chan <cschan@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/1320724108-20788-3-git-send-email-sboyd@codeaurora.org
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 Documentation/DocBook/debugobjects.tmpl |   50 +++++++++++++++++++++++++++++++
 include/linux/debugobjects.h            |    6 ++++
 lib/debugobjects.c                      |   38 +++++++++++++++++++++++
 3 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/Documentation/DocBook/debugobjects.tmpl b/Documentation/DocBook/debugobjects.tmpl
index 08ff908..24979f6 100644
--- a/Documentation/DocBook/debugobjects.tmpl
+++ b/Documentation/DocBook/debugobjects.tmpl
@@ -96,6 +96,7 @@
 	<listitem><para>debug_object_deactivate</para></listitem>
 	<listitem><para>debug_object_destroy</para></listitem>
 	<listitem><para>debug_object_free</para></listitem>
+	<listitem><para>debug_object_assert_init</para></listitem>
       </itemizedlist>
       Each of these functions takes the address of the real object and
       a pointer to the object type specific debug description
@@ -273,6 +274,26 @@
 	debug checks.
       </para>
     </sect1>
+
+    <sect1 id="debug_object_assert_init">
+      <title>debug_object_assert_init</title>
+      <para>
+	This function is called to assert that an object has been
+	initialized.
+      </para>
+      <para>
+	When the real object is not tracked by debugobjects, it calls
+	fixup_assert_init of the object type description structure
+	provided by the caller, with the hardcoded object state
+	ODEBUG_NOT_AVAILABLE. The fixup function can correct the problem
+	by calling debug_object_init and other specific initializing
+	functions.
+      </para>
+      <para>
+	When the real object is already tracked by debugobjects it is
+	ignored.
+      </para>
+    </sect1>
   </chapter>
   <chapter id="fixupfunctions">
     <title>Fixup functions</title>
@@ -381,6 +402,35 @@
 	statistics.
       </para>
     </sect1>
+    <sect1 id="fixup_assert_init">
+      <title>fixup_assert_init</title>
+      <para>
+	This function is called from the debug code whenever a problem
+	in debug_object_assert_init is detected.
+      </para>
+      <para>
+	Called from debug_object_assert_init() with a hardcoded state
+	ODEBUG_STATE_NOTAVAILABLE when the object is not found in the
+	debug bucket.
+      </para>
+      <para>
+	The function returns 1 when the fixup was successful,
+	otherwise 0. The return value is used to update the
+	statistics.
+      </para>
+      <para>
+	Note, this function should make sure debug_object_init() is
+	called before returning.
+      </para>
+      <para>
+	The handling of statically initialized objects is a special
+	case. The fixup function should check if this is a legitimate
+	case of a statically initialized object or not. In this case only
+	debug_object_init() should be called to make the object known to
+	the tracker. Then the function should return 0 because this is not
+	a real fixup.
+      </para>
+    </sect1>
   </chapter>
   <chapter id="bugs">
     <title>Known Bugs And Assumptions</title>
diff --git a/include/linux/debugobjects.h b/include/linux/debugobjects.h
index 65970b8..0e5f578 100644
--- a/include/linux/debugobjects.h
+++ b/include/linux/debugobjects.h
@@ -46,6 +46,8 @@ struct debug_obj {
  *			fails
  * @fixup_free:		fixup function, which is called when the free check
  *			fails
+ * @fixup_assert_init:  fixup function, which is called when the assert_init
+ *			check fails
  */
 struct debug_obj_descr {
 	const char		*name;
@@ -54,6 +56,7 @@ struct debug_obj_descr {
 	int (*fixup_activate)	(void *addr, enum debug_obj_state state);
 	int (*fixup_destroy)	(void *addr, enum debug_obj_state state);
 	int (*fixup_free)	(void *addr, enum debug_obj_state state);
+	int (*fixup_assert_init)(void *addr, enum debug_obj_state state);
 };
 
 #ifdef CONFIG_DEBUG_OBJECTS
@@ -64,6 +67,7 @@ extern void debug_object_activate  (void *addr, struct debug_obj_descr *descr);
 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);
+extern void debug_object_assert_init(void *addr, struct debug_obj_descr *descr);
 
 /*
  * Active state:
@@ -89,6 +93,8 @@ static inline void
 debug_object_destroy   (void *addr, struct debug_obj_descr *descr) { }
 static inline void
 debug_object_free      (void *addr, struct debug_obj_descr *descr) { }
+static inline void
+debug_object_assert_init(void *addr, struct debug_obj_descr *descr) { }
 
 static inline void debug_objects_early_init(void) { }
 static inline void debug_objects_mem_init(void) { }
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index b7a5305..77cb245 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -571,6 +571,44 @@ out_unlock:
 }
 
 /**
+ * debug_object_assert_init - debug checks when object should be init-ed
+ * @addr:	address of the object
+ * @descr:	pointer to an object specific debug description structure
+ */
+void debug_object_assert_init(void *addr, struct debug_obj_descr *descr)
+{
+	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) {
+		struct debug_obj o = { .object = addr,
+				       .state = ODEBUG_STATE_NOTAVAILABLE,
+				       .descr = descr };
+
+		raw_spin_unlock_irqrestore(&db->lock, flags);
+		/*
+		 * Maybe the object is static.  Let the type specific
+		 * code decide what to do.
+		 */
+		if (debug_object_fixup(descr->fixup_assert_init, addr,
+				       ODEBUG_STATE_NOTAVAILABLE))
+			debug_print_object(&o, "assert_init");
+		return;
+	}
+
+	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

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

* [tip:core/debugobjects] timer: Setup uninitialized timer with a stub callback
  2011-11-08  3:48 ` [PATCHv2 1/3] debugobjects: Be smarter about static objects Stephen Boyd
  2011-11-28 14:18   ` [tip:core/debugobjects] " tip-bot for Stephen Boyd
@ 2011-11-28 14:20   ` tip-bot for Stephen Boyd
  1 sibling, 0 replies; 12+ messages in thread
From: tip-bot for Stephen Boyd @ 2011-11-28 14:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, sboyd, john.stultz, akpm, cschan, tglx

Commit-ID:  fb16b8cf0b66386134b09e7b8b7056450272d159
Gitweb:     http://git.kernel.org/tip/fb16b8cf0b66386134b09e7b8b7056450272d159
Author:     Stephen Boyd <sboyd@codeaurora.org>
AuthorDate: Mon, 7 Nov 2011 19:48:26 -0800
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 23 Nov 2011 18:49:23 +0100

timer: Setup uninitialized timer with a stub callback

Remove the WARN_ON() in timer_fixup_activate() as we now get the
debugobjects printout in the debugobjects activate check.

We also assign a dummy timer callback so that if the timer is
actually set to fire we don't oops.

[ tglx@linutronix.de: Split out the debugobjects vs. the timer change ]

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: Christine Chan <cschan@codeaurora.org>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Link: http://lkml.kernel.org/r/1320724108-20788-2-git-send-email-sboyd@codeaurora.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/timer.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/kernel/timer.c b/kernel/timer.c
index dbaa624..317087d 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -427,6 +427,12 @@ static int timer_fixup_init(void *addr, enum debug_obj_state state)
 	}
 }
 
+/* Stub timer callback for improperly used timers. */
+static void stub_timer(unsigned long data)
+{
+	WARN_ON(1);
+}
+
 /*
  * fixup_activate is called when:
  * - an active object is activated
@@ -450,7 +456,8 @@ static int timer_fixup_activate(void *addr, enum debug_obj_state state)
 			debug_object_activate(timer, &timer_debug_descr);
 			return 0;
 		} else {
-			WARN_ON_ONCE(1);
+			setup_timer(timer, stub_timer, 0);
+			return 1;
 		}
 		return 0;
 

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

* [tip:core/debugobjects] timer: Use debugobjects to catch deletion of uninitialized timers
  2011-11-08  3:48 ` [PATCHv2 3/3] kernel/timer.c: Use debugobjects to catch deletion of uninitialized timers Stephen Boyd
@ 2011-11-28 14:21   ` tip-bot for Christine Chan
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Christine Chan @ 2011-11-28 14:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, john.stultz, hpa, mingo, akpm, cschan, tglx, sboyd

Commit-ID:  dc4218bd0fe499fce2896f88101ea42dac1f60fc
Gitweb:     http://git.kernel.org/tip/dc4218bd0fe499fce2896f88101ea42dac1f60fc
Author:     Christine Chan <cschan@codeaurora.org>
AuthorDate: Mon, 7 Nov 2011 19:48:28 -0800
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 23 Nov 2011 18:49:23 +0100

timer: Use debugobjects to catch deletion of uninitialized timers

del_timer_sync() calls debug_object_assert_init() to assert that
a timer has been initialized before calling lock_timer_base().
lock_timer_base() would spin forever on a NULL(uninit-ed) base.
The check is added to del_timer() to prevent silent failure, even
though it would not get stuck in an infinite loop.

[ sboyd@codeaurora.org: Remove WARN, intialize timer function]

Signed-off-by: Christine Chan <cschan@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/1320724108-20788-4-git-send-email-sboyd@codeaurora.org
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/timer.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/kernel/timer.c b/kernel/timer.c
index 317087d..5fc5a76 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -487,12 +487,40 @@ static int timer_fixup_free(void *addr, enum debug_obj_state state)
 	}
 }
 
+/*
+ * fixup_assert_init is called when:
+ * - an untracked/uninit-ed object is found
+ */
+static int timer_fixup_assert_init(void *addr, enum debug_obj_state state)
+{
+	struct timer_list *timer = addr;
+
+	switch (state) {
+	case ODEBUG_STATE_NOTAVAILABLE:
+		if (timer->entry.prev == TIMER_ENTRY_STATIC) {
+			/*
+			 * This is not really a fixup. The timer was
+			 * statically initialized. We just make sure that it
+			 * is tracked in the object tracker.
+			 */
+			debug_object_init(timer, &timer_debug_descr);
+			return 0;
+		} else {
+			setup_timer(timer, stub_timer, 0);
+			return 1;
+		}
+	default:
+		return 0;
+	}
+}
+
 static struct debug_obj_descr timer_debug_descr = {
-	.name		= "timer_list",
-	.debug_hint	= timer_debug_hint,
-	.fixup_init	= timer_fixup_init,
-	.fixup_activate	= timer_fixup_activate,
-	.fixup_free	= timer_fixup_free,
+	.name			= "timer_list",
+	.debug_hint		= timer_debug_hint,
+	.fixup_init		= timer_fixup_init,
+	.fixup_activate		= timer_fixup_activate,
+	.fixup_free		= timer_fixup_free,
+	.fixup_assert_init	= timer_fixup_assert_init,
 };
 
 static inline void debug_timer_init(struct timer_list *timer)
@@ -515,6 +543,11 @@ static inline void debug_timer_free(struct timer_list *timer)
 	debug_object_free(timer, &timer_debug_descr);
 }
 
+static inline void debug_timer_assert_init(struct timer_list *timer)
+{
+	debug_object_assert_init(timer, &timer_debug_descr);
+}
+
 static void __init_timer(struct timer_list *timer,
 			 const char *name,
 			 struct lock_class_key *key);
@@ -538,6 +571,7 @@ EXPORT_SYMBOL_GPL(destroy_timer_on_stack);
 static inline void debug_timer_init(struct timer_list *timer) { }
 static inline void debug_timer_activate(struct timer_list *timer) { }
 static inline void debug_timer_deactivate(struct timer_list *timer) { }
+static inline void debug_timer_assert_init(struct timer_list *timer) { }
 #endif
 
 static inline void debug_init(struct timer_list *timer)
@@ -559,6 +593,11 @@ static inline void debug_deactivate(struct timer_list *timer)
 	trace_timer_cancel(timer);
 }
 
+static inline void debug_assert_init(struct timer_list *timer)
+{
+	debug_timer_assert_init(timer);
+}
+
 static void __init_timer(struct timer_list *timer,
 			 const char *name,
 			 struct lock_class_key *key)
@@ -909,6 +948,8 @@ int del_timer(struct timer_list *timer)
 	unsigned long flags;
 	int ret = 0;
 
+	debug_assert_init(timer);
+
 	timer_stats_timer_clear_start_info(timer);
 	if (timer_pending(timer)) {
 		base = lock_timer_base(timer, &flags);
@@ -939,6 +980,8 @@ int try_to_del_timer_sync(struct timer_list *timer)
 	unsigned long flags;
 	int ret = -1;
 
+	debug_assert_init(timer);
+
 	base = lock_timer_base(timer, &flags);
 
 	if (base->running_timer == timer)

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

* Re: [tip:core/debugobjects] debugobjects: Be smarter about static objects
  2011-11-28 14:18   ` [tip:core/debugobjects] " tip-bot for Stephen Boyd
@ 2011-12-13 10:38     ` Thomas Gleixner
  2011-12-13 19:36       ` Stephen Boyd
  0 siblings, 1 reply; 12+ messages in thread
From: Thomas Gleixner @ 2011-12-13 10:38 UTC (permalink / raw)
  To: john.stultz, Ingo Molnar, H. Peter Anvin, LKML, Andrew Morton,
	cschan, sboyd, Peter Zijlstra

Stephen,

On Mon, 28 Nov 2011, tip-bot for Stephen Boyd wrote:

> Commit-ID:  feac18dda25134005909e7770c77464e65608bd8
> Gitweb:     http://git.kernel.org/tip/feac18dda25134005909e7770c77464e65608bd8
> Author:     Stephen Boyd <sboyd@codeaurora.org>
> AuthorDate: Mon, 7 Nov 2011 19:48:26 -0800
> Committer:  Thomas Gleixner <tglx@linutronix.de>
> CommitDate: Wed, 23 Nov 2011 18:49:22 +0100
> 
> debugobjects: Be smarter about static objects
> 
> Make debugobjects use the return code from the fixup function. That
> allows us better diagnostics in the activate check than relying on a
> WARN_ON() in the object specific code.

that series wreckaged the debugobjects selftest. Can you please have a
look?

[    0.000000] ODEBUG: selftest warnings failed 4 != 5

Thanks,

	tglx

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

* Re: [tip:core/debugobjects] debugobjects: Be smarter about static objects
  2011-12-13 10:38     ` Thomas Gleixner
@ 2011-12-13 19:36       ` Stephen Boyd
  2011-12-13 20:37         ` Thomas Gleixner
  0 siblings, 1 reply; 12+ messages in thread
From: Stephen Boyd @ 2011-12-13 19:36 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: john.stultz, Ingo Molnar, H. Peter Anvin, LKML, Andrew Morton,
	cschan, Peter Zijlstra

On 12/13/11 02:38, Thomas Gleixner wrote:
> Stephen,
>
> On Mon, 28 Nov 2011, tip-bot for Stephen Boyd wrote:
>
>> Commit-ID:  feac18dda25134005909e7770c77464e65608bd8
>> Gitweb:     http://git.kernel.org/tip/feac18dda25134005909e7770c77464e65608bd8
>> Author:     Stephen Boyd <sboyd@codeaurora.org>
>> AuthorDate: Mon, 7 Nov 2011 19:48:26 -0800
>> Committer:  Thomas Gleixner <tglx@linutronix.de>
>> CommitDate: Wed, 23 Nov 2011 18:49:22 +0100
>>
>> debugobjects: Be smarter about static objects
>>
>> Make debugobjects use the return code from the fixup function. That
>> allows us better diagnostics in the activate check than relying on a
>> WARN_ON() in the object specific code.
> that series wreckaged the debugobjects selftest. Can you please have a
> look?
>
> [    0.000000] ODEBUG: selftest warnings failed 4 != 5
>
>

Thanks, I should have run the selftest :-(

This code is only slightly confusing

static int __init fixup_activate(void *addr, enum debug_obj_state state)
{
        struct self_test *obj = addr;

        switch (state) {
        case ODEBUG_STATE_NOTAVAILABLE:
                if (obj->static_init == 1) {
                        debug_object_init(obj, &descr_type_test);
                        debug_object_activate(obj, &descr_type_test);
                        /*
                         * Real code should return 0 here ! This is
                         * not a fixup of some bad behaviour. We
                         * merily call the debug_init function to keep
                         * track of the object.
                         */
                        return 1;
                } else {
                        /* Real code needs to emit a warning here */
                }
                return 0;


It seems that it does the complete opposite of what it should do, i.e.
return 1 when the fixup is static and not actually a problem and return
0 otherwise. Because of this return 1, debug_object_activate() thinks
there was a problem in the fixup and then it ups the warning count
because this patch added a warning print for static objects.

I see two solutions:

diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 77cb245..a79083e 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -967,7 +967,7 @@ static void __init debug_objects_selftest(void)

        obj.static_init = 1;
        debug_object_activate(&obj, &descr_type_test);
-       if (check_results(&obj, ODEBUG_STATE_ACTIVE, ++fixups, warnings))
+       if (check_results(&obj, ODEBUG_STATE_ACTIVE, ++fixups, ++warnings))
                goto out;
        debug_object_init(&obj, &descr_type_test);
        if (check_results(&obj, ODEBUG_STATE_INIT, ++fixups, ++warnings))


This would just up the warning count to take into account that a warning
is now printed when the state is NOTAVAILABLE and the fixup returns 1.

Or

diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 77cb245..0ab9ae8 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -818,17 +818,9 @@ static int __init fixup_activate(void *addr, enum debug_obj_state state)   
                if (obj->static_init == 1) {
                        debug_object_init(obj, &descr_type_test);
                        debug_object_activate(obj, &descr_type_test);
-                       /*
-                        * Real code should return 0 here ! This is
-                        * not a fixup of some bad behaviour. We
-                        * merily call the debug_init function to keep
-                        * track of the object.
-                        */
-                       return 1;
-               } else {
-                       /* Real code needs to emit a warning here */
+                       return 0;
                }
-               return 0;
+               return 1;

        case ODEBUG_STATE_ACTIVE:
                debug_object_deactivate(obj, &descr_type_test);
@@ -967,7 +959,7 @@ static void __init debug_objects_selftest(void)

        obj.static_init = 1;
        debug_object_activate(&obj, &descr_type_test);
-       if (check_results(&obj, ODEBUG_STATE_ACTIVE, ++fixups, warnings))
+       if (check_results(&obj, ODEBUG_STATE_ACTIVE, fixups, warnings))
                goto out;
        debug_object_init(&obj, &descr_type_test);
        if (check_results(&obj, ODEBUG_STATE_INIT, ++fixups, ++warnings))



This would make the fixup function for a static NOTAVAILABLE object
return 0 and 1 appropriately and corrects the fixup and warning checking
to reflect that nothing was in need of fixing.

Why was the fixup for selftest inverted?

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

* Re: [tip:core/debugobjects] debugobjects: Be smarter about static objects
  2011-12-13 19:36       ` Stephen Boyd
@ 2011-12-13 20:37         ` Thomas Gleixner
  2011-12-14  4:59           ` [PATCH] debugobjects: Fix selftest for static warnings Stephen Boyd
  0 siblings, 1 reply; 12+ messages in thread
From: Thomas Gleixner @ 2011-12-13 20:37 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: john.stultz, Ingo Molnar, H. Peter Anvin, LKML, Andrew Morton,
	cschan, Peter Zijlstra

On Tue, 13 Dec 2011, Stephen Boyd wrote:
> 
> This code is only slightly confusing

Maybe we should tell that the guy who wrote it :)
 
> static int __init fixup_activate(void *addr, enum debug_obj_state state)
> {
>         struct self_test *obj = addr;
> 
>         switch (state) {
>         case ODEBUG_STATE_NOTAVAILABLE:
>                 if (obj->static_init == 1) {
>                         debug_object_init(obj, &descr_type_test);
>                         debug_object_activate(obj, &descr_type_test);
>                         /*
>                          * Real code should return 0 here ! This is
>                          * not a fixup of some bad behaviour. We
>                          * merily call the debug_init function to keep
>                          * track of the object.
>                          */
>                         return 1;
>                 } else {
>                         /* Real code needs to emit a warning here */
>                 }
>                 return 0;
> 
> 
> It seems that it does the complete opposite of what it should do, i.e.
> return 1 when the fixup is static and not actually a problem and return
> 0 otherwise. Because of this return 1, debug_object_activate() thinks
> there was a problem in the fixup and then it ups the warning count
> because this patch added a warning print for static objects.

Hmm, I think that was because I had not implemented that static
warning thing back then. So yes, it's backwards and should be fixed
proper:

> diff --git a/lib/debugobjects.c b/lib/debugobjects.c
> index 77cb245..0ab9ae8 100644
> --- a/lib/debugobjects.c
> +++ b/lib/debugobjects.c
> @@ -818,17 +818,9 @@ static int __init fixup_activate(void *addr, enum debug_obj_state state)   
>                 if (obj->static_init == 1) {
>                         debug_object_init(obj, &descr_type_test);
>                         debug_object_activate(obj, &descr_type_test);
> -                       /*
> -                        * Real code should return 0 here ! This is
> -                        * not a fixup of some bad behaviour. We
> -                        * merily call the debug_init function to keep
> -                        * track of the object.
> -                        */
> -                       return 1;
> -               } else {
> -                       /* Real code needs to emit a warning here */
> +                       return 0;
>                 }
> -               return 0;
> +               return 1;
> 
>         case ODEBUG_STATE_ACTIVE:
>                 debug_object_deactivate(obj, &descr_type_test);
> @@ -967,7 +959,7 @@ static void __init debug_objects_selftest(void)
> 
>         obj.static_init = 1;
>         debug_object_activate(&obj, &descr_type_test);
> -       if (check_results(&obj, ODEBUG_STATE_ACTIVE, ++fixups, warnings))
> +       if (check_results(&obj, ODEBUG_STATE_ACTIVE, fixups, warnings))
>                 goto out;
>         debug_object_init(&obj, &descr_type_test);
>         if (check_results(&obj, ODEBUG_STATE_INIT, ++fixups, ++warnings))
> 
> 
> 
> This would make the fixup function for a static NOTAVAILABLE object
> return 0 and 1 appropriately and corrects the fixup and warning checking
> to reflect that nothing was in need of fixing.

Yes, the other thing works, but is butt ugly.
 
> Why was the fixup for selftest inverted?

See above plus laziness I assume :)

Can you please resend with a changelong ?

Thanks,

	tglx

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

* [PATCH] debugobjects: Fix selftest for static warnings
  2011-12-13 20:37         ` Thomas Gleixner
@ 2011-12-14  4:59           ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2011-12-14  4:59 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: john.stultz, Ingo Molnar, H . Peter Anvin, linux-kernel,
	Andrew Morton, cschan, Peter Zijlstra

debugobjects is now printing a warning when a fixup for a
NOTAVAILABLE object is run. This causes the selftest to fail
like:

[    0.000000] ODEBUG: selftest warnings failed 4 != 5

We could just increase the number of warnings that the selftest
is expecting to see because that is actually what has changed.
But, it turns out that fixup_activate() was written with inverted
logic and thus a fixup for a static object returned 1 indicating
the object had been fixed, and 0 otherwise. Fix the logic to be
correct and update the counts to reflect that nothing needed
fixing for a static object.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Reported-By: Thomas Gleixner <tglx@linutronix.de>
---
 lib/debugobjects.c |   14 +++-----------
 1 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 77cb245..0ab9ae8 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -818,17 +818,9 @@ static int __init fixup_activate(void *addr, enum debug_obj_state state)
 		if (obj->static_init == 1) {
 			debug_object_init(obj, &descr_type_test);
 			debug_object_activate(obj, &descr_type_test);
-			/*
-			 * Real code should return 0 here ! This is
-			 * not a fixup of some bad behaviour. We
-			 * merily call the debug_init function to keep
-			 * track of the object.
-			 */
-			return 1;
-		} else {
-			/* Real code needs to emit a warning here */
+			return 0;
 		}
-		return 0;
+		return 1;
 
 	case ODEBUG_STATE_ACTIVE:
 		debug_object_deactivate(obj, &descr_type_test);
@@ -967,7 +959,7 @@ static void __init debug_objects_selftest(void)
 
 	obj.static_init = 1;
 	debug_object_activate(&obj, &descr_type_test);
-	if (check_results(&obj, ODEBUG_STATE_ACTIVE, ++fixups, warnings))
+	if (check_results(&obj, ODEBUG_STATE_ACTIVE, fixups, warnings))
 		goto out;
 	debug_object_init(&obj, &descr_type_test);
 	if (check_results(&obj, ODEBUG_STATE_INIT, ++fixups, ++warnings))
-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

end of thread, other threads:[~2011-12-14  4:59 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-08  3:48 [PATCHv2 0/3] Catching del_timer_sync() on uninitialized timers Stephen Boyd
2011-11-08  3:48 ` [PATCHv2 1/3] debugobjects: Be smarter about static objects Stephen Boyd
2011-11-28 14:18   ` [tip:core/debugobjects] " tip-bot for Stephen Boyd
2011-12-13 10:38     ` Thomas Gleixner
2011-12-13 19:36       ` Stephen Boyd
2011-12-13 20:37         ` Thomas Gleixner
2011-12-14  4:59           ` [PATCH] debugobjects: Fix selftest for static warnings Stephen Boyd
2011-11-28 14:20   ` [tip:core/debugobjects] timer: Setup uninitialized timer with a stub callback tip-bot for Stephen Boyd
2011-11-08  3:48 ` [PATCHv2 2/3] debugobjects: Extend to assert that an object is initialized Stephen Boyd
2011-11-28 14:19   ` [tip:core/debugobjects] " tip-bot for Christine Chan
2011-11-08  3:48 ` [PATCHv2 3/3] kernel/timer.c: Use debugobjects to catch deletion of uninitialized timers Stephen Boyd
2011-11-28 14:21   ` [tip:core/debugobjects] timer: " tip-bot for Christine Chan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.