[PATCH] makedumpfile: fix for hugepages filtering

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxxxxx>
---
 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))


_______________________________________________
kexec mailing list
kexec@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/kexec



[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux