aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index 8451dfc31d25..b2b5c3a22a36 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -22,6 +22,8 @@
22#include <linux/tty_driver.h> 22#include <linux/tty_driver.h>
23#include <linux/console.h> 23#include <linux/console.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/jiffies.h>
26#include <linux/nmi.h>
25#include <linux/module.h> 27#include <linux/module.h>
26#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
27#include <linux/interrupt.h> /* For in_interrupt() */ 29#include <linux/interrupt.h> /* For in_interrupt() */
@@ -162,6 +164,61 @@ out:
162 164
163__setup("log_buf_len=", log_buf_len_setup); 165__setup("log_buf_len=", log_buf_len_setup);
164 166
167#ifdef CONFIG_BOOT_PRINTK_DELAY
168
169static unsigned int boot_delay; /* msecs delay after each printk during bootup */
170static unsigned long long printk_delay_msec; /* per msec, based on boot_delay */
171
172static int __init boot_delay_setup(char *str)
173{
174 unsigned long lpj;
175 unsigned long long loops_per_msec;
176
177 lpj = preset_lpj ? preset_lpj : 1000000; /* some guess */
178 loops_per_msec = (unsigned long long)lpj / 1000 * HZ;
179
180 get_option(&str, &boot_delay);
181 if (boot_delay > 10 * 1000)
182 boot_delay = 0;
183
184 printk_delay_msec = loops_per_msec;
185 printk(KERN_DEBUG "boot_delay: %u, preset_lpj: %ld, lpj: %lu, "
186 "HZ: %d, printk_delay_msec: %llu\n",
187 boot_delay, preset_lpj, lpj, HZ, printk_delay_msec);
188 return 1;
189}
190__setup("boot_delay=", boot_delay_setup);
191
192static void boot_delay_msec(void)
193{
194 unsigned long long k;
195 unsigned long timeout;
196
197 if (boot_delay == 0 || system_state != SYSTEM_BOOTING)
198 return;
199
200 k = (unsigned long long)printk_delay_msec * boot_delay;
201
202 timeout = jiffies + msecs_to_jiffies(boot_delay);
203 while (k) {
204 k--;
205 cpu_relax();
206 /*
207 * use (volatile) jiffies to prevent
208 * compiler reduction; loop termination via jiffies
209 * is secondary and may or may not happen.
210 */
211 if (time_after(jiffies, timeout))
212 break;
213 touch_nmi_watchdog();
214 }
215}
216#else
217static inline void boot_delay_msec(void)
218{
219}
220#endif
221
165/* 222/*
166 * Commands to do_syslog: 223 * Commands to do_syslog:
167 * 224 *
@@ -527,6 +584,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
527 static char printk_buf[1024]; 584 static char printk_buf[1024];
528 static int log_level_unknown = 1; 585 static int log_level_unknown = 1;
529 586
587 boot_delay_msec();
588
530 preempt_disable(); 589 preempt_disable();
531 if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id()) 590 if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id())
532 /* If a crash is occurring during printk() on this CPU, 591 /* If a crash is occurring during printk() on this CPU,