Horms wrote:
Hi Sachin,

I took a quick look over this. And it seems to be fine.
I've put some minor comments inline.
  */
-static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES];
+static struct memory_range *crash_memory_range;

I think that crash_memory_range needs to be initialised to NULL here.
Otherwise the err check in get_crash_memory_ranges() may be bogus.
Hmm .. since all these variables are static globals they will be initialized to NULL. But i think for clarity sake we should
explicitly initialize them to NULL. Have changed it.

+               fprintf(stderr, "Memory allocation for crash memory range 
failed\n");
Can you make this <= 80col wide? I think it is just a little over.
Done.

I think that memory_range, base_memory_range and exclude_range all
need to be initialised to NULL here. Otherwise the checks
in cleanup_memory_ranges() may be bogus.
Hmm ok done.

+
+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);
+}

Should this function set any freed pointers to NULL ?
I guess it should not be necessary to set them to NULL. This is an exit
path and the program will end.

+
+/*
+ * 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)) {

I personally prefer the following
        if (!memory_range || !base_memory_range || !exclude_range ||
            !usablemem_rgns.ranges)

Actually, I really prefer doing the error check after each malloc(),
but thats just me.
Done.

+               fprintf(stderr, "Memory allocation for memory range structure 
failed\n");

Can you make this <= 80col wide? I think it is just a little over.
Done

+extern mem_rgns_t usablemem_rgns;
usablemem_rgns.ranges needs to be initialised to NULL somehow.
Perhaps you could just change the declaration (wherever that is)
to mem_rgns_t usablemem_rgns = { 0, NULL }; I think that would work.
Done.

Here is the modified patch. Thanks for the review.

I have tested this on few PPC64 boxes and haven't found any problem
with it.

* 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]>
---


* 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-14 14:39:51.000000000 +0530
@@ -62,13 +62,16 @@ 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 = NULL;
+
+/* 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
  * kernel to boot. (lime memmap= option in other archs)
  */
-mem_rgns_t usablemem_rgns = {0, };
+mem_rgns_t usablemem_rgns = {0, NULL};
 
 /*
  * To store the memory size of the first kernel and this value will be
@@ -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) {
+		fprintf(stderr, "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-14 14:48:45.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,92 @@
 #include "crashdump-ppc64.h"
 #include <arch/options.h>
 
-static struct exclude_range exclude_range[MAX_MEMORY_RANGES];
+static struct exclude_range *exclude_range = NULL;
+static struct memory_range *memory_range = NULL;
+static struct memory_range *base_memory_range = NULL;
 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));
+	if (!memory_range)
+		goto err1;
+
+	base_memory_range = (struct memory_range *) malloc(
+		(sizeof(struct memory_range) * max_memory_ranges));
+	if (!base_memory_range)
+		goto err1;
+
+	exclude_range = (struct exclude_range *) malloc(
+		(sizeof(struct exclude_range) * max_memory_ranges));
+	if (!exclude_range)
+		goto err1;
+
+	usablemem_rgns.ranges = (struct exclude_range *) malloc(
+		(sizeof(struct exclude_range) * max_memory_ranges));
+	if (!(usablemem_rgns.ranges)) 
+		goto err1;
+
+	return 0;
+
+err1:
+	fprintf(stderr, "memory range structure allocation failure\n");
+	cleanup_memory_ranges();
+	return -1;
+	
+}
+
+/*
+ * 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 +164,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 +523,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 +589,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