Skip to contentSkip to conversation

kdump: extend crashkernel=range:size to dynamically increase reservation size

PATCH In review [email protected] 2 participants 3 messages Oct 24, 2017

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/3 kdump: extend crashkernel=range:size to dynamically increase reservation size

crashkernel=range:size syntax allows to reserve specified size for system with total memory fall into the specified range. For example:
crashkernel=2G-3G:128M,3G-:256M reserves 128M for system with memory >=2G and memory <3G, and reserves 256M for system with memory >= 3G

In the above case 256M as a fixed value which can not fulfill very huge systems with large memory and IO devices. As memory size increases usually minimum memory requirement for booting will also increase. It is nearly impossible for a kernel to run with a fixed limited memory size for all kinds of systems.

Thus extend the crashkernel=range:size to let user specify the scaling ratio in kernel cmdline like below:
crashkernel=range:size^order, for example:
crashkernel=2G-:128M^14 reserve 128M + (total_memory - 128M) >> 14 for machines with over 2G memory.

Also s/start-[end]/[start]-end/ in kernel-parameters.txt according to code

---
 Documentation/admin-guide/kernel-parameters.txt |   10 ++++--
 Documentation/kdump/kdump.txt                   |    7 ++--
 kernel/crash_core.c                             |   35 +++++++++++++++++++++---
 3 files changed, 41 insertions(+), 11 deletions(-)
kernel/crash_core.c +31 -4
@@ -31,7 +31,7 @@ static unsigned char *vmcoreinfo_data_sa
 /*
  * This function parses command lines in the format
  *
- *   crashkernel=ramsize-range:size[,...][@offset]
+ *   crashkernel=ramsize-range:size[,...][@offset][^order]
  *
  * The function returns 0 on success and -EINVAL on failure.
  */
