Skip to contentSkip to conversation

Proposal for run time memory allocation for crash kernel

PATCH Ronit halder 1 participant 1 message Jun 20, 2016

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

Hi,
Currenty linux kernel allocates memory at the boot time for crash kernel booted using kexec system call in kernel crash. It will be very useful if we can allocate memory in run time.
It is possible to allocate memory for crash kernel at the boot time using CMA (Contiguous Memory Allocator). CMA is capable of allocating big chunk of memory. At the boot time we will create one (if only low memory is used) or two (if we use both high and low memory) CMA areas of size given in "crashkernel" boot time command line parameter. Then the user can allocate or free memory from those CMA areas using "/sys/kernel/kexec_crash_size" sysfs entry.

I am attaching a prototype patch with the mail. I have made the patch against kernel version v4.4.11.
Please give your opinions.

arch/x86/kernel/setup.c +14 -17
index d2bbe34..42c7226 100644
@@ -69,6 +69,7 @@
 #include <linux/crash_dump.h>
 #include <linux/tboot.h>
 #include <linux/jiffies.h>
+#include <linux/cma.h>
 
 #include <video/edid.h>
 
@@ -122,7 +123,8 @@
  */
 unsigned long max_low_pfn_mapped;
 unsigned long max_pfn_mapped;
-
+struct cma *crashk_cma = NULL;
+struct cma *crashk_cma_low = NULL;
 #ifdef CONFIG_DMI
 RESERVE_BRK(dmi_alloc, 65536);
 #endif
@@ -532,9 +534,9 @@ static int __init reserve_crashkernel_low(void)
 		return -ENOMEM;
 	}
 
-	ret = memblock_reserve(low_base, low_size);
+	ret =  cma_declare_contiguous(low_base, low_size, 0, CRASH_ALIGN, 0, 1, &crashk_cma_low);
 	if (ret) {
-		pr_err("%s: Error reserving crashkernel low memblock.\n", __func__);
+		pr_err("%s: Error reserving CMA area for crashkernel low.\n", __func__);
 		return ret;
 	}
 
@@ -543,9 +545,7 @@ static int __init reserve_crashkernel_low(void)
 		(unsigned long)(low_base >> 20),
 		(unsigned long)(total_low_mem >> 20));
 
-	crashk_low_res.start = low_base;
-	crashk_low_res.end   = low_base + low_size - 1;
-	insert_resource(&iomem_resource, &crashk_low_res);
+
 #endif
 	return 0;
 }
@@ -578,6 +578,8 @@ static void __init reserve_crashkernel(void)
 						    high ? CRASH_ADDR_HIGH_MAX
 							 : CRASH_ADDR_LOW_MAX,
 						    crash_size, CRASH_ALIGN);
+		pr_info("ronit 0 crash_base %llu crash_size %llu \n", crash_base, crash_size);
+
 		if (!crash_base) {
 			pr_info("crashkernel reservation failed - No suitable area found.\n");
 			return;
@@ -589,30 +591,25 @@ static void __init reserve_crashkernel(void)
 		start = memblock_find_in_range(crash_base,
 					       crash_base + crash_size,
 					       crash_size, 1 << 20);
+		pr_info("ronit base_mentioned crash_base %llu crash_size %llu \n", crash_base, crash_size);
 		if (start != crash_base) {
 			pr_info("crashkernel reservation failed - memory is in use.\n");
 			return;
 		}
 	}
-	ret = memblock_reserve(crash_base, crash_size);
-	if (ret) {
-		pr_err("%s: Error reserving crashkernel memblock.\n", __func__);
+	if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
 		return;
 	}
-
-	if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
-		memblock_free(crash_base, crash_size);
+	ret =  cma_declare_contiguous(crash_base, crash_size, 0, CRASH_ALIGN, 0, 1, &crashk_cma);
+	if (ret) {
+		pr_err("%s: Error reserving CMA area for crashkernel.\n", __func__);
 		return;
 	}
 
-	pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
+	pr_info("ronit halder Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
 		(unsigned long)(crash_size >> 20),
 		(unsigned long)(crash_base >> 20),
 		(unsigned long)(total_mem >> 20));
-
-	crashk_res.start = crash_base;
-	crashk_res.end   = crash_base + crash_size - 1;
-	insert_resource(&iomem_resource, &crashk_res);
 }
 #else
 static void __init reserve_crashkernel(void)
include/linux/kexec.h +8 -1
index d140b1e..d6a24d6 100644
@@ -307,7 +307,7 @@ extern size_t vmcoreinfo_max_size;
 
 /* flag to track if kexec reboot is in progress */
 extern bool kexec_in_progress;
-
+extern struct cma *crashk_cma, *crashk_cma_low;
 int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
 		unsigned long long *crash_size, unsigned long long *crash_base);
 int parse_crashkernel_high(char *cmdline, unsigned long long system_ram,
@@ -318,6 +318,13 @@ int crash_shrink_memory(unsigned long new_size);
 size_t crash_get_memory_size(void);
 void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
 
+//custom functions
+int crash_free_memory(unsigned int size);
+int crash_alloc_memory(unsigned int size);
+int crash_alloc_memory_low(void);
+int crash_free_memory_low(void);
+size_t crash_get_memory_size_low(void);
+
 int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
 					 unsigned long buf_len);
 void * __weak arch_kexec_kernel_image_load(struct kimage *image);
kernel/kexec_core.c +80 -0

111 lines not on this page · raw message

kernel/ksysfs.c +13 -2
index e83b264..fbc5314 100644
@@ -116,12 +116,23 @@ static ssize_t kexec_crash_size_store(struct kobject *kobj,
 {
 	unsigned long cnt;
 	int ret;
+	int size;
 
 	if (kstrtoul(buf, 0, &cnt))
 		return -EINVAL;
 
-	ret = crash_shrink_memory(cnt);
-	return ret < 0 ? ret : count;
+	size = cnt<<20;
+	if (cnt == 0) {
+		crash_free_memory_low();
+		ret = crash_free_memory(crash_get_memory_size());
+	}
+	else if (cnt > 0) {
+		if (crash_get_memory_size_low() == 0)
+			crash_alloc_memory_low();
+		ret = crash_free_memory(crash_get_memory_size());
+		ret = crash_alloc_memory(size);
+	}
+	return count;
 }
 KERNEL_ATTR_RW(kexec_crash_size);
 

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec