[PATCH 5/7] printk: Add config option for disabling printk offloading
From: Jan Kara
Date: Mon Oct 26 2015 - 00:53:36 EST
From: Jan Kara <jack@xxxxxxx>
Necessity for offloading of printing was observed only for large
systems. So add a config option (disabled by default) which removes most
of the overhead added by this functionality.
Signed-off-by: Jan Kara <jack@xxxxxxx>
---
Documentation/kernel-parameters.txt | 13 +++++++------
init/Kconfig | 14 ++++++++++++++
kernel/printk/printk.c | 35 +++++++++++++++++++++++++++++++++--
3 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index df8adee975ba..913c166fdfea 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2958,18 +2958,19 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Format: <bool> (1/Y/y=enable, 0/N/n=disable)
default: disabled
- printk.offload_chars=
+ printk.offload_chars= [KNL]
Printing to console can be relatively slow especially
in case of serial console. When there is intensive
printing happening from several cpus (as is the case
during boot), a cpu can be spending significant time
(seconds or more) doing printing. To avoid softlockups,
lost interrupts, and similar problems other cpus
- will take over printing after the currently printing
- cpu has printed 'printk.offload_chars' characters.
- Higher value means possibly longer interrupt and other
- latencies but lower overhead of printing due to handing
- over of printing.
+ will take over printing (if CONFIG_PRINTK_OFFLOAD=y)
+ after the currently printing cpu has printed
+ 'printk.offload_chars' characters. Higher value means
+ possibly longer interrupt and other latencies but
+ lower overhead of printing due to handing over of
+ printing.
Format: <number> (0 = disabled)
default: 1000
diff --git a/init/Kconfig b/init/Kconfig
index c24b6f767bf0..fa9749da5fc8 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1456,6 +1456,20 @@ config PRINTK
very difficult to diagnose system problems, saying N here is
strongly discouraged.
+config PRINTK_OFFLOAD
+ default n
+ bool "Enable support for offloading printing to different CPU"
+ depends on PRINTK && SMP
+ help
+ Printing to console can be relatively slow especially in case of
+ serial console. On large machines when there is intensive printing
+ happening from several cpus (as is the case during boot), a cpu can
+ be spending significant time (seconds or more) doing printing. To
+ avoid softlockups, lost interrupts, and similar problems other cpus
+ will take over printing after the currently printing cpu has printed
+ certain number of characters (tunable via 'printk.offload_chars'
+ kernel parameter).
+
config BUG
bool "BUG() support" if EXPERT
default y
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index e404c429fe87..5153c6518b9d 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -79,6 +79,7 @@ static DEFINE_SEMAPHORE(console_sem);
struct console *console_drivers;
EXPORT_SYMBOL_GPL(console_drivers);
+#ifdef CONFIG_PRINTK_OFFLOAD
/*
* This spinlock is taken when printing to console. It is used only so that
* we can spin on it when some other thread wants to take over printing to
@@ -105,6 +106,7 @@ static DEFINE_MUTEX(printk_kthread_mutex);
/* Wait queue printing kthreads sleep on when idle */
static DECLARE_WAIT_QUEUE_HEAD(print_queue);
+#endif /* CONFIG_PRINTK_OFFLOAD */
#ifdef CONFIG_LOCKDEP
static struct lockdep_map console_lock_dep_map = {
@@ -308,6 +310,7 @@ static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
static char *log_buf = __log_buf;
static u32 log_buf_len = __LOG_BUF_LEN;
+#ifdef CONFIG_PRINTK_OFFLOAD
static int offload_chars_set(const char *val, const struct kernel_param *kp);
static struct kernel_param_ops offload_chars_ops = {
.set = offload_chars_set,
@@ -326,6 +329,7 @@ module_param_cb(offload_chars, &offload_chars_ops, &printk_offload_chars,
S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(offload_chars, "offload printing to console to a different"
" cpu after this number of characters");
+#endif
/* Return log buffer address */
char *log_buf_addr_get(void)
@@ -2255,6 +2259,7 @@ out:
raw_spin_unlock_irqrestore(&logbuf_lock, flags);
}
+#ifdef CONFIG_PRINTK_OFFLOAD
/*
* Returns true iff there is other cpu waiting to take over printing. This
* function also takes are of setting PRINTK_HANDOVER_B if we want to hand over
@@ -2279,6 +2284,23 @@ static bool cpu_stop_printing(int printed_chars)
return false;
}
+#define spin_lock_print_lock(flags) spin_lock_irqsave(&print_lock, flags)
+
+#define spin_unlock_print_lock(flags) spin_unlock_irqrestore(&print_lock, flags)
+
+#else
+
+static bool cpu_stop_printing(int printed_chars)
+{
+ return false;
+}
+
+#define spin_lock_print_lock(flags) local_irq_save(flags)
+
+#define spin_unlock_print_lock(flags) local_irq_restore(flags)
+
+#endif
+
/**
* console_unlock - unlock the console system
*
@@ -2317,7 +2339,7 @@ void console_unlock(void)
console_cont_flush(text, sizeof(text));
again:
retry = false;
- spin_lock_irqsave(&print_lock, flags);
+ spin_lock_print_lock(flags);
for (;;) {
struct printk_log *msg;
size_t ext_len = 0;
@@ -2416,7 +2438,7 @@ skip:
* succeeds in getting console_sem (unless someone else takes it and
* then he'll be responsible for printing).
*/
- spin_unlock_irqrestore(&print_lock, flags);
+ spin_unlock_print_lock(flags);
/*
* In case we cannot trylock the console_sem again, there's a new owner
@@ -2776,6 +2798,7 @@ int unregister_console(struct console *console)
}
EXPORT_SYMBOL(unregister_console);
+#ifdef CONFIG_PRINTK_OFFLOAD
/* Kthread which takes over printing from a CPU which asks for help */
static int printing_task(void *arg)
{
@@ -2868,6 +2891,14 @@ static void printk_offload_init(void)
mutex_unlock(&printk_kthread_mutex);
}
+#else /* CONFIG_PRINTK_OFFLOAD */
+
+static void printk_offload_init(void)
+{
+}
+
+#endif /* CONFIG_PRINTK_OFFLOAD */
+
static int __init printk_late_init(void)
{
struct console *con;
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/