Blame SOURCES/kexec-tools-2.0.15-makedumpfile-exclude-pages-that-are-logically-offline.patch

bedde7
From adc459398196322830e3b4bfacfab941c5f75f3a Mon Sep 17 00:00:00 2001
bedde7
From: David Hildenbrand <david@redhat.com>
bedde7
Date: Thu, 22 Nov 2018 11:09:38 +0100
bedde7
Subject: [PATCH] [PATCH] exclude pages that are logically offline
bedde7
bedde7
Linux marks pages that are logically offline via a page flag (map count).
bedde7
Such pages e.g. include pages infated as part of a balloon driver or
bedde7
pages that were not actually onlined when onlining the whole section.
bedde7
bedde7
While the hypervisor usually allows to read such inflated memory, we
bedde7
basically read and dump data that is completely irrelevant. Also, this
bedde7
might result in quite some overhead in the hypervisor. In addition,
bedde7
we saw some problems under Hyper-V, whereby we can crash the kernel by
bedde7
dumping, when reading memory of a partially onlined memory segment
bedde7
(for memory added by the Hyper-V balloon driver).
bedde7
bedde7
Therefore, don't read and dump pages that are marked as being logically
bedde7
offline.
bedde7
bedde7
Signed-off-by: David Hildenbrand <david@redhat.com>
bedde7
---
bedde7
 makedumpfile.c | 34 ++++++++++++++++++++++++++++++----
bedde7
 makedumpfile.h |  1 +
bedde7
 2 files changed, 31 insertions(+), 4 deletions(-)
bedde7
bedde7
diff --git a/makedumpfile-1.6.2/makedumpfile.c b/makedumpfile-1.6.2/makedumpfile.c
bedde7
index c9634cd..44c3aad 100644
bedde7
--- a/makedumpfile-1.6.2/makedumpfile.c
bedde7
+++ b/makedumpfile-1.6.2/makedumpfile.c
bedde7
@@ -88,6 +88,7 @@ mdf_pfn_t pfn_cache_private;
bedde7
 mdf_pfn_t pfn_user;
bedde7
 mdf_pfn_t pfn_free;
bedde7
 mdf_pfn_t pfn_hwpoison;
bedde7
+mdf_pfn_t pfn_offline;
bedde7
bedde7
 mdf_pfn_t num_dumped;
bedde7
bedde7
@@ -249,6 +250,21 @@ isHugetlb(unsigned long dtor)
bedde7
                     && (SYMBOL(free_huge_page) == dtor));
bedde7
 }
bedde7
bedde7
+static int
bedde7
+isOffline(unsigned long flags, unsigned int _mapcount)
bedde7
+{
bedde7
+	if (NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE) == NOT_FOUND_NUMBER)
bedde7
+		return FALSE;
bedde7
+
bedde7
+	if (flags & (1UL << NUMBER(PG_slab)))
bedde7
+		return FALSE;
bedde7
+
bedde7
+	if (_mapcount == (int)NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE))
bedde7
+		return TRUE;
bedde7
+
bedde7
+	return FALSE;
bedde7
+}
bedde7
+
bedde7
 static inline unsigned long
bedde7
 calculate_len_buf_out(long page_size)
bedde7
 {
bedde7
@@ -2258,6 +2274,8 @@ write_vmcoreinfo_data(void)
bedde7
	WRITE_NUMBER("PG_hwpoison", PG_hwpoison);
bedde7
bedde7
	WRITE_NUMBER("PAGE_BUDDY_MAPCOUNT_VALUE", PAGE_BUDDY_MAPCOUNT_VALUE);
bedde7
+	WRITE_NUMBER("PAGE_OFFLINE_MAPCOUNT_VALUE",
bedde7
+		     PAGE_OFFLINE_MAPCOUNT_VALUE);
bedde7
	WRITE_NUMBER("phys_base", phys_base);
bedde7
bedde7
	WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR);
bedde7
@@ -2656,6 +2674,7 @@ read_vmcoreinfo(void)
bedde7
	READ_SRCFILE("pud_t", pud_t);
bedde7
bedde7
	READ_NUMBER("PAGE_BUDDY_MAPCOUNT_VALUE", PAGE_BUDDY_MAPCOUNT_VALUE);
bedde7
+	READ_NUMBER("PAGE_OFFLINE_MAPCOUNT_VALUE", PAGE_OFFLINE_MAPCOUNT_VALUE);
bedde7
	READ_NUMBER("phys_base", phys_base);
bedde7
 #ifdef __aarch64__
