23ef29
From hbathini at linux.vnet.ibm.com  Thu Aug 17 05:31:51 2017
23ef29
From: hbathini at linux.vnet.ibm.com (Hari Bathini)
23ef29
Date: Thu, 17 Aug 2017 18:01:51 +0530
23ef29
Subject: [PATCH] kexec-tools: ppc64: avoid adding coherent memory regions to
23ef29
 crash memory ranges
23ef29
Message-ID: <150297311110.25328.11468130779639120510.stgit@hbathini.in.ibm.com>
23ef29
Content-Length: 3407
23ef29
Lines: 121
23ef29
23ef29
Accelerator devices like GPU and FPGA cards contain onboard memory. This
23ef29
onboard memory is represented as a memory only NUMA node, integrating it
23ef29
with core memory subsystem. Since, the link through which these devices
23ef29
are integrated to core memory goes down after a system crash and they are
23ef29
meant for user workloads, avoid adding coherent device memory regions to
23ef29
crash memory ranges. Without this change, makedumpfile tool tries to save
23ef29
unaccessible coherent device memory regions, crashing the system.
23ef29
23ef29
Signed-off-by: Hari Bathini <hbathini at linux.vnet.ibm.com>
23ef29
---
23ef29
 kexec/arch/ppc64/crashdump-ppc64.c |   64 +++++++++++++++++++++++++++++++++++-
23ef29
 kexec/arch/ppc64/kexec-ppc64.h     |    1 +
23ef29
 2 files changed, 63 insertions(+), 2 deletions(-)
23ef29
23ef29
diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c
23ef29
index 13995bf..7ea3983 100644
23ef29
--- a/kexec/arch/ppc64/crashdump-ppc64.c
23ef29
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
23ef29
@@ -181,6 +181,53 @@ static int get_dyn_reconf_crash_memory_ranges(void)
23ef29
 	return 0;
23ef29
 }
23ef29
 
23ef29
+/*
23ef29
+ * For a given memory node, check if it is mapped to system RAM or
23ef29
+ * to onboard memory on accelerator device like GPU card or such.
23ef29
+ */
23ef29
+static int is_coherent_device_mem(const char *fname)
23ef29
+{
23ef29
+	char fpath[PATH_LEN];
23ef29
+	char buf[32];
23ef29
+	DIR *dmem;
23ef29
+	FILE *file;
23ef29
+	struct dirent *mentry;
23ef29
+	int cnt, ret = 0;
23ef29
+
23ef29
+	strcpy(fpath, fname);
23ef29
+	if ((dmem = opendir(fpath)) == NULL) {
23ef29
+		perror(fpath);
23ef29
+		return -1;
23ef29
+	}
23ef29
+
23ef29
+	while ((mentry = readdir(dmem)) != NULL) {
23ef29
+		if (strcmp(mentry->d_name, "compatible"))
23ef29
+			continue;
23ef29
+
23ef29
+		strcat(fpath, "/compatible");
23ef29
+		if ((file = fopen(fpath, "r")) == NULL) {
23ef29
+			perror(fpath);
23ef29
+			ret = -1;
23ef29
+			break;
23ef29
+		}
23ef29
+		if ((cnt = fread(buf, 1, 32, file)) < 0) {
23ef29
+			perror(fpath);
23ef29
+			fclose(file);
23ef29
+			ret = -1;
23ef29
+			break;
23ef29
+		}
23ef29
+		if (!strncmp(buf, "ibm,coherent-device-memory", 26)) {
23ef29
+			ret = 1;
23ef29
+			break;
23ef29
+		}
23ef29
+		fclose(file);
23ef29
+	}
23ef29
+
23ef29
+	closedir(dmem);
23ef29
+	return ret;
23ef29
+}
23ef29
+
23ef29
+
23ef29
 /* Reads the appropriate file and retrieves the SYSTEM RAM regions for whom to
23ef29
  * create Elf headers. Keeping it separate from get_memory_ranges() as
23ef29
  * requirements are different in the case of normal kexec and crashdumps.
23ef29
@@ -196,12 +243,12 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
23ef29
 {
23ef29
 
23ef29
 	char device_tree[256] = "/proc/device-tree/";
23ef29
-	char fname[256];
23ef29
+	char fname[PATH_LEN];
23ef29
 	char buf[MAXBYTES];
23ef29
 	DIR *dir, *dmem;
23ef29
 	FILE *file;
23ef29
 	struct dirent *dentry, *mentry;
23ef29
-	int n, crash_rng_len = 0;
23ef29
+	int n, ret, crash_rng_len = 0;
23ef29
 	unsigned long long start, end;
23ef29
 	int page_size;
23ef29
 
23ef29
@@ -240,6 +287,19 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
23ef29
 			continue;
23ef29
 		strcpy(fname, device_tree);
23ef29
 		strcat(fname, dentry->d_name);
23ef29
+
23ef29
+		ret = is_coherent_device_mem(fname);
23ef29
+		if (ret == -1) {
23ef29
+			closedir(dir);
23ef29
+			goto err;
23ef29
+		} else if (ret == 1) {
23ef29
+			/*
23ef29
+			 * Avoid adding this memory region as it is not
23ef29
+			 * mapped to system RAM.
23ef29
+			 */
23ef29
+			continue;
23ef29
+		}
23ef29
+
23ef29
 		if ((dmem = opendir(fname)) == NULL) {
23ef29
 			perror(fname);
23ef29
 			closedir(dir);
23ef29
diff --git a/kexec/arch/ppc64/kexec-ppc64.h b/kexec/arch/ppc64/kexec-ppc64.h
23ef29
index 633ae77..434b4bf 100644
23ef29
--- a/kexec/arch/ppc64/kexec-ppc64.h
23ef29
+++ b/kexec/arch/ppc64/kexec-ppc64.h
23ef29
@@ -1,6 +1,7 @@
23ef29
 #ifndef KEXEC_PPC64_H
23ef29
 #define KEXEC_PPC64_H
23ef29
 
23ef29
+#define PATH_LEN 256
23ef29
 #define MAXBYTES 128
23ef29
 #define MAX_LINE 160
23ef29
 #define CORE_TYPE_ELF32 1
23ef29
23ef29
23ef29