Blame SOURCES/kexec-tools-2.0.15-makedumpfile-fix-for-hugepages-filtering.patch

42f05b
From 5b6fe3ecda7c000360065834e7eb14d1add8017d Mon Sep 17 00:00:00 2001
42f05b
From: Hari Bathini <hbathini@linux.vnet.ibm.com>
42f05b
Date: Thu, 8 Mar 2018 23:39:55 +0530
42f05b
Subject: [PATCH] makedumpfile: fix for hugepages filtering
42f05b
42f05b
Kernel commit 036e7aa49fb2 changed 'compound_dtor' & 'compound_order'
42f05b
types from 'unsigned short' to 'unsigned char'. Fix it here to ensure
42f05b
hugepages are filtered properly.
42f05b
42f05b
Also, makedumpfile tool commit 484c6b18624 used 'int' type for 'dtor'
42f05b
argument in 'isHugetlb' function. While this works in recent kernels
42f05b
that use 'unsigned short/char' type for 'compound_dtor', it breaks
42f05b
older kernels that used address of 'free_huge_page' as dtor. Fix it
42f05b
by changing 'dtor' type.
42f05b
42f05b
Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
42f05b
Signed-off-by: Pingfan Liu <piliu@redhat.com>
42f05b
---
42f05b
 makedumpfile.c | 30 ++++++++++++++++++++++++------
42f05b
 makedumpfile.h |  1 +
42f05b
 2 files changed, 25 insertions(+), 6 deletions(-)
42f05b
42f05b
diff --git a/makedumpfile-1.6.2/makedumpfile.c b/makedumpfile-1.6.2/makedumpfile.c
42f05b
index ed138d3..ac8483d 100644
42f05b
--- a/makedumpfile-1.6.2/makedumpfile.c
42f05b
+++ b/makedumpfile-1.6.2/makedumpfile.c
42f05b
@@ -241,7 +241,7 @@ is_in_same_page(unsigned long vaddr1, unsigned long vaddr2)
42f05b
 }
42f05b
 
42f05b
 static inline int
42f05b
-isHugetlb(int dtor)
42f05b
+isHugetlb(unsigned long dtor)
42f05b
 {
42f05b
         return ((NUMBER(HUGETLB_PAGE_DTOR) != NOT_FOUND_NUMBER)
42f05b
 		&& (NUMBER(HUGETLB_PAGE_DTOR) == dtor))
42f05b
@@ -5798,18 +5798,36 @@ __exclude_unnecessary_pages(unsigned long mem_map,
42f05b
 		 * and PGMM_CACHED is a power of 2.
42f05b
 		 */
42f05b
 		if ((index_pg < PGMM_CACHED - 1) && isCompoundHead(flags)) {
42f05b
-			if (order_offset)
42f05b
-				compound_order = USHORT(pcache + SIZE(page) + order_offset);
42f05b
+			unsigned long long addr =
42f05b
+				(unsigned long long)(pcache + SIZE(page));
42f05b
+
42f05b
+			if (order_offset) {
42f05b
+				if (info->kernel_version >=
42f05b
+				    KERNEL_VERSION(4, 16, 0)) {
42f05b
+					compound_order =
42f05b
+						UCHAR(addr + order_offset);
42f05b
+				} else {
42f05b
+					compound_order =
42f05b
+						USHORT(addr + order_offset);
42f05b
+				}
42f05b
+			}
42f05b
 
42f05b
 			if (dtor_offset) {
42f05b
 				/*
42f05b
 				 * compound_dtor has been changed from the address of descriptor
42f05b
 				 * to the ID of it since linux-4.4.
42f05b
 				 */
42f05b
-				if (info->kernel_version >= KERNEL_VERSION(4, 4, 0)) {
42f05b
-					compound_dtor = USHORT(pcache + SIZE(page) + dtor_offset);
42f05b
+				if (info->kernel_version >=
42f05b
+				    KERNEL_VERSION(4, 16, 0)) {
42f05b
+					compound_dtor =
42f05b
+						UCHAR(addr + dtor_offset);
42f05b
+				} else if (info->kernel_version >=
42f05b
+					   KERNEL_VERSION(4, 4, 0)) {
42f05b
+					compound_dtor =
42f05b
+						USHORT(addr + dtor_offset);
42f05b
 				} else {
42f05b
-					compound_dtor = ULONG(pcache + SIZE(page) + dtor_offset);
42f05b
+					compound_dtor =
42f05b
+						ULONG(addr + dtor_offset);
42f05b
 				}
42f05b
 			}
42f05b
 
42f05b
diff --git a/makedumpfile-1.6.2/makedumpfile.h b/makedumpfile-1.6.2/makedumpfile.h
42f05b
index 01eece2..4cfad98 100644
42f05b
--- a/makedumpfile-1.6.2/makedumpfile.h
42f05b
+++ b/makedumpfile-1.6.2/makedumpfile.h
42f05b
@@ -241,6 +241,7 @@ static inline int string_exists(char *s) { return (s ? TRUE : FALSE); }
42f05b
 		     string_exists((char *)(B)) &&	\
42f05b
 	(strncmp((char *)(A), (char *)(B), strlen((char *)(B))) == 0))
42f05b
 
42f05b
+#define UCHAR(ADDR)	*((unsigned char *)(ADDR))
42f05b
 #define USHORT(ADDR)	*((unsigned short *)(ADDR))
42f05b
 #define UINT(ADDR)	*((unsigned int *)(ADDR))
42f05b
 #define ULONG(ADDR)	*((unsigned long *)(ADDR))
42f05b
-- 
42f05b
2.7.4
42f05b