mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@elte.hu>, Thomas Gleixner <tglx@linutronix.de>,
	Linux Kernel list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v3] timer: implement lockdep deadlock detection
Date: Wed, 28 Jan 2009 19:06:57 +0100	[thread overview]
Message-ID: <1233166017.4811.9.camel@johannes.local> (raw)
In-Reply-To: <1233140081.3936.21.camel@johannes.local>

On Wed, 2009-01-28 at 11:59 +0100, Johannes Berg wrote:

> > > I actually got "trying to register non-static key" on my powerpc64
> > > machine. Is there a possibility that functions are not static??
> > 
> > Hmm, weird, afaict static_obj() includes both text and data, for the
> > core kernel as well as modules.
> 
> Yeah, I'd think it should. I'll run it by the powerpc list when I get it
> again, it only seems to happen very rarely.

It's actually a generic bug.

delayed work structs are initialised like this:

#define __DELAYED_WORK_INITIALIZER(n, f) {                      \
        .work = __WORK_INITIALIZER((n).work, (f)),              \
        .timer = TIMER_INITIALIZER(NULL, 0, 0),                 \
        }

#define DECLARE_DELAYED_WORK(n, f)                              \
        struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f)


Note the NULL function, which I used for the key of timers. Thus, the
key is NULL, and the name is "NULL".

Now, this means that my code for the run timer:

				struct lockdep_map lockdep_map =
					timer->lockdep_map;

will actually have lockdep_map here with a NULL key. Once it gets into

			lock_map_acquire(&lockdep_map);

it'll try to register &lockdep_map as the key.

Interestingly, that doesn't seem to be a problem on x86_64, which would
appear to be a bug, the stack certainly isn't a static location.

The patch below fixes it by using the file/lineno of the static
definition as both the name and the key -- using it as the name means
you have a good chance of finding it if something goes wrong, and using
it as the key means we have a good key for it. The patch looks horrible
though. Any better ideas? If not, I think we should roll this into the
original patch.

johannes
---
 include/linux/timer.h |   26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

--- wireless-testing.orig/include/linux/timer.h	2009-01-28 18:55:03.270071595 +0100
+++ wireless-testing/include/linux/timer.h	2009-01-28 19:00:41.326947619 +0100
@@ -32,23 +32,35 @@ extern struct tvec_base boot_tvec_bases;
 /*
  * NB: because we have to copy the lockdep_map, setting _key
  * here is required, otherwise it could get initialised to the
- * copy of the lockdep_map! We use the function pointer as the
- * lockdep key here.
+ * copy of the lockdep_map! We use the pointer to and the string
+ * "<file>:<line>" as the key resp. the name of the lockdep_map.
  */
-#define __TIMER_LOCKDEP_MAP_INITIALIZER(fn, name)		\
-	.lockdep_map = STATIC_LOCKDEP_MAP_INIT(name, fn),
+#define __TIMER_LOCKDEP_MAP_INITIALIZER(name, key)			\
+	.lockdep_map = STATIC_LOCKDEP_MAP_INIT(name, key),
 #else
-#define __TIMER_LOCKDEP_MAP_INITIALIZER(fn, name)
+#define __TIMER_LOCKDEP_MAP_INITIALIZER(name, key)
 #endif
 
-#define TIMER_INITIALIZER(_function, _expires, _data) {			\
+#define ____TIMER_INITIALIZER(_function, _expires, _data, _name, _key) {\
 		.entry = { .prev = TIMER_ENTRY_STATIC },		\
 		.function = (_function),				\
 		.expires = (_expires),					\
 		.data = (_data),					\
 		.base = &boot_tvec_bases,				\
-		__TIMER_LOCKDEP_MAP_INITIALIZER((_function), #_function)\
+		__TIMER_LOCKDEP_MAP_INITIALIZER((_name), (_key))	\
 	}
+/*
+ * All the indirection here is required to build the
+ * "<file>:<line>" string and the pointer to it.
+ */
+#define ___TIMER_INITIALIZER(_fn, _exp, _dat, _kn)			\
+	____TIMER_INITIALIZER(_fn, _exp, _dat, (_kn), &(_kn))
+#define __TIMER_INITIALIZER(_fn, _exp, _dat, _f, _c, _l)		\
+	___TIMER_INITIALIZER(_fn, _exp, _dat, _f # _c # _l)
+#define _TIMER_INITIALIZER(_fn, _exp, _dat, _f, _l)			\
+	__TIMER_INITIALIZER(_fn, _exp, _dat, _f, :, _l)
+#define TIMER_INITIALIZER(_function, _expires, _data)			\
+	_TIMER_INITIALIZER(_function, _expires, _data, __FILE__, __LINE__)
 
 #define DEFINE_TIMER(_name, _function, _expires, _data)		\
 	struct timer_list _name =				\



  reply	other threads:[~2009-01-28 18:48 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-26 22:59 [PATCH] " Johannes Berg
2009-01-26 23:03 ` Johannes Berg
2009-01-26 23:07 ` Ingo Molnar
2009-01-27  8:45   ` Johannes Berg
2009-01-27  8:46   ` [PATCH v2] " Johannes Berg
2009-01-27 13:27     ` Ingo Molnar
2009-01-27 13:41       ` Ingo Molnar
2009-01-27 18:06         ` Johannes Berg
2009-01-27 18:30           ` Peter Zijlstra
2009-01-27 18:33             ` Johannes Berg
2009-01-27 18:57             ` [PATCH v3] " Johannes Berg
2009-01-28  8:20               ` Peter Zijlstra
2009-01-28  9:54                 ` Johannes Berg
2009-01-28 10:13                   ` Peter Zijlstra
2009-01-28 10:54                     ` Johannes Berg
2009-01-28 18:06                       ` Johannes Berg [this message]
2009-01-29 12:38                         ` Ingo Molnar
2009-01-29 15:03                           ` [PATCH v4] " Johannes Berg
2009-01-29 13:38                         ` [PATCH v3] " Peter Zijlstra
2009-01-29 13:44                           ` Arnd Bergmann
2009-01-29 14:25                           ` Johannes Berg
2009-01-27 18:12         ` [PATCH v2] " Johannes Berg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1233166017.4811.9.camel@johannes.local \
    --to=johannes@sipsolutions.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome