Skip to contentSkip to conversation

: Set plist.lock to NULL on PREEMPT_RT

PATCH New Arnaldo Carvalho de Melo 1 participant 1 message Oct 22, 2007

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 : Set plist.lock to NULL on PREEMPT_RT

On RT struct plist_head->lock is a raw_spinlock_t, but struct futex_hash_bucket->lock, that is set to plist_head->lock is a spinlock, which becomes a mutex on RT. Later in plist_check_head spin_is_locked can't figure out what is the right type, triggering a WARN_ON_SMP. As we were already special casing PREEMPT_RT on plist_check_head..

kernel/futex.c +10 -2
diff -uNrp linux-2.6.23-rt1.orig/kernel/futex.c linux-2.6.23-rt1/kernel/futex.c
@@ -947,9 +947,13 @@ static int futex_requeue(u32 __user *uad
 				plist_del(&this->list, &hb1->chain);
 				plist_add(&this->list, &hb2->chain);
 				this->lock_ptr = &hb2->lock;
-#if defined(CONFIG_DEBUG_PI_LIST) && !defined(CONFIG_PREEMPT_RT)
+#ifdef CONFIG_DEBUG_PI_LIST
+#ifdef CONFIG_PREEMPT_RT
+				this->list.plist.lock = NULL;
+#else
 				this->list.plist.lock = &hb2->lock;
 #endif
+#endif
 			}
 			this->key = key2;
 			get_futex_key_refs(&key2);
@@ -1008,9 +1012,13 @@ static inline void __queue_me(struct fut
 	prio = min(current->normal_prio, MAX_RT_PRIO);
 
 	plist_node_init(&q->list, prio);
-#if defined(CONFIG_DEBUG_PI_LIST) && !defined(CONFIG_PREEMPT_RT)
+#ifdef CONFIG_DEBUG_PI_LIST
+#ifdef CONFIG_PREEMPT_RT
+	q->list.plist.lock = NULL;
+#else
 	q->list.plist.lock = &hb->lock;
 #endif
+#endif
 	plist_add(&q->list, &hb->chain);
 	q->task = current;
 	spin_unlock(&hb->lock);