#undef E
 
+#ifdef CONFIG_PREEMPT_RT
+# define RT_PREPARE_DBL_UNLOCK()       { migrate_disable(); rcu_read_lock(); }
+#else
+# define RT_PREPARE_DBL_UNLOCK()
+#endif
 /*
  * Double unlock:
  */
 #define E()                                    \
                                                \
        LOCK(A);                                \
+       RT_PREPARE_DBL_UNLOCK();                \
        UNLOCK(A);                              \
        UNLOCK(A); /* fail */
 
 
 static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
 {
-       unsigned long saved_preempt_count = preempt_count();
+       int saved_preempt_count = preempt_count();
+#ifdef CONFIG_PREEMPT_RT
+#ifdef CONFIG_SMP
+       int saved_mgd_count = current->migration_disabled;
+#endif
+       int saved_rcu_count = current->rcu_read_lock_nesting;
+#endif
 
        WARN_ON(irqs_disabled());
 
         * count, so restore it:
         */
        preempt_count_set(saved_preempt_count);
+
+#ifdef CONFIG_PREEMPT_RT
+#ifdef CONFIG_SMP
+       while (current->migration_disabled > saved_mgd_count)
+               migrate_enable();
+#endif
+
+       while (current->rcu_read_lock_nesting > saved_rcu_count)
+               rcu_read_unlock();
+       WARN_ON_ONCE(current->rcu_read_lock_nesting < saved_rcu_count);
+#endif
+
 #ifdef CONFIG_TRACE_IRQFLAGS
        if (softirq_count())
                current->softirqs_enabled = 0;