From patchwork Wed Jan 19 23:01:07 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Travis X-Patchwork-Id: 490691 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0JN26jH030823 for ; Wed, 19 Jan 2011 23:02:07 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755132Ab1ASXBX (ORCPT ); Wed, 19 Jan 2011 18:01:23 -0500 Received: from relay1.sgi.com ([192.48.179.29]:44159 "EHLO relay.sgi.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755103Ab1ASXBV (ORCPT ); Wed, 19 Jan 2011 18:01:21 -0500 Received: from gulag1.americas.sgi.com (gulag1.americas.sgi.com [128.162.236.41]) by relay1.corp.sgi.com (Postfix) with ESMTP id C31988F8084; Wed, 19 Jan 2011 15:01:06 -0800 (PST) Received: by gulag1.americas.sgi.com (Postfix, from userid 5508) id A144E1037689C; Wed, 19 Jan 2011 17:01:06 -0600 (CST) Message-Id: <20110119230106.527741713@gulag1.americas.sgi.com> References: <20110119230106.341785959@gulag1.americas.sgi.com> User-Agent: quilt/0.46-1 Date: Wed, 19 Jan 2011 17:01:07 -0600 From: Mike Travis To: Ingo Molnar , Len Brown , "H. Peter Anvin" Cc: Thomas Gleixner , Jack Steiner , Robin Holt , Lori Gilbertson , x86@kernel.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org Subject: [PATCH 1/6] printk: Allocate kernel log buffer earlier Content-Disposition: inline; filename=get_log_buff_early Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Wed, 19 Jan 2011 23:02:07 +0000 (UTC) --- linux-2.6.32.orig/arch/x86/kernel/setup.c +++ linux-2.6.32/arch/x86/kernel/setup.c @@ -966,6 +966,11 @@ void __init setup_arch(char **cmdline_p) initmem_init(0, max_pfn); + /* + * Allocate bigger log buffer as early as possible + */ + setup_log_buf(); + #ifdef CONFIG_ACPI_SLEEP /* * Reserve low memory region for sleep support. --- linux-2.6.32.orig/include/linux/kernel.h +++ linux-2.6.32/include/linux/kernel.h @@ -281,6 +281,8 @@ static inline void log_buf_kexec_setup(v } #endif +void setup_log_buf(void); + extern int printk_needs_cpu(int cpu); extern void printk_tick(void); --- linux-2.6.32.orig/init/main.c +++ linux-2.6.32/init/main.c @@ -589,6 +589,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-2.6.32.orig/kernel/printk.c +++ linux-2.6.32/kernel/printk.c @@ -167,46 +167,66 @@ 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)); + + spin_lock_irqsave(&logbuf_lock, flags); + log_buf_len = new_log_buf_len; + log_buf = new_log_buf; + new_log_buf_len = 0; + + offset = start = min(con_start, log_start); + dest_idx = 0; + while (start != log_end) { + unsigned log_idx_mask = start & (__LOG_BUF_LEN - 1); + + log_buf[dest_idx] = __log_buf[log_idx_mask]; + if (dest_idx < sizeof(first_line) - 1) + first_line[dest_idx] = __log_buf[log_idx_mask]; + start++; + dest_idx++; + } + log_start -= offset; + con_start -= offset; + log_end -= offset; + spin_unlock_irqrestore(&logbuf_lock, flags); + + first_nl = strchr(first_line, '\n'); + if (first_nl) + *first_nl = '\0'; + + pr_info("log_buf_len: %d, first line: %s\n", + log_buf_len, first_line); + + pr_debug("bu: %d/%d (%d%%)\n", + dest_idx, __LOG_BUF_LEN - dest_idx, + (dest_idx * 100) / __LOG_BUF_LEN); +} #ifdef CONFIG_BOOT_PRINTK_DELAY