Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=eb13ba873881abd5e15af784756a61af635e665e
Commit:     eb13ba873881abd5e15af784756a61af635e665e
Parent:     5a26db5bd25cf4bf32ae9fa9f6136b6b6d5b45c5
Author:     Johannes Berg <[EMAIL PROTECTED]>
AuthorDate: Wed Jan 16 09:51:58 2008 +0100
Committer:  Peter Zijlstra <[EMAIL PROTECTED]>
CommitDate: Wed Jan 16 09:51:58 2008 +0100

    lockdep: fix workqueue creation API lockdep interaction
    Dave Young reported warnings from lockdep that the workqueue API
    can sometimes try to register lockdep classes with the same key
    but different names. This is not permitted in lockdep.
    
    Unfortunately, I was unaware of that restriction when I wrote
    the code to debug workqueue problems with lockdep and used the
    workqueue name as the lockdep class name. This can obviously
    lead to the problem if the workqueue name is dynamic.
    
    This patch solves the problem by always using a constant name
    for the workqueue's lockdep class, namely either the constant
    name that was passed in or a string consisting of the variable
    name.
    
    Signed-off-by: Johannes Berg <[EMAIL PROTECTED]>
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
    Signed-off-by: Peter Zijlstra <[EMAIL PROTECTED]>
---
 include/linux/workqueue.h |   14 +++++++++++---
 kernel/workqueue.c        |    5 +++--
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 7daafdc..7f28c32 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -149,19 +149,27 @@ struct execute_work {
 
 extern struct workqueue_struct *
 __create_workqueue_key(const char *name, int singlethread,
-                      int freezeable, struct lock_class_key *key);
+                      int freezeable, struct lock_class_key *key,
+                      const char *lock_name);
 
 #ifdef CONFIG_LOCKDEP
 #define __create_workqueue(name, singlethread, freezeable)     \
 ({                                                             \
        static struct lock_class_key __key;                     \
+       const char *__lock_name;                                \
+                                                               \
+       if (__builtin_constant_p(name))                         \
+               __lock_name = (name);                           \
+       else                                                    \
+               __lock_name = #name;                            \
                                                                \
        __create_workqueue_key((name), (singlethread),          \
-                              (freezeable), &__key);           \
+                              (freezeable), &__key,            \
+                              __lock_name);                    \
 })
 #else
 #define __create_workqueue(name, singlethread, freezeable)     \
-       __create_workqueue_key((name), (singlethread), (freezeable), NULL)
+       __create_workqueue_key((name), (singlethread), (freezeable), NULL, NULL)
 #endif
 
 #define create_workqueue(name) __create_workqueue((name), 0, 0)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 52d5e7c..8db0b59 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -722,7 +722,8 @@ static void start_workqueue_thread(struct 
cpu_workqueue_struct *cwq, int cpu)
 struct workqueue_struct *__create_workqueue_key(const char *name,
                                                int singlethread,
                                                int freezeable,
-                                               struct lock_class_key *key)
+                                               struct lock_class_key *key,
+                                               const char *lock_name)
 {
        struct workqueue_struct *wq;
        struct cpu_workqueue_struct *cwq;
@@ -739,7 +740,7 @@ struct workqueue_struct *__create_workqueue_key(const char 
*name,
        }
 
        wq->name = name;
-       lockdep_init_map(&wq->lockdep_map, name, key, 0);
+       lockdep_init_map(&wq->lockdep_map, lock_name, key, 0);
        wq->singlethread = singlethread;
        wq->freezeable = freezeable;
        INIT_LIST_HEAD(&wq->list);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to