diff options
Diffstat (limited to 'kernel/printk.c')
| -rw-r--r-- | kernel/printk.c | 59 |
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 | |||
| 169 | static unsigned int boot_delay; /* msecs delay after each printk during bootup */ | ||
| 170 | static unsigned long long printk_delay_msec; /* per msec, based on boot_delay */ | ||
| 171 | |||
| 172 | static 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 | |||
| 192 | static 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 | ||
| 217 | static 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, |
