[PATCH] makedumpfile: fix for hugepages filtering

Hari Bathini hbathini at linux.vnet.ibm.com
Thu Mar 8 10:09:55 PST 2018


Kernel commit 036e7aa49fb2 changed 'compound_dtor' & 'compound_order'
types from 'unsigned short' to 'unsigned char'. Fix it here to ensure
hugepages are filtered properly.

Also, makedumpfile tool commit 484c6b18624 used 'int' type for 'dtor'
argument in 'isHugetlb' function. While this works in recent kernels
that use 'unsigned short/char' type for 'compound_dtor', it breaks
older kernels that used address of 'free_huge_page' as dtor. Fix it
by changing 'dtor' type.

Signed-off-by: Hari Bathini <hbathini at linux.vnet.ibm.com>
---
 makedumpfile.c |   30 ++++++++++++++++++++++++------
 makedumpfile.h |    1 +
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index ed138d3..ac8483d 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -241,7 +241,7 @@ is_in_same_page(unsigned long vaddr1, unsigned long vaddr2)
 }
 
 static inline int
-isHugetlb(int dtor)
+isHugetlb(unsigned long dtor)
 {
         return ((NUMBER(HUGETLB_PAGE_DTOR) != NOT_FOUND_NUMBER)
 		&& (NUMBER(HUGETLB_PAGE_DTOR) == dtor))
@@ -5798,18 +5798,36 @@ __exclude_unnecessary_pages(unsigned long mem_map,
 		 * and PGMM_CACHED is a power of 2.
 		 */
 		if ((index_pg < PGMM_CACHED - 1) && isCompoundHead(flags)) {
-			if (order_offset)
-				compound_order = USHORT(pcache + SIZE(page) + order_offset);
+			unsigned long long addr =
+				(unsigned long long)(pcache + SIZE(page));
+
+			if (order_offset) {
+				if (info->kernel_version >=
+				    KERNEL_VERSION(4, 16, 0)) {
+					compound_order =
+						UCHAR(addr + order_offset);
+				} else {
+					compound_order =
+						USHORT(addr + order_offset);
+				}
+			}
 
 			if (dtor_offset) {
 				/*
 				 * compound_dtor has been changed from the address of descriptor
 				 * to the ID of it since linux-4.4.
 				 */
-				if (info->kernel_version >= KERNEL_VERSION(4, 4, 0)) {
-					compound_dtor = USHORT(pcache + SIZE(page) + dtor_offset);
+				if (info->kernel_version >=
+				    KERNEL_VERSION(4, 16, 0)) {
+					compound_dtor =
+						UCHAR(addr + dtor_offset);
+				} else if (info->kernel_version >=
+					   KERNEL_VERSION(4, 4, 0)) {
+					compound_dtor =
+						USHORT(addr + dtor_offset);
 				} else {
-					compound_dtor = ULONG(pcache + SIZE(page) + dtor_offset);
+					compound_dtor =
+						ULONG(addr + dtor_offset);
 				}
 			}
 
diff --git a/makedumpfile.h b/makedumpfile.h
index 01eece2..4cfad98 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -241,6 +241,7 @@ static inline int string_exists(char *s) { return (s ? TRUE : FALSE); }
 		     string_exists((char *)(B)) &&	\
 	(strncmp((char *)(A), (char *)(B), strlen((char *)(B))) == 0))
 
+#define UCHAR(ADDR)	*((unsigned char *)(ADDR))
 #define USHORT(ADDR)	*((unsigned short *)(ADDR))
 #define UINT(ADDR)	*((unsigned int *)(ADDR))
 #define ULONG(ADDR)	*((unsigned long *)(ADDR))




More information about the kexec mailing list