On Thu, Dec 14, 2006 at 03:08:29PM +0530, Sachin P. Sant wrote:
> 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.
Are globals gauranteed to be NULL? I know that in kernel land they are.
But I'm not sure about user-space.
> 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.
Ok, thanks for clarifying that.
> >>+
> >>+/*
> >>+ * 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.
Thanks. I have one more minor comment, sorry for missing it yesterday.
> 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:
if (memory_range)
free(memory_range);
if (base_memory_range)
free(base_memory_range);
if (exclude_range)
free(exclude_range);
> + fprintf(stderr, "memory range structure allocation failure\n");
> + cleanup_memory_ranges();
> + return -1;
> +
Sorry to be a pain, but I think that you really need something like the
above under err1. Sorry that I didn't notice that yesterday.
> +}
> +
> +/*
> + * 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 */
--
Horms
H: http://www.vergenet.net/~horms/
W: http://www.valinux.co.jp/en/
_______________________________________________
fastboot mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/fastboot