[RFC][PATCH 2/3] kexec-tools: add support for dynamic reconfiguration memory
Chandru
chandru at in.ibm.com
Fri Jun 13 14:00:12 EDT 2008
Changes to kexec-ppc64.c
Signed-off-by: Chandru Siddalingappa <chandru at in.ibm.com
---
--- kexec/arch/ppc64/kexec-ppc64.c.orig 2008-06-12 06:27:39.000000000 -0400
+++ kexec/arch/ppc64/kexec-ppc64.c 2008-06-13 13:28:31.000000000 -0400
@@ -96,6 +96,49 @@ err1:
}
+static int count_dyn_reconf_memory_ranges(void)
+{
+ 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;
+ }
+
+ if (fread(buf, 1, 8, file) < 0) {
+ perror(fname);
+ fclose(file);
+ return -1;
+ }
+
+ lmb_size = ((unsigned long long *)buf)[0];
+ fclose(file);
+
+ /* 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);
+}
+
/*
* Count the memory nodes under /proc/device-tree and populate the
* max_memory_ranges variable. This variable replaces MAX_MEMORY_RANGES
@@ -113,6 +156,12 @@ static int count_memory_ranges(void)
}
while ((dentry = readdir(dir)) != NULL) {
+ if (!strncmp(dentry->d_name,
+ "ibm,dynamic-reconfiguration-memory", 35)){
+ count_dyn_reconf_memory_ranges();
+ continue;
+ }
+
if (strncmp(dentry->d_name, "memory@", 7) &&
strcmp(dentry->d_name, "memory") &&
strncmp(dentry->d_name, "pci@", 4))
@@ -128,7 +177,52 @@ static int count_memory_ranges(void)
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++;
+
+ dbgprintf("%016llx-%016llx : %x\n",
+ base_memory_range[nr_memory_ranges-1].start,
+ base_memory_range[nr_memory_ranges-1].end,
+ base_memory_range[nr_memory_ranges-1].type);
+}
+
+static int get_dyn_reconf_base_ranges(void)
+{
+ 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 (nr_memory_ranges >= max_memory_ranges)
+ return -1;
+
+ start = ((uint64_t *)buf)[0];
+ end = start + lmb_size;
+ add_base_memory_range(start, end);
+ }
+ fclose(file);
+ return 0;
+}
/* Sort the base ranges in memory - this is useful for ensuring that our
* ranges are in ascending order, even if device-tree read of memory nodes
* is done differently. Also, could be used for other range coalescing later
@@ -156,7 +250,7 @@ static int sort_base_ranges(void)
/* Get base memory ranges */
static int get_base_ranges(void)
{
- int local_memory_ranges = 0;
+ uint64_t start, end;
char device_tree[256] = "/proc/device-tree/";
char fname[256];
char buf[MAXBYTES];
@@ -170,6 +264,11 @@ static int get_base_ranges(void)
return -1;
}
while ((dentry = readdir(dir)) != NULL) {
+ if (!strncmp(dentry->d_name,
+ "ibm,dynamic-reconfiguration-memory", 35)) {
+ get_dyn_reconf_base_ranges();
+ continue;
+ }
if (strncmp(dentry->d_name, "memory@", 7) &&
strcmp(dentry->d_name, "memory"))
continue;
@@ -197,27 +296,18 @@ static int get_base_ranges(void)
closedir(dir);
return -1;
}
- if (local_memory_ranges >= max_memory_ranges) {
+ if (nr_memory_ranges >= max_memory_ranges) {
fclose(file);
break;
}
- base_memory_range[local_memory_ranges].start =
- ((uint64_t *)buf)[0];
- base_memory_range[local_memory_ranges].end =
- base_memory_range[local_memory_ranges].start +
- ((uint64_t *)buf)[1];
- base_memory_range[local_memory_ranges].type = RANGE_RAM;
- local_memory_ranges++;
- dbgprintf("%016llx-%016llx : %x\n",
- base_memory_range[local_memory_ranges-1].start,
- base_memory_range[local_memory_ranges-1].end,
- base_memory_range[local_memory_ranges-1].type);
+ start = ((uint64_t *)buf)[0];
+ end = start + ((uint64_t *)buf)[1];
+ add_base_memory_range(start, end);
fclose(file);
}
closedir(dmem);
}
closedir(dir);
- nr_memory_ranges = local_memory_ranges;
sort_base_ranges();
memory_max = base_memory_range[nr_memory_ranges - 1].end;
#ifdef DEBUG
@@ -276,7 +366,9 @@ static int get_devtree_details(unsigned
strncmp(dentry->d_name, "memory@", 7) &&
strcmp(dentry->d_name, "memory") &&
strncmp(dentry->d_name, "pci@", 4) &&
- strncmp(dentry->d_name, "rtas", 4))
+ strncmp(dentry->d_name, "rtas", 4) &&
+ strncmp(dentry->d_name,
+ "ibm,dynamic-reconfiguration-memory", 35))
continue;
strcpy(fname, device_tree);
strcat(fname, dentry->d_name);
@@ -474,6 +566,29 @@ static int get_devtree_details(unsigned
closedir(cdir);
} /* memory */
+ if (!strncmp(dentry->d_name,
+ "ibm,dynamic-reconfiguration-memory", 35)) {
+ unsigned int k;
+ strcat(fname, "/ibm,dynamic-memory");
+ if ((file = fopen(fname, "r")) == NULL) {
+ perror(fname);
+ goto error_opencdir;
+ }
+ fseek(file, 4, SEEK_SET);
+ for (k = 0; k < num_of_lmbs; k++) {
+ if ((n = fread(buf, 1, 24, file)) < 0) {
+ perror(fname);
+ goto error_openfile;
+ }
+ rmo_base = ((unsigned long long *)buf)[0];
+ rmo_top = rmo_base + lmb_size;
+ if (rmo_top > 0x30000000UL)
+ rmo_top = 0x30000000UL;
+ }
+ fclose(file);
+ closedir(cdir);
+ } /* ibm,dynamic-reconfiguration-memory */
+
if (strncmp(dentry->d_name, "pci@", 4) == 0) {
strcat(fname, "/linux,tce-base");
if ((file = fopen(fname, "r")) == NULL) {
More information about the kexec
mailing list