bedde7
	READ_NUMBER("VA_BITS", VA_BITS);
bedde7
@@ -5918,6 +5937,12 @@ __exclude_unnecessary_pages(unsigned long mem_map,
bedde7
		else if (isHWPOISON(flags)) {
bedde7
			pfn_counter = &pfn_hwpoison;
bedde7
		}
bedde7
+		/*
bedde7
+		 * Exclude pages that are logically offline.
bedde7
+		 */
bedde7
+		else if (isOffline(flags, _mapcount)) {
bedde7
+			pfn_counter = &pfn_offline;
bedde7
+		}
bedde7
		/*
bedde7
		 * Unexcludable page
bedde7
		 */
bedde7
@@ -7399,7 +7424,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page)
bedde7
	 */
bedde7
	if (info->flag_cyclic) {
bedde7
		pfn_zero = pfn_cache = pfn_cache_private = 0;
bedde7
-		pfn_user = pfn_free = pfn_hwpoison = 0;
bedde7
+		pfn_user = pfn_free = pfn_hwpoison = pfn_offline = 0;
bedde7
		pfn_memhole = info->max_mapnr;
bedde7
	}
bedde7
bedde7
@@ -8674,7 +8699,7 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d
bedde7
		 * Reset counter for debug message.
bedde7
		 */
bedde7
		pfn_zero = pfn_cache = pfn_cache_private = 0;
bedde7
-		pfn_user = pfn_free = pfn_hwpoison = 0;
bedde7
+		pfn_user = pfn_free = pfn_hwpoison = pfn_offline = 0;
bedde7
		pfn_memhole = info->max_mapnr;
bedde7
bedde7
		/*
bedde7
@@ -9619,7 +9644,7 @@ print_report(void)
bedde7
	pfn_original = info->max_mapnr - pfn_memhole;
bedde7
bedde7
	pfn_excluded = pfn_zero + pfn_cache + pfn_cache_private
bedde7
-	    + pfn_user + pfn_free + pfn_hwpoison;
bedde7
+	    + pfn_user + pfn_free + pfn_hwpoison + pfn_offline;
bedde7
	shrinking = (pfn_original - pfn_excluded) * 100;
bedde7
	shrinking = shrinking / pfn_original;
bedde7
bedde7
@@ -9633,6 +9658,7 @@ print_report(void)
bedde7
	REPORT_MSG("    User process data pages : 0x%016llx\n", pfn_user);
bedde7
	REPORT_MSG("    Free pages              : 0x%016llx\n", pfn_free);
bedde7
	REPORT_MSG("    Hwpoison pages          : 0x%016llx\n", pfn_hwpoison);
bedde7
+	REPORT_MSG("    Offline pages           : 0x%016llx\n", pfn_offline);
bedde7
	REPORT_MSG("  Remaining pages  : 0x%016llx\n",
bedde7
	    pfn_original - pfn_excluded);
bedde7
	REPORT_MSG("  (The number of pages is reduced to %lld%%.)\n",
bedde7
@@ -9660,7 +9686,7 @@ print_mem_usage(void)
bedde7
	pfn_original = info->max_mapnr - pfn_memhole;
bedde7
bedde7
	pfn_excluded = pfn_zero + pfn_cache + pfn_cache_private
bedde7
-	    + pfn_user + pfn_free + pfn_hwpoison;
bedde7
+	    + pfn_user + pfn_free + pfn_hwpoison + pfn_offline;
bedde7
	shrinking = (pfn_original - pfn_excluded) * 100;
bedde7
	shrinking = shrinking / pfn_original;
bedde7
	total_size = info->page_size * pfn_original;
bedde7
diff --git a/makedumpfile-1.6.2/makedumpfile.h b/makedumpfile-1.6.2/makedumpfile.h
bedde7
index 5f7a1dc..a390582 100644
bedde7
--- a/makedumpfile-1.6.2/makedumpfile.h
bedde7
+++ b/makedumpfile-1.6.2/makedumpfile.h
bedde7
@@ -1874,6 +1874,7 @@ struct number_table {
bedde7
	long    PG_hwpoison;
bedde7
bedde7
	long	PAGE_BUDDY_MAPCOUNT_VALUE;
bedde7
+	long	PAGE_OFFLINE_MAPCOUNT_VALUE;
bedde7
	long	SECTION_SIZE_BITS;
bedde7
	long	MAX_PHYSMEM_BITS;
bedde7
	long    HUGETLB_PAGE_DTOR;
bedde7
--
bedde7
2.21.0