Horms wrote:
I will rediff them with all these patches applied and then send you the
patches.

Ok, that sounds perfect.

I have pushed my changes into kexec-tools-testing now,
that is all of them except the last one.
kexec tools for ppc64 uses static arrays [of length MAX_MEMORY_RANGES]
to store data related to memory regions. This used to eat up lot's of memory. There were some instances where more memory regions existed, which made kexec tools unusable on those machines. The following patch
gets rid of MAX_MEMORY_RANGES macro and uses dynamic memory allocation
for the above mentioned structures.

Please review.

Thanks
-Sachin

Signed-off-by : Sachin Sant <[EMAIL PROTECTED]>
---





* kexec tools for ppc64 uses static arrays [of length MAX_MEMORY_RANGES] to
* store data related to memory regions. This used to eat up lot's of memory.
* There were some instances where more memory regions existed, which made
* kexec tools unusable on those machines. The following patch gets rid of
* MAX_MEMORY_RANGES macro and uses dynamic memory allocation for the
* above mentioned structures.

Signed-off-by : Sachin Sant <[EMAIL PROTECTED]>
---

diff -Naurp hormsgittree/kexec/arch/ppc64/crashdump-ppc64.c hormsgittree-dyn-mem-alloc/kexec/arch/ppc64/crashdump-ppc64.c
--- hormsgittree/kexec/arch/ppc64/crashdump-ppc64.c	2006-12-05 17:08:18.000000000 +0530
+++ hormsgittree-dyn-mem-alloc/kexec/arch/ppc64/crashdump-ppc64.c	2006-12-13 11:35:23.000000000 +0530
@@ -62,7 +62,10 @@ extern struct arch_options_t arch_option
 /* Stores a sorted list of RAM memory ranges for which to create elf headers.
  * A separate program header is created for backup region
  */
-static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES];
+static struct memory_range *crash_memory_range;
+
+/* Define a variable to replace the CRASH_MAX_MEMORY_RANGES macro */
+static int crash_max_memory_ranges;
 
 /*
  * Used to save various memory ranges/regions needed for the captured
@@ -105,6 +108,15 @@ static int get_crash_memory_ranges(struc
 	int i, n;
 	unsigned long long start, end, cstart, cend;
 
+	crash_max_memory_ranges = max_memory_ranges + 6;
+
+	crash_memory_range = (struct memory_range *) malloc(
+		(sizeof(struct memory_range) * (crash_max_memory_ranges)));
+	if (crash_memory_range == NULL) {
+		fprintf(stderr, "Memory allocation for crash memory range failed\n");
+		return -1;
+	}
+
 	/* create a separate program header for the backup region */
 	crash_memory_range[0].start = BACKUP_SRC_START;
 	crash_memory_range[0].end = BACKUP_SRC_END;