@@ -41,6 +41,7 @@ static int __init parse_crashkernel_mem(
 					unsigned long long *crash_base)
 {
 	char *cur = cmdline, *tmp;
+	bool infinite_end = false;
 
 	/* for each entry of the comma-separated list */
 	do {
@@ -93,13 +94,21 @@ static int __init parse_crashkernel_mem(
 		/* match ? */
 		if (system_ram >= start && system_ram < end) {
 			*crash_size = size;
+			if (end == ULLONG_MAX)
+				infinite_end = true;
 			break;
 		}
 	} while (*cur++ == ',');
 
-	if (*crash_size > 0) {
-		while (*cur && *cur != ' ' && *cur != '@')
+	if (*crash_size <= 0)
+		goto out;
+
+	while (*cur && *cur != ' ') {
+		if (*cur != '@' && *cur != '^') {
 			cur++;
+			continue;
+		}
+
 		if (*cur == '@') {
 			cur++;
 			*crash_base = memparse(cur, &tmp);
@@ -107,10 +116,28 @@ static int __init parse_crashkernel_mem(
 				pr_warn("Memory value expected after '@'\n");
 				return -EINVAL;
 			}
-		}
+			cur = tmp;
+		} else if (*cur == '^' && infinite_end ) {
+			unsigned long long shift, size;
+
+			cur++;
+			shift = memparse(cur, &tmp);
+			if (cur == tmp) {
+				pr_warn("Memory reservation scale order expected after '^'\n");
+				return -EINVAL;
+			}
+			size = (system_ram - *crash_size) >> shift;
+			size = *crash_size + roundup(size, 1ULL << 20);
+			if (size < system_ram)
+				*crash_size = size;
+			cur = tmp;
+		} else
+			cur++;
 	}
 
 	return 0;
+out:
+	return -EINVAL;
 }
 
 /*
Documentation/admin-guide/kernel-parameters.txt +6 -4
@@ -680,12 +680,14 @@
 			is selected automatically. Check
 			Documentation/kdump/kdump.txt for further details.
 
-	crashkernel=range1:size1[,range2:size2,...][@offset]
+	crashkernel=range1:size1[,range2:size2,...][@offset][^order]
 			[KNL] Same as above, but depends on the memory
 			in the running system. The syntax of range is
-			start-[end] where start and end are both
-			a memory unit (amount[KMG]). See also
-			Documentation/kdump/kdump.txt for an example.
+			[start]-end where start and end are both
+			a memory unit (amount[KMG]). In case the end of the
+			range is infinity '^order' can be used to scale
+			the size to size + (total_mem - start) >> 2^order
+			See also Documentation/kdump/kdump.txt for an example.
 
 	crashkernel=size[KMG],high
 			[KNL, x86_64] range could be above 4G. Allow kernel
Documentation/kdump/kdump.txt +4 -3
@@ -267,19 +267,20 @@ been removed from the machine.
 
 The syntax is:
 
-    crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
+    crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset][^order]
     range=start-[end]
 
 For example:
 
-    crashkernel=512M-2G:64M,2G-:128M
+    crashkernel=512M-2G:64M,2G-:128M^14
 
 This would mean:
 
     1) if the RAM is smaller than 512M, then don't reserve anything
        (this is the "rescue" case)
     2) if the RAM size is between 512M and 2G (exclusive), then reserve 64M
-    3) if the RAM size is larger than 2G, then reserve 128M
+    3) if the RAM size is larger than 2G, then reserve:
+       128M + (total_mem - 128M) >> 14
 
 
 
#1 lore raw
Quoted 11 lines · Dave Young

crashkernel=range:size syntax allows to reserve specified size for system with total memory fall into the specified range. For example:
crashkernel=2G-3G:128M,3G-:256M reserves 128M for system with memory >=2G and memory <3G, and reserves 256M for system with memory >= 3G

In the above case 256M as a fixed value which can not fulfill very huge systems with large memory and IO devices. As memory size increases usually minimum memory requirement for booting will also increase. It is nearly impossible for a kernel to run with a fixed limited memory size for all kinds of systems.

Quoted 5 lines

Thus extend the crashkernel=range:size to let user specify the scaling ratio in kernel cmdline like below:
crashkernel=range:size^order, for example:
crashkernel=2G-:128M^14 reserve 128M + (total_memory - 128M) >> 14 for machines with over 2G memory.

Well, ah.., this look a little ugly and tricky. Leave this to other reviewers to comment.

Quoted 132 lines

Also s/start-[end]/[start]-end/ in kernel-parameters.txt according to code

---
 Documentation/admin-guide/kernel-parameters.txt |   10 ++++--
 Documentation/kdump/kdump.txt                   |    7 ++--
 kernel/crash_core.c                             |   35 +++++++++++++++++++++---
 3 files changed, 41 insertions(+), 11 deletions(-)
kernel/crash_core.c +31 -4
@@ -31,7 +31,7 @@ static unsigned char *vmcoreinfo_data_sa
 /*
  * This function parses command lines in the format
  *
- *   crashkernel=ramsize-range:size[,...][@offset]
+ *   crashkernel=ramsize-range:size[,...][@offset][^order]
  *
  * The function returns 0 on success and -EINVAL on failure.
  */
@@ -41,6 +41,7 @@ static int __init parse_crashkernel_mem(
 					unsigned long long *crash_base)
 {
 	char *cur = cmdline, *tmp;
+	bool infinite_end = false;
 
 	/* for each entry of the comma-separated list */
 	do {
@@ -93,13 +94,21 @@ static int __init parse_crashkernel_mem(
 		/* match ? */
 		if (system_ram >= start && system_ram < end) {
 			*crash_size = size;
+			if (end == ULLONG_MAX)
+				infinite_end = true;
 			break;
 		}
 	} while (*cur++ == ',');
 
-	if (*crash_size > 0) {
-		while (*cur && *cur != ' ' && *cur != '@')
+	if (*crash_size <= 0)
+		goto out;
+
+	while (*cur && *cur != ' ') {
+		if (*cur != '@' && *cur != '^') {
 			cur++;
+			continue;
+		}
+
 		if (*cur == '@') {
 			cur++;
 			*crash_base = memparse(cur, &tmp);
@@ -107,10 +116,28 @@ static int __init parse_crashkernel_mem(
 				pr_warn("Memory value expected after '@'\n");
 				return -EINVAL;
 			}
-		}
+			cur = tmp;
+		} else if (*cur == '^' && infinite_end ) {
+			unsigned long long shift, size;
+
+			cur++;
+			shift = memparse(cur, &tmp);
+			if (cur == tmp) {
+				pr_warn("Memory reservation scale order expected after '^'\n");
+				return -EINVAL;
+			}
+			size = (system_ram - *crash_size) >> shift;
+			size = *crash_size + roundup(size, 1ULL << 20);
+			if (size < system_ram)
+				*crash_size = size;
+			cur = tmp;
+		} else
+			cur++;
 	}
 
 	return 0;
+out:
+	return -EINVAL;
 }
 
 /*
Documentation/admin-guide/kernel-parameters.txt +6 -4
@@ -680,12 +680,14 @@
 			is selected automatically. Check
 			Documentation/kdump/kdump.txt for further details.
 
-	crashkernel=range1:size1[,range2:size2,...][@offset]
+	crashkernel=range1:size1[,range2:size2,...][@offset][^order]
 			[KNL] Same as above, but depends on the memory
 			in the running system. The syntax of range is
-			start-[end] where start and end are both
-			a memory unit (amount[KMG]). See also
-			Documentation/kdump/kdump.txt for an example.
+			[start]-end where start and end are both
+			a memory unit (amount[KMG]). In case the end of the
+			range is infinity '^order' can be used to scale
+			the size to size + (total_mem - start) >> 2^order
+			See also Documentation/kdump/kdump.txt for an example.
 
 	crashkernel=size[KMG],high
 			[KNL, x86_64] range could be above 4G. Allow kernel
Documentation/kdump/kdump.txt +4 -3
@@ -267,19 +267,20 @@ been removed from the machine.
 
 The syntax is:
 
-    crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
+    crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset][^order]
     range=start-[end]
 
 For example:
 
-    crashkernel=512M-2G:64M,2G-:128M
+    crashkernel=512M-2G:64M,2G-:128M^14
 
 This would mean:
 
     1) if the RAM is smaller than 512M, then don't reserve anything
        (this is the "rescue" case)
     2) if the RAM size is between 512M and 2G (exclusive), then reserve 64M
-    3) if the RAM size is larger than 2G, then reserve 128M
+    3) if the RAM size is larger than 2G, then reserve:
+       128M + (total_mem - 128M) >> 14
 
 
 
author
#2 lore raw

Hi Baoquan,

Quoted 12 lines · Baoquan He
Quoted 11 lines · Dave Young

crashkernel=range:size syntax allows to reserve specified size for system with total memory fall into the specified range. For example:
crashkernel=2G-3G:128M,3G-:256M reserves 128M for system with memory >=2G and memory <3G, and reserves 256M for system with memory >= 3G

In the above case 256M as a fixed value which can not fulfill very huge systems with large memory and IO devices. As memory size increases usually minimum memory requirement for booting will also increase. It is nearly impossible for a kernel to run with a fixed limited memory size for all kinds of systems.

Quoted 8 lines
Quoted 5 lines

Thus extend the crashkernel=range:size to let user specify the scaling ratio in kernel cmdline like below:
crashkernel=range:size^order, for example:
crashkernel=2G-:128M^14 reserve 128M + (total_memory - 128M) >> 14 for machines with over 2G memory.

Well, ah.., this look a little ugly and tricky. Leave this to other reviewers to comment.

But this is better than embed policy in kernel.. RHEL takes a crashkernel=auto which do the scaling. Leaving user to determine the scaling ratio is the better way.

OTOH, this is an improvement to current crashkernel=range:size which can not scale the size before.

Quoted 122 lines
Quoted 122 lines

Also s/start-[end]/[start]-end/ in kernel-parameters.txt according to code

---
 Documentation/admin-guide/kernel-parameters.txt |   10 ++++--
 Documentation/kdump/kdump.txt                   |    7 ++--
 kernel/crash_core.c                             |   35 +++++++++++++++++++++---
 3 files changed, 41 insertions(+), 11 deletions(-)
kernel/crash_core.c +31 -4
@@ -31,7 +31,7 @@ static unsigned char *vmcoreinfo_data_sa
 /*
  * This function parses command lines in the format
  *
- *   crashkernel=ramsize-range:size[,...][@offset]
+ *   crashkernel=ramsize-range:size[,...][@offset][^order]
  *
  * The function returns 0 on success and -EINVAL on failure.
  */
@@ -41,6 +41,7 @@ static int __init parse_crashkernel_mem(
 					unsigned long long *crash_base)
 {
 	char *cur = cmdline, *tmp;
+	bool infinite_end = false;
 
 	/* for each entry of the comma-separated list */
 	do {
@@ -93,13 +94,21 @@ static int __init parse_crashkernel_mem(
 		/* match ? */
 		if (system_ram >= start && system_ram < end) {
 			*crash_size = size;
+			if (end == ULLONG_MAX)
+				infinite_end = true;
 			break;
 		}
 	} while (*cur++ == ',');
 
-	if (*crash_size > 0) {
-		while (*cur && *cur != ' ' && *cur != '@')
+	if (*crash_size <= 0)
+		goto out;
+
+	while (*cur && *cur != ' ') {
+		if (*cur != '@' && *cur != '^') {
 			cur++;
+			continue;
+		}
+
 		if (*cur == '@') {
 			cur++;
 			*crash_base = memparse(cur, &tmp);
@@ -107,10 +116,28 @@ static int __init parse_crashkernel_mem(
 				pr_warn("Memory value expected after '@'\n");
 				return -EINVAL;
 			}
-		}
+			cur = tmp;
+		} else if (*cur == '^' && infinite_end ) {
+			unsigned long long shift, size;
+
+			cur++;
+			shift = memparse(cur, &tmp);
+			if (cur == tmp) {
+				pr_warn("Memory reservation scale order expected after '^'\n");
+				return -EINVAL;
+			}
+			size = (system_ram - *crash_size) >> shift;
+			size = *crash_size + roundup(size, 1ULL << 20);
+			if (size < system_ram)
+				*crash_size = size;
+			cur = tmp;
+		} else
+			cur++;
 	}
 
 	return 0;
+out:
+	return -EINVAL;
 }
 
 /*
Documentation/admin-guide/kernel-parameters.txt +6 -4
@@ -680,12 +680,14 @@
 			is selected automatically. Check
 			Documentation/kdump/kdump.txt for further details.
 
-	crashkernel=range1:size1[,range2:size2,...][@offset]
+	crashkernel=range1:size1[,range2:size2,...][@offset][^order]
 			[KNL] Same as above, but depends on the memory
 			in the running system. The syntax of range is
-			start-[end] where start and end are both
-			a memory unit (amount[KMG]). See also
-			Documentation/kdump/kdump.txt for an example.
+			[start]-end where start and end are both
+			a memory unit (amount[KMG]). In case the end of the
+			range is infinity '^order' can be used to scale
+			the size to size + (total_mem - start) >> 2^order
+			See also Documentation/kdump/kdump.txt for an example.
 
 	crashkernel=size[KMG],high
 			[KNL, x86_64] range could be above 4G. Allow kernel
Documentation/kdump/kdump.txt +2 -2
@@ -267,19 +267,20 @@ been removed from the machine.
 
 The syntax is:
 
-    crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
+    crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset][^order]
     range=start-[end]
 
 For example:
 
-    crashkernel=512M-2G:64M,2G-:128M
+    crashkernel=512M-2G:64M,2G-:128M^14
 
 This would mean:
 
Quoted 11 lines

Documentation/kdump/kdump.txt been removed from the machine. · line 286

Quoted 11 lines
Documentation/kdump/kdump.txt +2 -1
     1) if the RAM is smaller than 512M, then don't reserve anything
        (this is the "rescue" case)
     2) if the RAM size is between 512M and 2G (exclusive), then reserve 64M
-    3) if the RAM size is larger than 2G, then reserve 128M
+    3) if the RAM size is larger than 2G, then reserve:
+       128M + (total_mem - 128M) >> 14
 
 
 

Thanks
Dave