aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2013-07-09 00:26:32 +0200
committerSteven Rostedt <rostedt@rostedt.homelinux.com>2013-09-13 12:33:24 -0400
commitcf1fadd17f07f449fc7c338c6e0f5a0886e48f30 (patch)
tree93f415038d43a4771a18a99f389566123acc87bf /include
parent418ad59a2cd9106d190e003a580038ed9408ca54 (diff)
list_bl.h: fix it for for !SMP && !DEBUG_SPINLOCK
The patch "list_bl.h: make list head locking RT safe" introduced an unconditional __set_bit(0, (unsigned long *)b); in void hlist_bl_lock(struct hlist_bl_head *b). This clobbers the value of b->first. When the value of b->first is retrieved using hlist_bl_first the clobbering is undone using (unsigned long)h->first & ~LIST_BL_LOCKMASK and so depending on LIST_BL_LOCKMASK being one. But LIST_BL_LOCKMASK is only one if at least on of CONFIG_SMP and CONFIG_DEBUG_SPINLOCK are defined. Without these the value returned by hlist_bl_first has the zeroth bit set which likely results in a crash. So only do the clobbering in the cases where LIST_BL_LOCKMASK is one. An alternative would be to always define LIST_BL_LOCKMASK to one with CONFIG_PREEMPT_RT_BASE. Cc: stable-rt@vger.kernel.org Acked-by: Paul Gortmaker <paul.gortmaker@windriver.com> Tested-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Diffstat (limited to 'include')
-rw-r--r--include/linux/list_bl.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/include/linux/list_bl.h b/include/linux/list_bl.h
index ddfd46a88f93..becd7a61263f 100644
--- a/include/linux/list_bl.h
+++ b/include/linux/list_bl.h
@@ -131,8 +131,10 @@ static inline void hlist_bl_lock(struct hlist_bl_head *b)
bit_spin_lock(0, (unsigned long *)b);
#else
raw_spin_lock(&b->lock);
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
__set_bit(0, (unsigned long *)b);
#endif
+#endif
}
static inline void hlist_bl_unlock(struct hlist_bl_head *b)
@@ -140,7 +142,9 @@ static inline void hlist_bl_unlock(struct hlist_bl_head *b)
#ifndef CONFIG_PREEMPT_RT_BASE
__bit_spin_unlock(0, (unsigned long *)b);
#else
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
__clear_bit(0, (unsigned long *)b);
+#endif
raw_spin_unlock(&b->lock);
#endif
}