Re: [PATCH] kexec memory ranges dynamic allocation
From: Maxim Uvarov <hidden>
Date: 2008-10-31 06:53:26
Also in:
kexec
2008/10/31 Simon Horman [off-list ref]
Hi, Could someone please comment on the satus of this patch?
Hello, Simon I can not reproduce error which you wrote before on my target. So it is a little bit difficult to say what was wrong exactly.
On Wed, Oct 15, 2008 at 12:46:24PM +0400, Maxim Uvarov wrote:quoted
Patch corrected. ( git_kexec_powerpc_v2.patch is attached.) I tested it on ppc64 pasemi electra board. Both kexec -l and kexec -pworks.quoted
Maxim. 2008/10/15 Simon Horman [off-list ref]quoted
On Tue, Oct 14, 2008 at 07:11:19PM +0400, Maxim Uvarov wrote:quoted
Hello all, As you all know it is not easy to count exact value of memory rangesfromquoted
quoted
quoted
device tree on powerpc. It very depends on how dts file was written. What do you think aboutreallyquoted
dynamic allocation buffers for this buffers?Conceptually I have no objections to the change, though I would like to get some review from ppc people. (linuxppc-dev@ozlabs.org CCed)quoted
Patch is attached.This patch doesn't seem to compile for me. # powerpc64-unknown-linux-gnu-gcc --version powerpc64-unknown-linux-gnu-gcc (GCC) 4.1.1 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There isNOquoted
quoted
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULARPURPOSE.quoted
quoted
#make [snip] kexec/arch/ppc64/kexec-ppc64.c:100: warning: function declaration isn'taquoted
quoted
prototype kexec/arch/ppc64/kexec-ppc64.c: In function 'realloc_memory_ranges': kexec/arch/ppc64/kexec-ppc64.c:107: warning: passing argument 1 of 'realloc' makes pointer from integer without a cast kexec/arch/ppc64/kexec-ppc64.c:107: error: too few arguments tofunctionquoted
quoted
'realloc' kexec/arch/ppc64/kexec-ppc64.c:102: warning: unused variable 'tmp' -- Simon Horman VA Linux Systems Japan K.K., Sydney, Australia Satellite Office H: www.vergenet.net/~horms/ <http://www.vergenet.net/%7Ehorms/> <http://www.vergenet.net/%7Ehorms/>quoted
quoted
W: www.valinux.co.jp/en-- Best regards, Maxim Uvarovquoted
diff --git a/kexec/arch/ppc64/kexec-ppc64.cb/kexec/arch/ppc64/kexec-ppc64.cquoted
index 069a9fc..0ad40fa 100644--- a/kexec/arch/ppc64/kexec-ppc64.c +++ b/kexec/arch/ppc64/kexec-ppc64.c@@ -96,96 +96,46 @@ err1: } -static int count_dyn_reconf_memory_ranges(void) +static int realloc_memory_ranges() { - char device_tree[] = "/proc/device-tree/"; - char fname[128]; - char buf[32]; - FILE *file; - - strcpy(fname, device_tree); - strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,lmb-size"); - if ((file = fopen(fname, "r")) == NULL) { - perror(fname); - return -1; - } + size_t memory_range_len; - if (fread(buf, 1, 8, file) < 0) { - perror(fname); - fclose(file); - return -1; - } - - lmb_size = ((uint64_t *)buf)[0]; - fclose(file); + max_memory_ranges++; + memory_range_len = sizeof(struct memory_range) * max_memory_ranges; - /* Get number of lmbs from ibm,dynamic-memory */ - strcpy(fname, device_tree); - strcat(fname,"ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory");quoted
- if ((file = fopen(fname, "r")) == NULL) { - perror(fname); - return -1; - } - /* - * first 4 bytes provide number of entries(lmbs) - */ - if (fread(buf, 1, 4, file) < 0) { - perror(fname); - fclose(file); - return -1; - } - num_of_lmbs = ((unsigned int *)buf)[0]; - max_memory_ranges += num_of_lmbs; - fclose(file); + memory_range = (struct memory_range *) realloc(memory_range,memory_range_len);quoted
+ if (!memory_range) + goto err; - return 0; -} + base_memory_range = (struct memory_range *) realloc(memory_range,memory_range_len);quoted
+ if (!base_memory_range) + goto err; -/* - * 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(void) -{ - char device_tree[256] = "/proc/device-tree/"; - struct dirent *dentry; - DIR *dir; + exclude_range = (struct memory_range *) realloc(exclude_range,memory_range_len);quoted
+ if (!exclude_range) + goto err; - if ((dir = opendir(device_tree)) == NULL) { - perror(device_tree); - return -1; - } + usablemem_rgns.ranges = (struct memory_range *) + realloc(usablemem_rgns.ranges,memory_range_len);quoted
+ if (!(usablemem_rgns.ranges)) + goto err; - while ((dentry = readdir(dir)) != NULL) { - if (!strncmp(dentry->d_name, - "ibm,dynamic-reconfiguration-memory", 35)){ - if (count_dyn_reconf_memory_ranges() != 0) - return -1; - continue; - } + return 0; - if (strncmp(dentry->d_name, "memory@", 7) && - strcmp(dentry->d_name, "memory") && - strncmp(dentry->d_name, "pci@", 4)) - continue; - max_memory_ranges++; - } - /* need to add extra region for retained initrd */ - if (reuse_initrd) { - max_memory_ranges++; - } +err: + fprintf(stderr, "memory range structure re-allocation failure\n"); + return -1; +} - closedir(dir); - return 0; -} static void add_base_memory_range(uint64_t start, uint64_t end) { base_memory_range[nr_memory_ranges].start = start; base_memory_range[nr_memory_ranges].end = end; base_memory_range[nr_memory_ranges].type = RANGE_RAM; nr_memory_ranges++; + if (nr_memory_ranges >= max_memory_ranges) + realloc_memory_ranges(); dbgprintf("%016llx-%016llx : %x\n", base_memory_range[nr_memory_ranges-1].start,@@ -300,8 +250,8 @@ static int get_base_ranges(void) return -1; } if (nr_memory_ranges >= max_memory_ranges) { - fclose(file); - break; + if (realloc_memory_ranges() < 0) + break; } start = ((uint64_t *)buf)[0]; end = start + ((uint64_t *)buf)[1];@@ -396,6 +346,8 @@ static int get_devtree_details(unsigned longkexec_flags)quoted
exclude_range[i].start = 0x0UL; exclude_range[i].end = kernel_end; i++; + if (i >= max_memory_ranges) + realloc_memory_ranges(); if (kexec_flags & KEXEC_ON_CRASH) { memset(fname, 0, sizeof(fname));@@ -470,6 +422,8 @@ static int get_devtree_details(unsigned longkexec_flags)quoted
exclude_range[i].start = htab_base; exclude_range[i].end = htab_base + htab_size; i++; + if (i >= max_memory_ranges) + realloc_memory_ranges(); /* reserve the initrd_start and end locations. */ if (reuse_initrd) {@@ -545,6 +499,8 @@ static int get_devtree_details(unsigned longkexec_flags)quoted
exclude_range[i].start = rtas_base; exclude_range[i].end = rtas_base + rtas_size; i++; + if (i >= max_memory_ranges) + realloc_memory_ranges(); if (kexec_flags & KEXEC_ON_CRASH) add_usable_mem_rgns(rtas_base, rtas_size); } /* rtas */@@ -740,9 +696,10 @@ out: /* 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; +{ + /* allocate memory_range dynamically */ + max_memory_ranges = 1; + if (alloc_memory_ranges()) return -1; if (setup_memory_ranges(kexec_flags))-- Simon Horman VA Linux Systems Japan K.K., Sydney, Australia Satellite Office H: www.vergenet.net/~horms/ <http://www.vergenet.net/%7Ehorms/> W: www.valinux.co.jp/en
-- Best regards, Maxim Uvarov