On Thu, Feb 17, 2011 at 10:51 AM, Mike Travis <travis@xxxxxxx> wrote: > On larger systems, because of the numerous ACPI, Bootmem and EFI > messages, the static log buffer overflows before the larger one > specified by the log_buf_len param is allocated. Minimize the > overflow by allocating the new log buffer as soon as possible. > > All arch's are covered by the "setup_log_buf" in start_kernel(). > The x86 arch allocates it right after bootmem is created. > > v1: Added pertinent __init & __initdata specifiers. > v2: updated to apply to x86-tip > > Signed-off-by: Mike Travis <travis@xxxxxxx> > Reviewed-by: Jack Steiner <steiner@xxxxxxx> > Reviewed-by: Robin Holt <holt@xxxxxxx> > --- > arch/x86/kernel/setup.c | 5 ++ > include/linux/printk.h | 4 ++ > init/main.c | 1 > kernel/printk.c | 81 +++++++++++++++++++++++++++++------------------- > 4 files changed, 60 insertions(+), 31 deletions(-) > > --- linux.orig/arch/x86/kernel/setup.c > +++ linux/arch/x86/kernel/setup.c > @@ -1007,6 +1007,11 @@ void __init setup_arch(char **cmdline_p) > memblock_find_dma_reserve(); > dma32_reserve_bootmem(); > > + /* > + * Allocate bigger log buffer as early as possible > + */ > + setup_log_buf(); > + > #ifdef CONFIG_KVM_CLOCK > kvmclock_init(); > #endif > --- linux.orig/include/linux/printk.h > +++ linux/include/linux/printk.h > @@ -1,6 +1,8 @@ > #ifndef __KERNEL_PRINTK__ > #define __KERNEL_PRINTK__ > > +#include <linux/init.h> > + > extern const char linux_banner[]; > extern const char linux_proc_banner[]; > > @@ -89,6 +91,8 @@ int no_printk(const char *fmt, ...) > extern asmlinkage __attribute__ ((format (printf, 1, 2))) > void early_printk(const char *fmt, ...); > > +void __init setup_log_buf(void); > + > extern int printk_needs_cpu(int cpu); > extern void printk_tick(void); > > --- linux.orig/init/main.c > +++ linux/init/main.c > @@ -592,6 +592,7 @@ asmlinkage void __init start_kernel(void > * These use large bootmem allocations and must precede > * kmem_cache_init() > */ > + setup_log_buf(); > pidhash_init(); > vfs_caches_init_early(); > sort_main_extable(); > --- linux.orig/kernel/printk.c > +++ linux/kernel/printk.c > @@ -162,46 +162,65 @@ void log_buf_kexec_setup(void) > } > #endif > > +static unsigned long __initdata new_log_buf_len; > static int __init log_buf_len_setup(char *str) > { > unsigned size = memparse(str, &str); > - unsigned long flags; > > if (size) > size = roundup_pow_of_two(size); > - if (size > log_buf_len) { > - unsigned start, dest_idx, offset; > - char *new_log_buf; > - > - new_log_buf = alloc_bootmem(size); > - if (!new_log_buf) { > - printk(KERN_WARNING "log_buf_len: allocation failed\n"); > - goto out; > - } > - > - spin_lock_irqsave(&logbuf_lock, flags); > - log_buf_len = size; > - log_buf = new_log_buf; > - > - offset = start = min(con_start, log_start); > - dest_idx = 0; > - while (start != log_end) { > - log_buf[dest_idx] = __log_buf[start & (__LOG_BUF_LEN - 1)]; > - start++; > - dest_idx++; > - } > - log_start -= offset; > - con_start -= offset; > - log_end -= offset; > - spin_unlock_irqrestore(&logbuf_lock, flags); > + if (size > log_buf_len) > + new_log_buf_len = size; > > - printk(KERN_NOTICE "log_buf_len: %d\n", log_buf_len); > - } > -out: > - return 1; > + return 0; > } > +early_param("log_buf_len", log_buf_len_setup); > > -__setup("log_buf_len=", log_buf_len_setup); > +void __init setup_log_buf(void) > +{ > + unsigned long flags; > + unsigned start, dest_idx, offset; > + char *new_log_buf; > + char first_line[64], *first_nl; > + > + if (!new_log_buf_len) > + return; > + > + new_log_buf = alloc_bootmem(new_log_buf_len); > + memset(first_line, 0, sizeof(first_line)); use x86_memblock_find_range in x86 code? you can do that much earlier before SRAT etc is parsed. Thanks Yinghai -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html