[PATCH 1/3] kexec/kdump: read crash memory ranges from drconf memory
Simon Horman
horms at verge.net.au
Tue Oct 7 21:40:57 EDT 2008
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
More information about the kexec
mailing list