From 5b6fe3ecda7c000360065834e7eb14d1add8017d Mon Sep 17 00:00:00 2001 From: Hari Bathini Date: Thu, 8 Mar 2018 23:39:55 +0530 Subject: [PATCH] makedumpfile: fix for hugepages filtering 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 Signed-off-by: Pingfan Liu --- makedumpfile.c | 30 ++++++++++++++++++++++++------ makedumpfile.h | 1 + 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/makedumpfile-1.6.2/makedumpfile.c b/makedumpfile-1.6.2/makedumpfile.c index ed138d3..ac8483d 100644 --- a/makedumpfile-1.6.2/makedumpfile.c +++ b/makedumpfile-1.6.2/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-1.6.2/makedumpfile.h b/makedumpfile-1.6.2/makedumpfile.h index 01eece2..4cfad98 100644 --- a/makedumpfile-1.6.2/makedumpfile.h +++ b/makedumpfile-1.6.2/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)) -- 2.7.4