public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 5/7] printk: Add config option for disabling printk offloading
  2015-10-26  4:52 [PATCH 0/6 v2] printk: Softlockup avoidance Jan Kara
@ 2015-10-26  4:52 ` Jan Kara
  0 siblings, 0 replies; 2+ messages in thread
From: Jan Kara @ 2015-10-26  4:52 UTC (permalink / raw)
  To: Andrew Morton; +Cc: LKML, pmladek, KY Srinivasan, rostedt, Jan Kara

From: Jan Kara <jack@suse.cz>

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@suse.cz>
---
 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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH 5/7] printk: Add config option for disabling printk offloading
@ 2015-12-10 15:10 Sergey Senozhatsky
  0 siblings, 0 replies; 2+ messages in thread
From: Sergey Senozhatsky @ 2015-12-10 15:10 UTC (permalink / raw)
  To: Jan Kara
  Cc: Andrew Morton, Petr Mladek, KY Srinivasan, Steven Rostedt,
	linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

> 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.

to be folded:


- add spin_lock_init_print_lock() to be called from zap_lock()
- move PRINTK_OFFLOAD defines up, so zap_lock() sees them

---
 kernel/printk/printk.c | 119 ++++++++++++++++++++++++++-----------------------
 1 file changed, 63 insertions(+), 56 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 2a500a5..86f5abf 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -333,7 +333,66 @@ 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
+
+/*
+ * 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
+ * printing to some other cpu.
+ */
+static bool cpu_stop_printing(int printed_chars)
+{
+	/* Oops? Print everything now to maximize chances user will see it */
+	if (oops_in_progress)
+		return false;
+	if (!printk_offload_chars || printed_chars < printk_offload_chars)
+		return false;
+	/*
+	 * Make sure we load fresh value of printing_tasks_spinning. Matches
+	 * the barrier in printing_task()
+	 */
+	smp_rmb();
+	if (atomic_read(&printing_tasks_spinning))
+		return true;
+	wake_up(&print_queue);
+
+	return false;
+}
+
+static bool cpu_should_cond_resched(bool do_cond_resched)
+{
+	/* Oops? Print everything now to maximize chances user will see it */
+	if (oops_in_progress)
+		return false;
+	if (!printk_offload_chars && do_cond_resched)
+		return true;
+	return false;
+}
+
+#define spin_lock_print_lock(flags) raw_spin_lock_irqsave(&print_lock, flags)
+
+#define spin_unlock_print_lock(flags) raw_spin_unlock_irqrestore(&print_lock, flags)
+
+#define spin_lock_init_print_lock() raw_spin_lock_init(&print_lock)
+
+#else /* !CONFIG_PRINTK_OFFLOAD */
+
+static bool cpu_stop_printing(int printed_chars)
+{
+	return false;
+}
+
+static bool cpu_should_cond_resched(bool do_cond_resched)
+{
+	return do_cond_resched && !oops_in_progress;
+}
+
+#define spin_lock_print_lock(flags) local_irq_save(flags)
+
+#define spin_unlock_print_lock(flags) local_irq_restore(flags)
+
+#define spin_lock_init_print_lock()
+
+#endif /* CONFIG_PRINTK_OFFLOAD */
 
 /* Return log buffer address */
 char *log_buf_addr_get(void)
@@ -1531,7 +1590,7 @@ static void zap_locks(void)
 	/* If a crash is occurring, make sure we can't deadlock */
 	raw_spin_lock_init(&logbuf_lock);
 	/* And make sure that we print immediately */
-	raw_spin_lock_init(&print_lock);
+	spin_lock_init_print_lock();
 	sema_init(&console_sem, 1);
 }
 
@@ -2265,58 +2324,6 @@ 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
- * printing to some other cpu.
- */
-static bool cpu_stop_printing(int printed_chars)
-{
-	/* Oops? Print everything now to maximize chances user will see it */
-	if (oops_in_progress)
-		return false;
-	if (!printk_offload_chars || printed_chars < printk_offload_chars)
-		return false;
-	/*
-	 * Make sure we load fresh value of printing_tasks_spinning. Matches
-	 * the barrier in printing_task()
-	 */
-	smp_rmb();
-	if (atomic_read(&printing_tasks_spinning))
-		return true;
-	wake_up(&print_queue);
-
-	return false;
-}
-
-static bool cpu_should_cond_resched(bool do_cond_resched)
-{
-	/* Oops? Print everything now to maximize chances user will see it */
-	if (oops_in_progress)
-		return false;
-	if (!printk_offload_chars && do_cond_resched)
-		return true;
-	return false;
-}
-
-#define spin_lock_print_lock(flags) raw_spin_lock_irqsave(&print_lock, flags)
-
-#define spin_unlock_print_lock(flags) raw_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
  *
@@ -2440,9 +2447,9 @@ skip:
 		printed_chars += len;
 
 		if (unlikely(cpu_should_cond_resched(do_cond_resched))) {
-			raw_spin_unlock_irqrestore(&print_lock, flags);
+			spin_unlock_print_lock(flags);
 			cond_resched();
-			raw_spin_lock_irqsave(&print_lock, flags);
+			spin_lock_print_lock(flags);
 		}
 	}
 
-- 
2.6.3


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-12-10 15:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-10 15:10 [PATCH 5/7] printk: Add config option for disabling printk offloading Sergey Senozhatsky
  -- strict thread matches above, loose matches on Subject: below --
2015-10-26  4:52 [PATCH 0/6 v2] printk: Softlockup avoidance Jan Kara
2015-10-26  4:52 ` [PATCH 5/7] printk: Add config option for disabling printk offloading Jan Kara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox