From patchwork Mon May 30 13:48:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9141519 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 820E460777 for ; Mon, 30 May 2016 13:51:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7360E28188 for ; Mon, 30 May 2016 13:51:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 66A0E2819E; Mon, 30 May 2016 13:51:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6984D28188 for ; Mon, 30 May 2016 13:51:02 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1b7NYY-0005cB-9I; Mon, 30 May 2016 13:48:34 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1b7NYX-0005c5-Dn for xen-devel@lists.xenproject.org; Mon, 30 May 2016 13:48:33 +0000 Received: from [85.158.139.211] by server-10.bemta-5.messagelabs.com id E7/3B-11369-0B44C475; Mon, 30 May 2016 13:48:32 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrKIsWRWlGSWpSXmKPExsXS6fjDS3e9i0+ 4QetBFYvvWyYzOTB6HP5whSWAMYo1My8pvyKBNeP2ZPmCtqCKmf3fGBsYtzp0MXJyCAnkSTzc 0MIOYvMK2Elc6PzEAmJLCBhK7Ju/ig3EZhFQlXi27T8jiM0moC7R9mw7axcjB4eIgIHEuaNJX YxcHMwCrYwSRxo3gdULC/hLHFl0jQWkhldAUOLvDmGQMDPQ+O7nb5gnMHLNQsjMQpKBsLUkHv 66xQJha0ssW/iaGaScWUBaYvk/Dpjy79/noykBsT0lXs5rYVnAyLGKUaM4tagstUjX0FQvqSg zPaMkNzEzR9fQwFQvN7W4ODE9NScxqVgvOT93EyMw+BiAYAdjw3bPQ4ySHExKoryTfnqHC/El 5adUZiQWZ8QXleakFh9ilOHgUJLgTXH2CRcSLEpNT61Iy8wBxgFMWoKDR0mE1xwkzVtckJhbn JkOkTrFqCglzhsMkhAASWSU5sG1wWLvEqOslDAvI9AhQjwFqUW5mSWo8q8YxTkYlYR5/UCm8G TmlcBNfwW0mAlosdk5L5DFJYkIKakGRvYb3C+lWibV7LkhkpD/6sTbbf4tHOfNL2zaNLfu0dn HM5/emH0j5PDUzlWuEneV+qf/UtNn0T9zKuZ6HeP+vxZ9T1pkeJVTjGRS1jZu3rPf9/SLZXYF 4U73Ztnenf8wjqvIZNXMDy9/HqguWrVl7XrpLS66BydfjbG/dDAla+XenYlr7Cfu1a1QYinOS DTUYi4qTgQAK/VcnLgCAAA= X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-8.tower-206.messagelabs.com!1464616109!42088353!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 8.46; banners=-,-,- X-VirusChecked: Checked Received: (qmail 33941 invoked from network); 30 May 2016 13:48:31 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-8.tower-206.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 30 May 2016 13:48:31 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Mon, 30 May 2016 07:48:28 -0600 Message-Id: <574C60CA02000078000EFAF6@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.0 Date: Mon, 30 May 2016 07:48:26 -0600 From: "Jan Beulich" To: "xen-devel" Mime-Version: 1.0 Cc: Andrew Cooper , Daniel Kiper , David Vrabel Subject: [Xen-devel] [PATCH] kexec: allow relaxed placement specification via command line X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Rather than just allowing a fixed address or fully automatic placement, also allow for specifying an upper bound. Especially on EFI systems, where firmware memory use is commonly less predictable than on legacy BIOS ones, this makes success of the reservation more likely when automatic placement is not an option (e.g. because of special DMA restrictions of devices involved in actually carrying out the dump). Also take the opportunity to actually add text to the "crashkernel" entry in the command line option doc. Signed-off-by: Jan Beulich kexec: allow relaxed placement specification via command line Rather than just allowing a fixed address or fully automatic placement, also allow for specifying an upper bound. Especially on EFI systems, where firmware memory use is commonly less predictable than on legacy BIOS ones, this makes success of the reservation more likely when automatic placement is not an option (e.g. because of special DMA restrictions of devices involved in actually carrying out the dump). Also take the opportunity to actually add text to the "crashkernel" entry in the command line option doc. Signed-off-by: Jan Beulich --- a/docs/misc/xen-command-line.markdown +++ b/docs/misc/xen-command-line.markdown @@ -458,7 +458,18 @@ Specify the maximum address to allocate combination with the `low_crashinfo` command line option. ### crashkernel -> `= :[,...][@]` +> `= :[,...][{@,<}]` +> `= [{@,<}]` + +Specify sizes and optionally placement of the kexec reservation area. +The `:' pairs indicate how much memory to set +aside for kexec (`') for a given range of installed RAM +(`'). Each `' is of the form +`-[]'. + +A trailing `@' specifies the exact address this area should be +placed at, whereas `<' in place of `@' just specifies an upper bound of +the address range the area should fall into. ### credit2\_balance\_over > `= ` --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1044,13 +1044,19 @@ void __init noreturn __start_xen(unsigne } #ifdef CONFIG_KEXEC - /* Don't overlap with modules. */ - e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size), - mod, mbi->mods_count, -1); - if ( !kexec_crash_area.start && (s < e) ) + while ( !kexec_crash_area.start ) { - e = (e - kexec_crash_area.size) & PAGE_MASK; - kexec_crash_area.start = e; + /* Don't overlap with modules. */ + e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size), + mod, mbi->mods_count, -1); + if ( s >= e ) + break; + if ( e > kexec_crash_area_limit ) + { + e = kexec_crash_area_limit & PAGE_MASK; + continue; + } + kexec_crash_area.start = (e - kexec_crash_area.size) & PAGE_MASK; } #endif } --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -60,6 +60,7 @@ static unsigned char vmcoreinfo_data[VMC static size_t vmcoreinfo_size = 0; xen_kexec_reserve_t kexec_crash_area; +paddr_t __initdata kexec_crash_area_limit = ~(paddr_t)0; static struct { u64 start, end; unsigned long size; @@ -86,7 +87,7 @@ static void *crash_heap_current = NULL, /* * Parse command lines in the format * - * crashkernel=:[,...][@] + * crashkernel=:[,...][{@,<}
] * * with being of form * @@ -94,7 +95,7 @@ static void *crash_heap_current = NULL, * * as well as the legacy ones in the format * - * crashkernel=[@] + * crashkernel=[{@,<}
] */ static void __init parse_crashkernel(const char *str) { @@ -109,7 +110,7 @@ static void __init parse_crashkernel(con { printk(XENLOG_WARNING "crashkernel: too many ranges\n"); cur = NULL; - str = strchr(str, '@'); + str = strpbrk(str, "@<"); break; } @@ -154,9 +155,16 @@ static void __init parse_crashkernel(con } else kexec_crash_area.size = parse_size_and_unit(cur = str, &str); - if ( cur != str && *str == '@' ) - kexec_crash_area.start = parse_size_and_unit(cur = str + 1, &str); - if ( cur == str ) + if ( cur != str ) + { + if ( *str == '@' ) + kexec_crash_area.start = parse_size_and_unit(cur = str + 1, &str); + else if ( *str == '<' ) + kexec_crash_area_limit = parse_size_and_unit(cur = str + 1, &str); + else + printk(XENLOG_WARNING "crashkernel: '%s' ignored\n", str); + } + if ( cur && cur == str ) printk(XENLOG_WARNING "crashkernel: memory value expected\n"); } custom_param("crashkernel", parse_crashkernel); --- a/xen/include/xen/kexec.h +++ b/xen/include/xen/kexec.h @@ -14,6 +14,7 @@ typedef struct xen_kexec_reserve { } xen_kexec_reserve_t; extern xen_kexec_reserve_t kexec_crash_area; +extern paddr_t kexec_crash_area_limit; extern bool_t kexecing; Reviewed-by: David Vrabel --- a/docs/misc/xen-command-line.markdown +++ b/docs/misc/xen-command-line.markdown @@ -458,7 +458,18 @@ Specify the maximum address to allocate combination with the `low_crashinfo` command line option. ### crashkernel -> `= :[,...][@]` +> `= :[,...][{@,<}]` +> `= [{@,<}]` + +Specify sizes and optionally placement of the kexec reservation area. +The `:' pairs indicate how much memory to set +aside for kexec (`') for a given range of installed RAM +(`'). Each `' is of the form +`-[]'. + +A trailing `@' specifies the exact address this area should be +placed at, whereas `<' in place of `@' just specifies an upper bound of +the address range the area should fall into. ### credit2\_balance\_over > `= ` --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1044,13 +1044,19 @@ void __init noreturn __start_xen(unsigne } #ifdef CONFIG_KEXEC - /* Don't overlap with modules. */ - e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size), - mod, mbi->mods_count, -1); - if ( !kexec_crash_area.start && (s < e) ) + while ( !kexec_crash_area.start ) { - e = (e - kexec_crash_area.size) & PAGE_MASK; - kexec_crash_area.start = e; + /* Don't overlap with modules. */ + e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size), + mod, mbi->mods_count, -1); + if ( s >= e ) + break; + if ( e > kexec_crash_area_limit ) + { + e = kexec_crash_area_limit & PAGE_MASK; + continue; + } + kexec_crash_area.start = (e - kexec_crash_area.size) & PAGE_MASK; } #endif } --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -60,6 +60,7 @@ static unsigned char vmcoreinfo_data[VMC static size_t vmcoreinfo_size = 0; xen_kexec_reserve_t kexec_crash_area; +paddr_t __initdata kexec_crash_area_limit = ~(paddr_t)0; static struct { u64 start, end; unsigned long size; @@ -86,7 +87,7 @@ static void *crash_heap_current = NULL, /* * Parse command lines in the format * - * crashkernel=:[,...][@] + * crashkernel=:[,...][{@,<}
] * * with being of form * @@ -94,7 +95,7 @@ static void *crash_heap_current = NULL, * * as well as the legacy ones in the format * - * crashkernel=[@] + * crashkernel=[{@,<}
] */ static void __init parse_crashkernel(const char *str) { @@ -109,7 +110,7 @@ static void __init parse_crashkernel(con { printk(XENLOG_WARNING "crashkernel: too many ranges\n"); cur = NULL; - str = strchr(str, '@'); + str = strpbrk(str, "@<"); break; } @@ -154,9 +155,16 @@ static void __init parse_crashkernel(con } else kexec_crash_area.size = parse_size_and_unit(cur = str, &str); - if ( cur != str && *str == '@' ) - kexec_crash_area.start = parse_size_and_unit(cur = str + 1, &str); - if ( cur == str ) + if ( cur != str ) + { + if ( *str == '@' ) + kexec_crash_area.start = parse_size_and_unit(cur = str + 1, &str); + else if ( *str == '<' ) + kexec_crash_area_limit = parse_size_and_unit(cur = str + 1, &str); + else + printk(XENLOG_WARNING "crashkernel: '%s' ignored\n", str); + } + if ( cur && cur == str ) printk(XENLOG_WARNING "crashkernel: memory value expected\n"); } custom_param("crashkernel", parse_crashkernel); --- a/xen/include/xen/kexec.h +++ b/xen/include/xen/kexec.h @@ -14,6 +14,7 @@ typedef struct xen_kexec_reserve { } xen_kexec_reserve_t; extern xen_kexec_reserve_t kexec_crash_area; +extern paddr_t kexec_crash_area_limit; extern bool_t kexecing;