From 99abb977ad29a00172612acdcd8cf3fbe95470b4 Mon Sep 17 00:00:00 2001 Message-Id: <99abb977ad29a00172612acdcd8cf3fbe95470b4.1601675152.git.zanussi@kernel.org> In-Reply-To: <5b5a156f9808b1acf1205606e03da117214549ea.1601675151.git.zanussi@kernel.org> References: <5b5a156f9808b1acf1205606e03da117214549ea.1601675151.git.zanussi@kernel.org> From: Thomas Gleixner Date: Wed, 19 Sep 2012 14:50:37 +0200 Subject: [PATCH 206/333] printk: Make rt aware Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.148-rt64.tar.xz Drop the lock before calling the console driver and do not disable interrupts while printing to a serial console. Signed-off-by: Thomas Gleixner --- kernel/printk/printk.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index e582817249ce..1eb212298f95 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1652,6 +1652,7 @@ SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) return do_syslog(type, buf, len, SYSLOG_FROM_READER); } +#ifndef CONFIG_PREEMPT_RT_FULL /* * Special console_lock variants that help to reduce the risk of soft-lockups. * They allow to pass console_lock to another printk() call using a busy wait. @@ -1792,6 +1793,15 @@ static int console_trylock_spinning(void) return 1; } +#else + +static int console_trylock_spinning(void) +{ + return console_trylock(); +} + +#endif + /* * Call the console drivers, asking them to write out * log_buf[start] to log_buf[end - 1]. @@ -1807,6 +1817,7 @@ static void call_console_drivers(const char *ext_text, size_t ext_len, if (!console_drivers) return; + migrate_disable(); for_each_console(con) { if (exclusive_console && con != exclusive_console) continue; @@ -1822,6 +1833,7 @@ static void call_console_drivers(const char *ext_text, size_t ext_len, else con->write(con, text, len); } + migrate_enable(); } int printk_delay_msec __read_mostly; @@ -2016,20 +2028,30 @@ asmlinkage int vprintk_emit(int facility, int level, /* If called from the scheduler, we can not call up(). */ if (!in_sched && pending_output) { + int may_trylock = 1; + +#ifdef CONFIG_PREEMPT_RT_FULL + /* + * we can't take a sleeping lock with IRQs or preeption disabled + * so we can't print in these contexts + */ + if (!(preempt_count() == 0 && !irqs_disabled())) + may_trylock = 0; +#endif /* * Disable preemption to avoid being preempted while holding * console_sem which would prevent anyone from printing to * console */ - preempt_disable(); + migrate_disable(); /* * Try to acquire and then immediately release the console * semaphore. The release will print out buffers and wake up * /dev/kmsg and syslog() users. */ - if (console_trylock_spinning()) + if (may_trylock && console_trylock_spinning()) console_unlock(); - preempt_enable(); + migrate_enable(); } if (pending_output) @@ -2491,6 +2513,10 @@ void console_unlock(void) console_seq++; raw_spin_unlock(&logbuf_lock); +#ifdef CONFIG_PREEMPT_RT_FULL + printk_safe_exit_irqrestore(flags); + call_console_drivers(ext_text, ext_len, text, len); +#else /* * While actively printing out messages, if another printk() * were to occur on another CPU, it may wait for this one to @@ -2509,6 +2535,7 @@ void console_unlock(void) } printk_safe_exit_irqrestore(flags); +#endif if (do_cond_resched) cond_resched(); -- 2.17.1