|
@@ -1888,6 +1888,12 @@ asmlinkage int vprintk_emit(int facility, int level,
|
|
|
|
|
|
/* If called from the scheduler, we can not call up(). */
|
|
|
if (!in_sched) {
|
|
|
+ /*
|
|
|
+ * 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
|
|
@@ -1895,6 +1901,7 @@ asmlinkage int vprintk_emit(int facility, int level,
|
|
|
*/
|
|
|
if (console_trylock_spinning())
|
|
|
console_unlock();
|
|
|
+ preempt_enable();
|
|
|
}
|
|
|
|
|
|
return printed_len;
|
|
@@ -2211,20 +2218,7 @@ int console_trylock(void)
|
|
|
return 0;
|
|
|
}
|
|
|
console_locked = 1;
|
|
|
- /*
|
|
|
- * 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();
|
|
|
+ console_may_schedule = 0;
|
|
|
return 1;
|
|
|
}
|
|
|
EXPORT_SYMBOL(console_trylock);
|