Skip to content

Commit

Permalink
printk: add printk_delay to make messages readable for some scenarios
Browse files Browse the repository at this point in the history
When syslog is not possible, at the same time there's no serial/net
console available, it will be hard to read the printk messages.  For
example oops/panic/warning messages in shutdown phase.

Add a printk delay feature, we can make each printk message delay some
milliseconds.

Setting the delay by proc/sysctl interface: /proc/sys/kernel/printk_delay

The value range from 0 - 10000, default value is 0

[[email protected]: fix a few things]
Signed-off-by: Dave Young <[email protected]>
Acked-by: Ingo Molnar <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
hidave authored and torvalds committed Sep 23, 2009
1 parent 3a3b6ed commit af91322
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Documentation/sysctl/kernel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,14 @@ send before ratelimiting kicks in.

==============================================================

printk_delay:

Delay each printk message in printk_delay milliseconds

Value from 0 - 10000 is allowed.

==============================================================

randomize-va-space:

This option can be used to select the type of process address
Expand Down
2 changes: 2 additions & 0 deletions include/linux/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ extern int printk_ratelimit(void);
extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
unsigned int interval_msec);

extern int printk_delay_msec;

/*
* Print a one-time message (analogous to WARN_ONCE() et al):
*/
Expand Down
15 changes: 15 additions & 0 deletions kernel/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,20 @@ static int recursion_bug;
static int new_text_line = 1;
static char printk_buf[1024];

int printk_delay_msec __read_mostly;

static inline void printk_delay(void)
{
if (unlikely(printk_delay_msec)) {
int m = printk_delay_msec;

while (m--) {
mdelay(1);
touch_nmi_watchdog();
}
}
}

asmlinkage int vprintk(const char *fmt, va_list args)
{
int printed_len = 0;
Expand All @@ -662,6 +676,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
char *p;

boot_delay_msec();
printk_delay();

preempt_disable();
/* This stops the holder of console_sem just where we want him */
Expand Down
14 changes: 14 additions & 0 deletions kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ static int __maybe_unused one = 1;
static int __maybe_unused two = 2;
static unsigned long one_ul = 1;
static int one_hundred = 100;
#ifdef CONFIG_PRINTK
static int ten_thousand = 10000;
#endif

/* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
Expand Down Expand Up @@ -722,6 +725,17 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = CTL_UNNUMBERED,
.procname = "printk_delay",
.data = &printk_delay_msec,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
.strategy = &sysctl_intvec,
.extra1 = &zero,
.extra2 = &ten_thousand,
},
#endif
{
.ctl_name = KERN_NGROUPS_MAX,
Expand Down

0 comments on commit af91322

Please sign in to comment.