On Wed, Sep 24, 2008 at 05:19:07PM +0530, Chandru wrote: > Get the memory ranges of the 1st kernel excluding the memory reserved for > kexec/kdump kernel in case of ibm,dynamic-reconfiguration-memory node of > device tree > > Signed-off-by: Chandru Siddalingappa <chandru at in.ibm.com> > --- > > kexec/arch/ppc64/crashdump-ppc64.c | 121 +++++++++++++++++++-------- > kexec/arch/ppc64/crashdump-ppc64.h | 3 > 2 files changed, 90 insertions(+), 34 deletions(-) > > --- kexec-tools-orig/kexec/arch/ppc64/crashdump-ppc64.c 2008-09-24 > 14:46:55.000000000 +0530 > +++ kexec-tools/kexec/arch/ppc64/crashdump-ppc64.c 2008-09-24 > 14:34:38.000000000 +0530 > @@ -84,6 +84,82 @@ mem_rgns_t usablemem_rgns = {0, NULL}; > */ > uint64_t saved_max_mem = 0; > > +static unsigned long long cstart, cend; > +static int memory_ranges; I'm not entirely happy with the scope of these variables being changed to static. But I guess it is ok. > + > +/* > + * Exclude the region that lies within crashkernel > + */ > +static void exclude_crash_region(uint64_t start, uint64_t end) > +{ > + if (cstart < end && cend > start) { > + if (start < cstart && end > cend) { > + crash_memory_range[memory_ranges].start = start; > + crash_memory_range[memory_ranges].end = cstart; > + crash_memory_range[memory_ranges].type = RANGE_RAM; > + memory_ranges++; > + crash_memory_range[memory_ranges].start = cend; > + crash_memory_range[memory_ranges].end = end; > + crash_memory_range[memory_ranges].type = RANGE_RAM; > + memory_ranges++; > + } else if (start < cstart) { > + crash_memory_range[memory_ranges].start = start; > + crash_memory_range[memory_ranges].end = cstart; > + crash_memory_range[memory_ranges].type = RANGE_RAM; > + memory_ranges++; > + } else if (end > cend) { > + crash_memory_range[memory_ranges].start = cend; > + crash_memory_range[memory_ranges].end = end; > + crash_memory_range[memory_ranges].type = RANGE_RAM; > + memory_ranges++; > + } > + } else { > + crash_memory_range[memory_ranges].start = start; > + crash_memory_range[memory_ranges].end = end; > + crash_memory_range[memory_ranges].type = RANGE_RAM; > + memory_ranges++; > + } > +} > + > +static int get_dyn_reconf_crash_memory_ranges() > +{ > + uint64_t start, end; > + char fname[128], buf[32]; > + FILE *file; > + int i, n; > + > + strcpy(fname, "/proc/device-tree/"); > + strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory"); > + if ((file = fopen(fname, "r")) == NULL) { > + perror(fname); > + return -1; > + } > + > + fseek(file, 4, SEEK_SET); > + for (i = 0; i < num_of_lmbs; i++) { > + if ((n = fread(buf, 1, 24, file)) < 0) { > + perror(fname); > + fclose(file); > + return -1; > + } > + if (memory_ranges >= (max_memory_ranges + 1)) { > + /* No space to insert another element. */ > + fprintf(stderr, > + "Error: Number of crash memory ranges" > + " excedeed the max limit\n"); > + return -1; > + } > + > + start = ((uint64_t *)buf)[0]; > + end = start + lmb_size; > + if (start == 0 && end >= (BACKUP_SRC_END + 1)) > + start = BACKUP_SRC_END + 1; > + exclude_crash_region(start, end); > + } > + fclose(file); > + return 0; > +} > + > /* Reads the appropriate file and retrieves the SYSTEM RAM regions for whom to > * create Elf headers. Keeping it separate from get_memory_ranges() as > * requirements are different in the case of normal kexec and crashdumps. > @@ -98,7 +174,6 @@ uint64_t saved_max_mem = 0; > static int get_crash_memory_ranges(struct memory_range **range, int *ranges) > { > > - int memory_ranges = 0; > char device_tree[256] = "/proc/device-tree/"; > char fname[256]; > char buf[MAXBYTES]; > @@ -106,7 +181,7 @@ static int get_crash_memory_ranges(struc > FILE *file; > struct dirent *dentry, *mentry; > int i, n, crash_rng_len = 0; > - unsigned long long start, end, cstart, cend; > + unsigned long long start, end; > int page_size; > > crash_max_memory_ranges = max_memory_ranges + 6; > @@ -129,7 +204,16 @@ static int get_crash_memory_ranges(struc > perror(device_tree); > goto err; > } > + > + cstart = crash_base; > + cend = crash_base + crash_size; > + > while ((dentry = readdir(dir)) != NULL) { > + if (!strncmp(dentry->d_name, > + "ibm,dynamic-reconfiguration-memory", 35)){ > + get_dyn_reconf_crash_memory_ranges(); > + continue; > + } > if (strncmp(dentry->d_name, "memory@", 7) && > strcmp(dentry->d_name, "memory")) > continue; > @@ -170,38 +254,7 @@ static int get_crash_memory_ranges(struc > if (start == 0 && end >= (BACKUP_SRC_END + 1)) > start = BACKUP_SRC_END + 1; > > - cstart = crash_base; > - cend = crash_base + crash_size; > - /* > - * Exclude the region that lies within crashkernel > - */ > - if (cstart < end && cend > start) { > - if (start < cstart && end > cend) { > - crash_memory_range[memory_ranges].start = start; > - crash_memory_range[memory_ranges].end = cstart; > - crash_memory_range[memory_ranges].type = RANGE_RAM; > - memory_ranges++; > - crash_memory_range[memory_ranges].start = cend; > - crash_memory_range[memory_ranges].end = end; > - crash_memory_range[memory_ranges].type = RANGE_RAM; > - memory_ranges++; > - } else if (start < cstart) { > - crash_memory_range[memory_ranges].start = start; > - crash_memory_range[memory_ranges].end = cstart; > - crash_memory_range[memory_ranges].type = RANGE_RAM; > - memory_ranges++; > - } else if (end > cend){ > - crash_memory_range[memory_ranges].start = cend; > - crash_memory_range[memory_ranges].end = end; > - crash_memory_range[memory_ranges].type = RANGE_RAM; > - memory_ranges++; > - } > - } else { > - crash_memory_range[memory_ranges].start = start; > - crash_memory_range[memory_ranges].end = end; > - crash_memory_range[memory_ranges].type = RANGE_RAM; > - memory_ranges++; > - } > + exclude_crash_region(start, end); > fclose(file); > } > closedir(dmem); > --- kexec-tools-orig/kexec/arch/ppc64/crashdump-ppc64.h 2008-09-24 > 14:46:55.000000000 +0530 > +++ kexec-tools/kexec/arch/ppc64/crashdump-ppc64.h 2008-09-16 > 19:18:57.000000000 +0530 > @@ -28,4 +28,7 @@ extern uint64_t crash_size; > extern unsigned int rtas_base; > extern unsigned int rtas_size; > > +uint64_t lmb_size; > +unsigned int num_of_lmbs; > + I am a little confused about why these variables need to be global as they only seem to be used inside get_crash_memory_ranges(). I am also a little confused about how they are initialised. > #endif /* CRASHDUMP_PPC64_H */ -- Simon Horman VA Linux Systems Japan K.K., Sydney, Australia Satellite Office H: www.vergenet.net/~horms/ W: www.valinux.co.jp/en