| From b72b514282ffad0d665ea94932b968f388304079 Mon Sep 17 00:00:00 2001 |
| From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| Date: Thu, 21 Mar 2013 19:01:05 +0100 |
| Subject: [PATCH] HACK: printk: drop the logbuf_lock more often |
| |
| The lock is hold with irgs off. The latency drops 500us+ on my arm bugs |
| with a "full" buffer after executing "dmesg" on the shell. |
| |
| Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| --- |
| kernel/printk.c | 27 ++++++++++++++++++++++++++- |
| 1 file changed, 26 insertions(+), 1 deletion(-) |
| |
| --- a/kernel/printk.c |
| +++ b/kernel/printk.c |
| @@ -1034,6 +1034,7 @@ static int syslog_print_all(char __user |
| { |
| char *text; |
| int len = 0; |
| + int attempts = 0; |
| |
| text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); |
| if (!text) |
| @@ -1045,7 +1046,14 @@ static int syslog_print_all(char __user |
| u64 seq; |
| u32 idx; |
| enum log_flags prev; |
| - |
| + int num_msg; |
| +try_again: |
| + attempts++; |
| + if (attempts > 10) { |
| + len = -EBUSY; |
| + goto out; |
| + } |
| + num_msg = 0; |
| if (clear_seq < log_first_seq) { |
| /* messages are gone, move to first available one */ |
| clear_seq = log_first_seq; |
| @@ -1066,6 +1074,14 @@ static int syslog_print_all(char __user |
| prev = msg->flags; |
| idx = log_next(idx); |
| seq++; |
| + num_msg++; |
| + if (num_msg > 5) { |
| + num_msg = 0; |
| + raw_spin_unlock_irq(&logbuf_lock); |
| + raw_spin_lock_irq(&logbuf_lock); |
| + if (clear_seq < log_first_seq) |
| + goto try_again; |
| + } |
| } |
| |
| /* move first record forward until length fits into the buffer */ |
| @@ -1079,6 +1095,14 @@ static int syslog_print_all(char __user |
| prev = msg->flags; |
| idx = log_next(idx); |
| seq++; |
| + num_msg++; |
| + if (num_msg > 5) { |
| + num_msg = 0; |
| + raw_spin_unlock_irq(&logbuf_lock); |
| + raw_spin_lock_irq(&logbuf_lock); |
| + if (clear_seq < log_first_seq) |
| + goto try_again; |
| + } |
| } |
| |
| /* last message fitting into this dump */ |
| @@ -1120,6 +1144,7 @@ static int syslog_print_all(char __user |
| clear_seq = log_next_seq; |
| clear_idx = log_next_idx; |
| } |
| +out: |
| raw_spin_unlock_irq(&logbuf_lock); |
| |
| kfree(text); |