Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit adbc742b authored by Yinghai Lu's avatar Yinghai Lu Committed by H. Peter Anvin
Browse files

x86, kdump: Change crashkernel_high/low= to crashkernel=,high/low



Per hpa, use crashkernel=X,high crashkernel=Y,low instead of
crashkernel_hign=X crashkernel_low=Y. As that could be extensible.

-v2: according to Vivek, change delimiter to ;
-v3: let hign and low only handle simple form and it conforms to
	description in kernel-parameters.txt
     still keep crashkernel=X override any crashkernel=X,high
        crashkernel=Y,low
-v4: update get_last_crashkernel returning and add more strict
     checking in parse_crashkernel_simple() found by HATAYAMA.
-v5: Change delimiter back to , according to HPA.
     also separate parse_suffix from parse_simper according to vivek.
	so we can avoid @pos in that path.
-v6: Tight the checking about crashkernel=X,highblahblah,high
     found by HTYAYAMA.

Cc: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Link: http://lkml.kernel.org/r/1366089828-19692-5-git-send-email-yinghai@kernel.org


Acked-by: default avatarVivek Goyal <vgoyal@redhat.com>
Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
parent 55a20ee7
Loading
Loading
Loading
Loading
+5 −5
Original line number Original line Diff line number Diff line
@@ -603,16 +603,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
			a memory unit (amount[KMG]). See also
			a memory unit (amount[KMG]). See also
			Documentation/kdump/kdump.txt for an example.
			Documentation/kdump/kdump.txt for an example.


	crashkernel_high=size[KMG]
	crashkernel=size[KMG],high
			[KNL, x86_64] range could be above 4G. Allow kernel
			[KNL, x86_64] range could be above 4G. Allow kernel
			to allocate physical memory region from top, so could
			to allocate physical memory region from top, so could
			be above 4G if system have more than 4G ram installed.
			be above 4G if system have more than 4G ram installed.
			Otherwise memory region will be allocated below 4G, if
			Otherwise memory region will be allocated below 4G, if
			available.
			available.
			It will be ignored if crashkernel=X is specified.
			It will be ignored if crashkernel=X is specified.
	crashkernel_low=size[KMG]
	crashkernel=size[KMG],low
			[KNL, x86_64] range under 4G. When crashkernel_high= is
			[KNL, x86_64] range under 4G. When crashkernel=X,high
			passed, kernel could allocate physical memory region
			is passed, kernel could allocate physical memory region
			above 4G, that cause second kernel crash on system
			above 4G, that cause second kernel crash on system
			that require some amount of low memory, e.g. swiotlb
			that require some amount of low memory, e.g. swiotlb
			requires at least 64M+32K low memory.  Kernel would
			requires at least 64M+32K low memory.  Kernel would
@@ -620,7 +620,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
			This one let user to specify own low range under 4G
			This one let user to specify own low range under 4G
			for second kernel instead.
			for second kernel instead.
			0: to disable low allocation.
			0: to disable low allocation.
			It will be ignored when crashkernel_high=X is not used
			It will be ignored when crashkernel=X,high is not used
			or memory reserved is below 4G.
			or memory reserved is below 4G.


	cs89x0_dma=	[HW,NET]
	cs89x0_dma=	[HW,NET]
+3 −3
Original line number Original line Diff line number Diff line
@@ -528,7 +528,7 @@ static void __init reserve_crashkernel_low(void)
	int ret;
	int ret;


	total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
	total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
	/* crashkernel_low=YM */
	/* crashkernel=Y,low */
	ret = parse_crashkernel_low(boot_command_line, total_low_mem,
	ret = parse_crashkernel_low(boot_command_line, total_low_mem,
						&low_size, &base);
						&low_size, &base);
	if (ret != 0) {
	if (ret != 0) {
@@ -542,7 +542,7 @@ static void __init reserve_crashkernel_low(void)
		low_size = swiotlb_size_or_default() + (8UL<<20);
		low_size = swiotlb_size_or_default() + (8UL<<20);
		auto_set = true;
		auto_set = true;
	} else {
	} else {
		/* passed with crashkernel_low=0 ? */
		/* passed with crashkernel=0,low ? */
		if (!low_size)
		if (!low_size)
			return;
			return;
	}
	}
