[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <578EFCA1.1070405@linux.vnet.ibm.com>
Date: Wed, 20 Jul 2016 09:52:57 +0530
From: Hari Bathini <hbathini@...ux.vnet.ibm.com>
To: Eric Biederman <ebiederm@...ssion.com>,
Vivek Goyal <vgoyal@...hat.com>
Cc: Michael Ellerman <mpe@...erman.id.au>,
lkml <linux-kernel@...r.kernel.org>,
linuxppc-dev <linuxppc-dev@...abs.org>,
Rusty Russell <rusty@...tcorp.com.au>,
kexec@...ts.infradead.org
Subject: Re: [v2,1/2] refactor code parsing size based on memory range
Ping..
On Friday 24 June 2016 10:45 PM, Hari Bathini wrote:
>
>
> On 06/24/2016 10:56 AM, Michael Ellerman wrote:
>> On Wed, 2016-22-06 at 19:25:26 UTC, Hari Bathini wrote:
>>> Currently, crashkernel parameter supports the below syntax to parse
>>> size
>>> based on memory range:
>>>
>>> crashkernel=<range1>:<size1>[,<range2>:<size2>,...]
>>>
>>> While such parsing is implemented for crashkernel parameter, it
>>> applies to
>>> other parameters with similar syntax. So, move this code to a more
>>> generic
>>> place for code reuse.
>>>
>>> Cc: Eric Biederman <ebiederm@...ssion.com>
>>> Cc: Vivek Goyal <vgoyal@...hat.com>
>>> Cc: Rusty Russell <rusty@...tcorp.com.au>
>>> Cc: kexec@...ts.infradead.org
>>> Signed-off-by: Hari Bathini <hbathini@...ux.vnet.ibm.com>
>> Hari, it's not immediately clear that this makes no change to the
>> logic in the
>> kexec code. Can you reply with a longer change log explaining why the
>> old & new
>> logic is the same for kexec.
>>
>
> Hi Michael,
>
> Please consider this changelog for this patch:
>
> --
> crashkernel parameter supports different syntaxes to specify the amount
> of memory to be reserved for kdump kernel. Below is one of the supported
> syntaxes that needs parsing to find the memory size to reserve, based on
> memory range:
>
> crashkernel=<range1>:<size1>[,<range2>:<size2>,...]
>
> While such parsing is implemented for crashkernel parameter, it
> applies to
> other parameters, like fadump_reserve_mem, which could use similar
> syntax.
> So, to reuse code, moving the code that checks if the parameter syntax
> is as
> above and also the code that parses memory size to reserve, for this
> syntax.
> While the code is moved to kernel/params.c file, there is no change in
> logic
> for crashkernel parameter parsing as the moved code is invoked with
> function
> calls at appropriate places.
> --
>
> Thanks
> Hari
>
>>
>>
>>> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
>>> index 94aa10f..72f55e5 100644
>>> --- a/include/linux/kernel.h
>>> +++ b/include/linux/kernel.h
>>> @@ -436,6 +436,11 @@ extern char *get_options(const char *str, int
>>> nints, int *ints);
>>> extern unsigned long long memparse(const char *ptr, char **retptr);
>>> extern bool parse_option_str(const char *str, const char *option);
>>> +extern bool __init is_param_range_based(const char *cmdline);
>>> +extern unsigned long long __init parse_mem_range_size(const char
>>> *param,
>>> + char **str,
>>> + unsigned long long system_ram);
>>> +
>>> extern int core_kernel_text(unsigned long addr);
>>> extern int core_kernel_data(unsigned long addr);
>>> extern int __kernel_text_address(unsigned long addr);
>>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
>>> index 56b3ed0..d43f5cc 100644
>>> --- a/kernel/kexec_core.c
>>> +++ b/kernel/kexec_core.c
>>> @@ -1083,59 +1083,9 @@ static int __init parse_crashkernel_mem(char
>>> *cmdline,
>>> char *cur = cmdline, *tmp;
>>> /* for each entry of the comma-separated list */
>>> - do {
>>> - unsigned long long start, end = ULLONG_MAX, size;
>>> -
>>> - /* get the start of the range */
>>> - start = memparse(cur, &tmp);
>>> - if (cur == tmp) {
>>> - pr_warn("crashkernel: Memory value expected\n");
>>> - return -EINVAL;
>>> - }
>>> - cur = tmp;
>>> - if (*cur != '-') {
>>> - pr_warn("crashkernel: '-' expected\n");
>>> - return -EINVAL;
>>> - }
>>> - cur++;
>>> -
>>> - /* if no ':' is here, than we read the end */
>>> - if (*cur != ':') {
>>> - end = memparse(cur, &tmp);
>>> - if (cur == tmp) {
>>> - pr_warn("crashkernel: Memory value expected\n");
>>> - return -EINVAL;
>>> - }
>>> - cur = tmp;
>>> - if (end <= start) {
>>> - pr_warn("crashkernel: end <= start\n");
>>> - return -EINVAL;
>>> - }
>>> - }
>>> -
>>> - if (*cur != ':') {
>>> - pr_warn("crashkernel: ':' expected\n");
>>> - return -EINVAL;
>>> - }
>>> - cur++;
>>> -
>>> - size = memparse(cur, &tmp);
>>> - if (cur == tmp) {
>>> - pr_warn("Memory value expected\n");
>>> - return -EINVAL;
>>> - }
>>> - cur = tmp;
>>> - if (size >= system_ram) {
>>> - pr_warn("crashkernel: invalid size\n");
>>> - return -EINVAL;
>>> - }
>>> -
>>> - /* match ? */
>>> - if (system_ram >= start && system_ram < end) {
>>> - *crash_size = size;
>>> - break;
>>> - }
>>> - } while (*cur++ == ',');
>>> + *crash_size = parse_mem_range_size("crashkernel", &cur,
>>> system_ram);
>>> + if (cur == cmdline)
>>> + return -EINVAL;
>>> if (*crash_size > 0) {
>>> while (*cur && *cur != ' ' && *cur != '@')
>>> @@ -1272,7 +1222,6 @@ static int __init __parse_crashkernel(char
>>> *cmdline,
>>> const char *name,
>>> const char *suffix)
>>> {
>>> - char *first_colon, *first_space;
>>> char *ck_cmdline;
>>> BUG_ON(!crash_size || !crash_base);
>>> @@ -1290,12 +1239,10 @@ static int __init __parse_crashkernel(char
>>> *cmdline,
>>> return parse_crashkernel_suffix(ck_cmdline, crash_size,
>>> suffix);
>>> /*
>>> - * if the commandline contains a ':', then that's the extended
>>> + * if the parameter is range based, then that's the extended
>>> * syntax -- if not, it must be the classic syntax
>>> */
>>> - first_colon = strchr(ck_cmdline, ':');
>>> - first_space = strchr(ck_cmdline, ' ');
>>> - if (first_colon && (!first_space || first_colon < first_space))
>>> + if (is_param_range_based(ck_cmdline))
>>> return parse_crashkernel_mem(ck_cmdline, system_ram,
>>> crash_size, crash_base);
>>> diff --git a/kernel/params.c b/kernel/params.c
>>> index a6d6149..84e40ae 100644
>>> --- a/kernel/params.c
>>> +++ b/kernel/params.c
>>> @@ -268,6 +268,102 @@ char *parse_args(const char *doing,
>>> return err;
>>> }
>>> +/*
>>> + * is_param_range_based - check if current parameter is range based
>>> + * @cmdline: points to the parameter to check
>>> + *
>>> + * Returns true when the current paramer is range based, false
>>> otherwise
>>> + */
>>> +bool __init is_param_range_based(const char *cmdline)
>>> +{
>>> + char *first_colon, *first_space;
>>> +
>>> + first_colon = strchr(cmdline, ':');
>>> + first_space = strchr(cmdline, ' ');
>>> + if (first_colon && (!first_space || first_colon < first_space))
>>> + return true;
>>> +
>>> + return false;
>>> +}
>>> +
>>> +/*
>>> + * parse_mem_range_size - parse size based on memory range
>>> + * @param: the thing being parsed
>>> + * @str: (input) where parse begins
>>> + * expected format -
>>> <range1>:<size1>[,<range2>:<size2>,...]
>>> + * (output) On success - next char after parse completes
>>> + * On failure - unchanged
>>> + * @system_ram: system ram size to check memory range against
>>> + *
>>> + * Returns the memory size on success and 0 on failure
>>> + */
>>> +unsigned long long __init parse_mem_range_size(const char *param,
>>> + char **str,
>>> + unsigned long long system_ram)
>>> +{
>>> + char *cur = *str, *tmp;
>>> + unsigned long long mem_size = 0;
>>> +
>>> + /* for each entry of the comma-separated list */
>>> + do {
>>> + unsigned long long start, end = ULLONG_MAX, size;
>>> +
>>> + /* get the start of the range */
>>> + start = memparse(cur, &tmp);
>>> + if (cur == tmp) {
>>> + printk(KERN_INFO "%s: Memory value expected\n", param);
>>> + return mem_size;
>>> + }
>>> + cur = tmp;
>>> + if (*cur != '-') {
>>> + printk(KERN_INFO "%s: '-' expected\n", param);
>>> + return mem_size;
>>> + }
>>> + cur++;
>>> +
>>> + /* if no ':' is here, than we read the end */
>>> + if (*cur != ':') {
>>> + end = memparse(cur, &tmp);
>>> + if (cur == tmp) {
>>> + printk(KERN_INFO "%s: Memory value expected\n",
>>> + param);
>>> + return mem_size;
>>> + }
>>> + cur = tmp;
>>> + if (end <= start) {
>>> + printk(KERN_INFO "%s: end <= start\n", param);
>>> + return mem_size;
>>> + }
>>> + }
>>> +
>>> + if (*cur != ':') {
>>> + printk(KERN_INFO "%s: ':' expected\n", param);
>>> + return mem_size;
>>> + }
>>> + cur++;
>>> +
>>> + size = memparse(cur, &tmp);
>>> + if (cur == tmp) {
>>> + printk(KERN_INFO "%s: Memory value expected\n", param);
>>> + return mem_size;
>>> + }
>>> + cur = tmp;
>>> + if (size >= system_ram) {
>>> + printk(KERN_INFO "%s: invalid size\n", param);
>>> + return mem_size;
>>> + }
>>> +
>>> + /* match ? */
>>> + if (system_ram >= start && system_ram < end) {
>>> + mem_size = size;
>>> + *str = cur;
>>> + break;
>>> + }
>>> + } while (*cur++ == ',');
>>> +
>>> + return mem_size;
>>> +}
>>> +
>>> /* Lazy bastard, eh? */
>>> #define STANDARD_PARAM_DEF(name, type, format,
>>> strtolfn) \
>>> int param_set_##name(const char *val, const struct
>>> kernel_param *kp) \
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@...ts.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
> _______________________________________________
> kexec mailing list
> kexec@...ts.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
>
Powered by blists - more mailing lists