fs: hlist UP debug fixup
authorNick Piggin <npiggin@kernel.dk>
Fri, 14 Jan 2011 02:36:43 +0000 (02:36 +0000)
committerNick Piggin <npiggin@hera.kernel.org>
Fri, 14 Jan 2011 02:36:43 +0000 (02:36 +0000)
Po-Yu Chuang <ratbert.chuang@gmail.com> noticed that hlist_bl_set_first could
crash on a UP system when LIST_BL_LOCKMASK is 0, because

LIST_BL_BUG_ON(!((unsigned long)h->first & LIST_BL_LOCKMASK));

always evaulates to true.

Fix the expression, and also avoid a dependency between bit spinlock
implementation and list bl code (list code shouldn't know anything
except that bit 0 is set when adding and removing elements). Eventually
if a good use case comes up, we might use this list to store 1 or more
arbitrary bits of data, so it really shouldn't be tied to locking either,
but for now they are helpful for debugging.

Signed-off-by: Nick Piggin <npiggin@kernel.dk>
include/linux/list_bl.h
include/linux/rculist_bl.h

index 9ee97e7..b2adbb4 100644 (file)
@@ -16,7 +16,7 @@
  * some fast and compact auxiliary data.
  */
 
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+#if defined(CONFIG_SMP)
 #define LIST_BL_LOCKMASK       1UL
 #else
 #define LIST_BL_LOCKMASK       0UL
@@ -62,7 +62,8 @@ static inline void hlist_bl_set_first(struct hlist_bl_head *h,
                                        struct hlist_bl_node *n)
 {
        LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK);
-       LIST_BL_BUG_ON(!((unsigned long)h->first & LIST_BL_LOCKMASK));
+       LIST_BL_BUG_ON(((unsigned long)h->first & LIST_BL_LOCKMASK) !=
+                                                       LIST_BL_LOCKMASK);
        h->first = (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK);
 }
 
index b872b49..cf1244f 100644 (file)
@@ -11,7 +11,8 @@ static inline void hlist_bl_set_first_rcu(struct hlist_bl_head *h,
                                        struct hlist_bl_node *n)
 {
        LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK);
-       LIST_BL_BUG_ON(!((unsigned long)h->first & LIST_BL_LOCKMASK));
+       LIST_BL_BUG_ON(((unsigned long)h->first & LIST_BL_LOCKMASK) !=
+                                                       LIST_BL_LOCKMASK);
        rcu_assign_pointer(h->first,
                (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK));
 }