|
@@ -1757,13 +1757,6 @@ asmlinkage int vprintk_emit(int facility, int level,
|
|
|
/* If called from the scheduler, we can not call up(). */
|
|
|
if (!in_sched) {
|
|
|
lockdep_off();
|
|
|
- /*
|
|
|
- * Disable preemption to avoid being preempted while holding
|
|
|
- * console_sem which would prevent anyone from printing to
|
|
|
- * console
|
|
|
- */
|
|
|
- preempt_disable();
|
|
|
-
|
|
|
/*
|
|
|
* Try to acquire and then immediately release the console
|
|
|
* semaphore. The release will print out buffers and wake up
|
|
@@ -1771,7 +1764,6 @@ asmlinkage int vprintk_emit(int facility, int level,
|
|
|
*/
|
|
|
if (console_trylock())
|
|
|
console_unlock();
|
|
|
- preempt_enable();
|
|
|
lockdep_on();
|
|
|
}
|
|
|
|
|
@@ -2122,7 +2114,20 @@ int console_trylock(void)
|
|
|
return 0;
|
|
|
}
|
|
|
console_locked = 1;
|
|
|
- console_may_schedule = 0;
|
|
|
+ /*
|
|
|
+ * When PREEMPT_COUNT disabled we can't reliably detect if it's
|
|
|
+ * safe to schedule (e.g. calling printk while holding a spin_lock),
|
|
|
+ * because preempt_disable()/preempt_enable() are just barriers there
|
|
|
+ * and preempt_count() is always 0.
|
|
|
+ *
|
|
|
+ * RCU read sections have a separate preemption counter when
|
|
|
+ * PREEMPT_RCU enabled thus we must take extra care and check
|
|
|
+ * rcu_preempt_depth(), otherwise RCU read sections modify
|
|
|
+ * preempt_count().
|
|
|
+ */
|
|
|
+ console_may_schedule = !oops_in_progress &&
|
|
|
+ preemptible() &&
|
|
|
+ !rcu_preempt_depth();
|
|
|
return 1;
|
|
|
}
|
|
|
EXPORT_SYMBOL(console_trylock);
|