@@ -113,7 +125,7 @@ static int get_crash_memory_ranges(struc
 
 	if ((dir = opendir(device_tree)) == NULL) {
 		perror(device_tree);
-		return -1;
+		goto err;
 	}
 	while ((dentry = readdir(dir)) != NULL) {
 		if (strncmp(dentry->d_name, "memory@", 7))
@@ -123,7 +135,7 @@ static int get_crash_memory_ranges(struc
 		if ((dmem = opendir(fname)) == NULL) {
 			perror(fname);
 			closedir(dir);
-			return -1;
+			goto err;
 		}
 		while ((mentry = readdir(dmem)) != NULL) {
 			if (strcmp(mentry->d_name, "reg"))
@@ -133,21 +145,21 @@ static int get_crash_memory_ranges(struc
 				perror(fname);
 				closedir(dmem);
 				closedir(dir);
-				return -1;
+				goto err;
 			}
 			if ((n = fread(buf, 1, MAXBYTES, file)) < 0) {
 				perror(fname);
 				fclose(file);
 				closedir(dmem);
 				closedir(dir);
-				return -1;
+				goto err;
 			}
-			if (memory_ranges >= MAX_MEMORY_RANGES) {
+			if (memory_ranges >= max_memory_ranges) {
 				/* No space to insert another element. */
 				fprintf(stderr,
 					"Error: Number of crash memory ranges"
 					" excedeed the max limit\n");
-				return -1;
+				goto err;
 			}
 
 			start = ((unsigned long long *)buf)[0];
@@ -228,6 +240,11 @@ static int get_crash_memory_ranges(struc
 	}
 #endif
 	return 0;
+
+err:
+	if (crash_memory_range)
+		free(crash_memory_range);
+	return -1;
 }
 
 /* Converts unsigned long to ascii string. */
diff -Naurp hormsgittree/kexec/arch/ppc64/crashdump-ppc64.h hormsgittree-dyn-mem-alloc/kexec/arch/ppc64/crashdump-ppc64.h
--- hormsgittree/kexec/arch/ppc64/crashdump-ppc64.h	2006-12-05 17:08:18.000000000 +0530
+++ hormsgittree-dyn-mem-alloc/kexec/arch/ppc64/crashdump-ppc64.h	2006-12-13 11:26:40.000000000 +0530
@@ -13,8 +13,6 @@ void add_usable_mem_rgns(unsigned long l
 #define __pa(x)         ((unsigned long)(x)-PAGE_OFFSET)
 #define MAXMEM          (-KERNELBASE-VMALLOCBASE)
 
-#define CRASH_MAX_MEMORY_RANGES (MAX_MEMORY_RANGES + 6)
-
 #define COMMAND_LINE_SIZE       512 /* from kernel */
 /* Backup Region, First 64K of System RAM. */
 #define BACKUP_SRC_START    0x0000
diff -Naurp hormsgittree/kexec/arch/ppc64/fs2dt.c hormsgittree-dyn-mem-alloc/kexec/arch/ppc64/fs2dt.c
--- hormsgittree/kexec/arch/ppc64/fs2dt.c	2006-12-13 11:23:25.000000000 +0530
+++ hormsgittree-dyn-mem-alloc/kexec/arch/ppc64/fs2dt.c	2006-12-13 17:29:26.000000000 +0530
@@ -36,6 +36,7 @@
 #define NAMESPACE 16384		/* max bytes for property names */
 #define TREEWORDS 65536		/* max 32 bit words for property values */
 #define MEMRESERVE 256		/* max number of reserved memory blocks */
+#define MAX_MEMORY_RANGES 1024
 
 static char pathname[MAXPATH], *pathstart;
 static char propnames[NAMESPACE] = { 0 };
diff -Naurp hormsgittree/kexec/arch/ppc64/kexec-ppc64.c hormsgittree-dyn-mem-alloc/kexec/arch/ppc64/kexec-ppc64.c
--- hormsgittree/kexec/arch/ppc64/kexec-ppc64.c	2006-12-13 11:25:48.000000000 +0530
+++ hormsgittree-dyn-mem-alloc/kexec/arch/ppc64/kexec-ppc64.c	2006-12-13 11:29:24.000000000 +0530
@@ -20,6 +20,7 @@
 
 #include <stddef.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <errno.h>
 #include <stdint.h>
 #include <string.h>
@@ -34,17 +35,83 @@
 #include "crashdump-ppc64.h"
 #include <arch/options.h>
 
-static struct exclude_range exclude_range[MAX_MEMORY_RANGES];
+static struct exclude_range *exclude_range;
+static struct memory_range *memory_range;
+static struct memory_range *base_memory_range;
 static unsigned long long rmo_top;
-static struct memory_range memory_range[MAX_MEMORY_RANGES];
-static struct memory_range base_memory_range[MAX_MEMORY_RANGES];
 unsigned long long memory_max = 0;
 static int nr_memory_ranges, nr_exclude_ranges;
 unsigned long long crash_base, crash_size;
 unsigned int rtas_base, rtas_size;
+int max_memory_ranges;
 
 static int sort_base_ranges();
 
+
+static void cleanup_memory_ranges()
+{
+	if (memory_range)
+		free(memory_range);
+	if (base_memory_range)
+		free(base_memory_range);
+	if (exclude_range)
+		free(exclude_range);
+	if (usablemem_rgns.ranges)
+		free(usablemem_rgns.ranges);
+}
+
+/*
+ * Allocate memory for various data structures used to hold
+ * values of different memory ranges
+ */
+static int alloc_memory_ranges()
+{
+	memory_range = (struct memory_range *) malloc(
+		(sizeof(struct memory_range) * max_memory_ranges));
+	base_memory_range = (struct memory_range *) malloc(
+		(sizeof(struct memory_range) * max_memory_ranges));
+	exclude_range = (struct exclude_range *) malloc(
+		(sizeof(struct exclude_range) * max_memory_ranges));
+	usablemem_rgns.ranges = (struct exclude_range *) malloc(
+		(sizeof(struct exclude_range) * max_memory_ranges));
+	if ((memory_range == NULL) ||
+	    (base_memory_range == NULL) ||
+	    (exclude_range == NULL) ||
+	    (usablemem_rgns.ranges == NULL)) {
+		fprintf(stderr, "Memory allocation for memory range structure failed\n");
+		cleanup_memory_ranges();
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Count the memory@ nodes under /proc/device-tree and populate the
+ * max_memory_ranges variable. This variable replaces MAX_MEMORY_RANGES
+ * macro used earlier.
+ */
+static int count_memory_ranges()
+{
+	char device_tree[256] = "/proc/device-tree/";
+	struct dirent *dentry;
+	DIR *dir;
+
+	if ((dir = opendir(device_tree)) == NULL) {
+		perror(device_tree);
+		return -1;
+	}
+
+	while ((dentry = readdir(dir)) != NULL) {
+		if (strncmp(dentry->d_name, "memory@", 7))
+			continue;
+		max_memory_ranges++;
+	}
+	closedir(dir);
+
+	return 0;
+}
+
 /* Get base memory ranges */
 static int get_base_ranges()
 {
@@ -88,7 +155,7 @@ static int get_base_ranges()
 				closedir(dir);
 				return -1;
 			}
-			if (local_memory_ranges >= MAX_MEMORY_RANGES) {
+			if (local_memory_ranges >= max_memory_ranges) {
 				fclose(file);
 				break;
 			}
@@ -447,8 +514,10 @@ int setup_memory_ranges(unsigned long ke
 	 * nodes. Build list of ranges to be excluded from valid memory
 	 */
 
-	get_base_ranges();
-	get_devtree_details(kexec_flags);
+	if (get_base_ranges())
+		goto out;
+	if (get_devtree_details(kexec_flags))
+		goto out;
 
 	for (i = 0; i < nr_exclude_ranges; i++) {
 		/* If first exclude range does not start with 0, include the
@@ -511,12 +580,21 @@ int setup_memory_ranges(unsigned long ke
 		fprintf(stderr, "setup_memory_ranges memory_range[%d] start:%lx, end:%lx\n", k, memory_range[k].start, memory_range[k].end);
 #endif
 	return 0;
+
+out:
+	cleanup_memory_ranges();
+	return -1;
 }
 
 /* Return a list of valid memory ranges */
 int get_memory_ranges(struct memory_range **range, int *ranges,
 			unsigned long kexec_flags)
 {
+	if (count_memory_ranges())
+		return -1;
+	if (alloc_memory_ranges())
+		return -1;
+
 	setup_memory_ranges(kexec_flags);
 	*range = memory_range;
 	*ranges = nr_memory_ranges;
diff -Naurp hormsgittree/kexec/arch/ppc64/kexec-ppc64.h hormsgittree-dyn-mem-alloc/kexec/arch/ppc64/kexec-ppc64.h
--- hormsgittree/kexec/arch/ppc64/kexec-ppc64.h	2006-12-13 11:25:48.000000000 +0530
+++ hormsgittree-dyn-mem-alloc/kexec/arch/ppc64/kexec-ppc64.h	2006-12-13 11:43:00.000000000 +0530
@@ -1,8 +1,6 @@
 #ifndef KEXEC_PPC64_H
 #define KEXEC_PPC64_H
 
-#define MAX_MEMORY_RANGES 1024 /* TO FIX - needs to be dynamically set */
-
 #define MAXBYTES 128
 #define MAX_LINE 160
 #define CORE_TYPE_ELF32 1
@@ -17,6 +15,8 @@ void elf_ppc64_usage(void);
 void reserve(unsigned long long where, unsigned long long length);
 
 extern unsigned long initrd_base, initrd_size;
+extern int max_memory_ranges;
+
 /* boot block version 2 as defined by the linux kernel */
 struct bootblock {
 	unsigned magic,
@@ -39,7 +39,9 @@ struct exclude_range {
 
 typedef struct mem_rgns {
         unsigned int size;
-        struct exclude_range ranges[MAX_MEMORY_RANGES];
+        struct exclude_range *ranges;
 } mem_rgns_t;
 
+extern mem_rgns_t usablemem_rgns;
+
 #endif /* KEXEC_PPC64_H */
_______________________________________________
fastboot mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/fastboot

Reply via email to