62134d33a6
Copy from home:dl9pf:branches:openSUSE:Factory/kexec-tools via accept of submit request 20658 revision 2. OBS-URL: https://build.opensuse.org/request/show/20658 OBS-URL: https://build.opensuse.org/package/show/Kernel:kdump/kexec-tools?expand=0&rev=4
188 lines
5.2 KiB
Diff
188 lines
5.2 KiB
Diff
From d182ce5434c7b66569118db0ccfe63e5d8a03687 Mon Sep 17 00:00:00 2001
|
|
From: Maxim Uvarov <muvarov@gmail.com>
|
|
Date: Wed, 15 Oct 2008 12:46:24 +0400
|
|
Subject: [PATCH] ppc64: kexec memory ranges dynamic allocation
|
|
|
|
Do not count max_memory_range for allocation. Increase allocation buffers
|
|
when it is needed. This actually allows us to avoid a lot of troubles with
|
|
various device-tree files.
|
|
|
|
Signed-off-by: Maxim Uvarov <muvarov@gmail.com>
|
|
Signed-off-by: Simon Horman <horms@verge.net.au>
|
|
|
|
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
|
|
index 069a9fc..f60c9ec 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");
|
|
- 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);
|
|
+ if (!memory_range)
|
|
+ goto err;
|
|
|
|
- return 0;
|
|
-}
|
|
+ base_memory_range = (struct memory_range *) realloc(memory_range, memory_range_len);
|
|
+ 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);
|
|
+ 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);
|
|
+ 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 long kexec_flags)
|
|
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 long kexec_flags)
|
|
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 long kexec_flags)
|
|
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 */
|
|
@@ -741,8 +697,9 @@ out:
|
|
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))
|