From 49217d2feaa420b5bd24cd248252a20549358ab5 Mon Sep 17 00:00:00 2001 From: zhangzikang1992 Date: Mon, 29 Sep 2025 11:17:54 +0800 Subject: [PATCH] Fix incorrect page exclusion in exclude_nodata_pages() --- ...ges-exclusion-on-Linux-6.9-and-later.patch | 115 ++++++++++++++++++ kexec-tools.spec | 7 +- 2 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 Fix-failure-of-hugetlb-pages-exclusion-on-Linux-6.9-and-later.patch diff --git a/Fix-failure-of-hugetlb-pages-exclusion-on-Linux-6.9-and-later.patch b/Fix-failure-of-hugetlb-pages-exclusion-on-Linux-6.9-and-later.patch new file mode 100644 index 0000000..acc89b8 --- /dev/null +++ b/Fix-failure-of-hugetlb-pages-exclusion-on-Linux-6.9-and-later.patch @@ -0,0 +1,115 @@ +From 6c46a9d8c3bea79e380ba5ef854cd2e1c0e1f673 Mon Sep 17 00:00:00 2001 +From: zhangzikang +Date: Fri, 17 Jan 2025 11:53:07 +0800 +Subject: [PATCH] Fix failure of hugetlb pages exclusion on Linux 6.9 and later + +--- + makedumpfile-1.7.4/makedumpfile.c | 24 +++++++++++++++++++----- + makedumpfile-1.7.4/makedumpfile.h | 8 +++++--- + 2 files changed, 24 insertions(+), 8 deletions(-) + +diff --git a/makedumpfile-1.7.4/makedumpfile.c b/makedumpfile-1.7.4/makedumpfile.c +index a6ec9d4..aad5640 100644 +--- a/makedumpfile-1.7.4/makedumpfile.c ++++ b/makedumpfile-1.7.4/makedumpfile.c +@@ -275,13 +275,26 @@ isHugetlb(unsigned long dtor) + && (SYMBOL(free_huge_page) == dtor)); + } + ++static inline int ++isSlab(unsigned long flags, unsigned int _mapcount) ++{ ++ /* Linux 6.10 and later */ ++ if (NUMBER(PAGE_SLAB_MAPCOUNT_VALUE) != NOT_FOUND_NUMBER) { ++ unsigned int PG_slab = ~NUMBER(PAGE_SLAB_MAPCOUNT_VALUE); ++ if ((_mapcount & (PAGE_TYPE_BASE | PG_slab)) == PAGE_TYPE_BASE) ++ return TRUE; ++ } ++ ++ return flags & (1UL << NUMBER(PG_slab)); ++} ++ + static int + isOffline(unsigned long flags, unsigned int _mapcount) + { + if (NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE) == NOT_FOUND_NUMBER) + return FALSE; + +- if (flags & (1UL << NUMBER(PG_slab))) ++ if (isSlab(flags, _mapcount)) + return FALSE; + + if (_mapcount == (int)NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE)) +@@ -2970,6 +2983,7 @@ read_vmcoreinfo(void) + + READ_NUMBER("PAGE_BUDDY_MAPCOUNT_VALUE", PAGE_BUDDY_MAPCOUNT_VALUE); + READ_NUMBER("PAGE_OFFLINE_MAPCOUNT_VALUE", PAGE_OFFLINE_MAPCOUNT_VALUE); ++ READ_NUMBER("PAGE_SLAB_MAPCOUNT_VALUE", PAGE_SLAB_MAPCOUNT_VALUE); + READ_NUMBER("phys_base", phys_base); + READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE); + #ifdef __aarch64__ +@@ -6022,7 +6036,7 @@ static int + page_is_buddy_v3(unsigned long flags, unsigned int _mapcount, + unsigned long private, unsigned int _count) + { +- if (flags & (1UL << NUMBER(PG_slab))) ++ if (isSlab(flags, _mapcount)) + return FALSE; + + if (_mapcount == (int)NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE)) +@@ -6580,7 +6594,7 @@ check_order: + */ + else if ((info->dump_level & DL_EXCLUDE_CACHE) + && is_cache_page(flags) +- && !isPrivate(flags) && !isAnon(mapping, flags)) { ++ && !isPrivate(flags) && !isAnon(mapping, flags, _mapcount)) { + pfn_counter = &pfn_cache; + } + /* +@@ -6588,7 +6602,7 @@ check_order: + */ + else if ((info->dump_level & DL_EXCLUDE_CACHE_PRI) + && is_cache_page(flags) +- && !isAnon(mapping, flags)) { ++ && !isAnon(mapping, flags, _mapcount)) { + if (isPrivate(flags)) + pfn_counter = &pfn_cache_private; + else +@@ -6600,7 +6614,7 @@ check_order: + * - hugetlbfs pages + */ + else if ((info->dump_level & DL_EXCLUDE_USER_DATA) +- && (isAnon(mapping, flags) || isHugetlb(compound_dtor))) { ++ && (isAnon(mapping, flags, _mapcount) || isHugetlb(compound_dtor))) { + pfn_counter = &pfn_user; + } + /* +diff --git a/makedumpfile-1.7.4/makedumpfile.h b/makedumpfile-1.7.4/makedumpfile.h +index 59a809c..526668c 100644 +--- a/makedumpfile-1.7.4/makedumpfile.h ++++ b/makedumpfile-1.7.4/makedumpfile.h +@@ -161,9 +161,10 @@ test_bit(int nr, unsigned long addr) + #define isSwapBacked(flags) test_bit(NUMBER(PG_swapbacked), flags) + #define isHWPOISON(flags) (test_bit(NUMBER(PG_hwpoison), flags) \ + && (NUMBER(PG_hwpoison) != NOT_FOUND_NUMBER)) +-#define isSlab(flags) test_bit(NUMBER(PG_slab), flags) +-#define isAnon(mapping, flags) (((unsigned long)mapping & PAGE_MAPPING_ANON) != 0 \ +- && !isSlab(flags)) ++#define isAnon(mapping, flags, _mapcount) \ ++ (((unsigned long)mapping & PAGE_MAPPING_ANON) != 0 && !isSlab(flags, _mapcount)) ++ ++#define PAGE_TYPE_BASE (0xf0000000) + + #define PTOB(X) (((unsigned long long)(X)) << PAGESHIFT()) + #define BTOP(X) (((unsigned long long)(X)) >> PAGESHIFT()) +@@ -2235,6 +2236,7 @@ struct number_table { + + long PAGE_BUDDY_MAPCOUNT_VALUE; + long PAGE_OFFLINE_MAPCOUNT_VALUE; ++ long PAGE_SLAB_MAPCOUNT_VALUE; + long SECTION_SIZE_BITS; + long MAX_PHYSMEM_BITS; + long HUGETLB_PAGE_DTOR; +-- +2.43.0 + diff --git a/kexec-tools.spec b/kexec-tools.spec index 8515934..5a64b1e 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -4,7 +4,7 @@ Name: kexec-tools Version: 2.0.26 -Release: 13 +Release: 14 License: GPLv2 Summary: The kexec/kdump userspace component URL: https://www.kernel.org/ @@ -91,7 +91,7 @@ Patch0011: loongarch64-fix-kernel-image-size-error.patch Patch0012: LoongArch-Load-vmlinux.efi-to-the-link-address.patch %endif Patch0009: Before-adding-to-usablemem_rgns-check-if-the-memory-.patch - +Patch0013: Fix-failure-of-hugetlb-pages-exclusion-on-Linux-6.9-and-later.patch %description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -300,6 +300,9 @@ done %endif %changelog +* Mon Sep 29 2025 zhangzikang - 2.0.26-14 +- Fix incorrect page exclusion in exclude_nodata_pages() + * Tue Jun 24 2025 Ming Wang - 2.0.26-13 - Backport upstream patch to fix KVM kexec issue. - Fix loongarch kdump image size overflow issue. -- Gitee