@@ -582,7 +582,7 @@ static void __init reserve_crashkernel(void)
	ret = parse_crashkernel(boot_command_line, total_mem,
	ret = parse_crashkernel(boot_command_line, total_mem,
			&crash_size, &crash_base);
			&crash_size, &crash_base);
	if (ret != 0 || crash_size <= 0) {
	if (ret != 0 || crash_size <= 0) {
		/* crashkernel_high=XM */
		/* crashkernel=X,high */
		ret = parse_crashkernel_high(boot_command_line, total_mem,
		ret = parse_crashkernel_high(boot_command_line, total_mem,
				&crash_size, &crash_base);
				&crash_size, &crash_base);
		if (ret != 0 || crash_size <= 0)
		if (ret != 0 || crash_size <= 0)
+96 −13
Original line number Original line Diff line number Diff line
@@ -1368,35 +1368,114 @@ static int __init parse_crashkernel_simple(char *cmdline,
	return 0;
	return 0;
}
}


#define SUFFIX_HIGH 0
#define SUFFIX_LOW  1
#define SUFFIX_NULL 2
static __initdata char *suffix_tbl[] = {
	[SUFFIX_HIGH] = ",high",
	[SUFFIX_LOW]  = ",low",
	[SUFFIX_NULL] = NULL,
};

/*
/*
 * That function is the entry point for command line parsing and should be
 * That function parses "suffix"  crashkernel command lines like
 * called from the arch-specific code.
 *
 *	crashkernel=size,[high|low]
 *
 * It returns 0 on success and -EINVAL on failure.
 */
 */
static int __init __parse_crashkernel(char *cmdline,
static int __init parse_crashkernel_suffix(char *cmdline,
			     unsigned long long system_ram,
					   unsigned long long	*crash_size,
					   unsigned long long	*crash_size,
					   unsigned long long	*crash_base,
					   unsigned long long	*crash_base,
				const char *name)
					   const char *suffix)
{
{
	char 	*p = cmdline, *ck_cmdline = NULL;
	char *cur = cmdline;
	char	*first_colon, *first_space;


	BUG_ON(!crash_size || !crash_base);
	*crash_size = memparse(cmdline, &cur);
	*crash_size = 0;
	if (cmdline == cur) {
	*crash_base = 0;
		pr_warn("crashkernel: memory value expected\n");
		return -EINVAL;
	}

	/* check with suffix */
	if (strncmp(cur, suffix, strlen(suffix))) {
		pr_warn("crashkernel: unrecognized char\n");
		return -EINVAL;
	}
	cur += strlen(suffix);
	if (*cur != ' ' && *cur != '\0') {
		pr_warn("crashkernel: unrecognized char\n");
		return -EINVAL;
	}

	return 0;
}

static __init char *get_last_crashkernel(char *cmdline,
			     const char *name,
			     const char *suffix)
{
	char *p = cmdline, *ck_cmdline = NULL;


	/* find crashkernel and use the last one if there are more */
	/* find crashkernel and use the last one if there are more */
	p = strstr(p, name);
	p = strstr(p, name);
	while (p) {
	while (p) {
		char *end_p = strchr(p, ' ');
		char *q;

		if (!end_p)
			end_p = p + strlen(p);

		if (!suffix) {
			int i;

			/* skip the one with any known suffix */
			for (i = 0; suffix_tbl[i]; i++) {
				q = end_p - strlen(suffix_tbl[i]);
				if (!strncmp(q, suffix_tbl[i],
					     strlen(suffix_tbl[i])))
					goto next;
			}
			ck_cmdline = p;
		} else {
			q = end_p - strlen(suffix);
			if (!strncmp(q, suffix, strlen(suffix)))
				ck_cmdline = p;
				ck_cmdline = p;
		}
next:
		p = strstr(p+1, name);
		p = strstr(p+1, name);
	}
	}


	if (!ck_cmdline)
		return NULL;

	return ck_cmdline;
}

static int __init __parse_crashkernel(char *cmdline,
			     unsigned long long system_ram,
			     unsigned long long *crash_size,
			     unsigned long long *crash_base,
			     const char *name,
			     const char *suffix)
{
	char	*first_colon, *first_space;
	char	*ck_cmdline;

	BUG_ON(!crash_size || !crash_base);
	*crash_size = 0;
	*crash_base = 0;

	ck_cmdline = get_last_crashkernel(cmdline, name, suffix);

	if (!ck_cmdline)
	if (!ck_cmdline)
		return -EINVAL;
		return -EINVAL;


	ck_cmdline += strlen(name);
	ck_cmdline += strlen(name);


	if (suffix)
		return parse_crashkernel_suffix(ck_cmdline, crash_size,
				crash_base, suffix);
	/*
	/*
	 * if the commandline contains a ':', then that's the extended
	 * if the commandline contains a ':', then that's the extended
	 * syntax -- if not, it must be the classic syntax
	 * syntax -- if not, it must be the classic syntax
@@ -1413,13 +1492,17 @@ static int __init __parse_crashkernel(char *cmdline,
	return 0;
	return 0;
}
}


/*
 * That function is the entry point for command line parsing and should be
 * called from the arch-specific code.
 */
int __init parse_crashkernel(char *cmdline,
int __init parse_crashkernel(char *cmdline,
			     unsigned long long system_ram,
			     unsigned long long system_ram,
			     unsigned long long *crash_size,
			     unsigned long long *crash_size,
			     unsigned long long *crash_base)
			     unsigned long long *crash_base)
{
{
	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
					"crashkernel=");
					"crashkernel=", NULL);
}
}


int __init parse_crashkernel_high(char *cmdline,
int __init parse_crashkernel_high(char *cmdline,
@@ -1428,7 +1511,7 @@ int __init parse_crashkernel_high(char *cmdline,
			     unsigned long long *crash_base)
			     unsigned long long *crash_base)
{
{
	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
					"crashkernel_high=");
				"crashkernel=", suffix_tbl[SUFFIX_HIGH]);
}
}


int __init parse_crashkernel_low(char *cmdline,
int __init parse_crashkernel_low(char *cmdline,
@@ -1437,7 +1520,7 @@ int __init parse_crashkernel_low(char *cmdline,
			     unsigned long long *crash_base)
			     unsigned long long *crash_base)
{
{
	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
					"crashkernel_low=");
				"crashkernel=", suffix_tbl[SUFFIX_LOW]);
}
}


static void update_vmcoreinfo_note(void)
static void update_vmcoreinfo_note(void)