[PATCH makedumpfile v2 1/9] Do not call extensions for tail pages

Stephen Brennan stephen.s.brennan at oracle.com
Thu Aug 20 16:31:06 PDT 2026


Currently, extensions are called for every page which the loop does not
skip over. However, there is no case where the decision an extension
makes on a tail page will affect whether the tail page is included in
the dump:

  (1) If a compound head is excluded by the dump level (not an
  extension), we will create an exclusion in the 2nd bitmap and skip
  ahead in the loop, so we won't even call the extensions on tail pages.
  Even if we did not skip ahead, we have no consideration for removing
  the exclusion set by the compound head, so extensions would have no
  way to include specific sub-pages.

  (2) If a compound head is excluded by an extension returning
  PG_EXCLUDE, then we only exclude one page, and we do not skip forward
  in the loop. As a result, we will call extensions on each tail page,
  but regardless of the extension decision, the pages will be included,
  because we hit the "(compound_head & 1)" check before any exclusion
  can be done.

  (3) If a compound head is included by makedumpfile, we do not skip
  ahead in the loop, and so we do call extensions for each tail page.
  However, just as in (2), regardless of the decision of the extension
  we will include the tail page.

To sum up as succinctly as possible: while makedumpfile itself tries to
make filter decisions based on the head page, in some cases it calls
extensions on tail pages, and yet it disregards their decisions on them.
We can fix this in one of two ways:

  (a) Call extensions for every page and allow them to make any
  decision, including different decisions on head & tail pages.

  (b) Do not call extensions on tail pages at all; just apply the
  decision from the head page.

Since option (b) is the most similar to our existing behavior, it is the
simplest to implement. It is also more efficient, because it allows us
to skip compound tails, which is especially helpful for systems with
many excluded huge pages. Option (a) provides more flexibility for
extensions, but as of now there is no extension use case for allowing
arbitrary decisions on head & tail pages.

Thus, let's ensure we don't call extensions for any tail pages. Further,
let's treat PG_EXCLUDE as an exclusion of the entire compound page,
so that extension decisions have the same scope as any other filter
decision.

Signed-off-by: Stephen Brennan <stephen.s.brennan at oracle.com>
---
 makedumpfile.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 46d9ac7..1aafd4f 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -6543,14 +6543,6 @@ __exclude_unnecessary_pages(unsigned long mem_map,
 			pfn_read_end   = pfn + pfn_mm - 1;
 		}
 
-		/*
-		 * Include pages that specified by user via
-		 * makedumpfile extensions
-		 */
-		filter_pg = run_extension_callback(pfn, pcache);
-		if (filter_pg == PG_INCLUDE)
-			continue;
-
 		flags   = ULONG(pcache + OFFSET(page.flags));
 		_count  = UINT(pcache + OFFSET(page._refcount));
 		mapping = ULONG(pcache + OFFSET(page.mapping));
@@ -6637,14 +6629,22 @@ check_order:
 		 * Excludable compound tail pages must have already been excluded by
 		 * exclude_range(), don't need to check them here.
 		 */
-		if (compound_head & 1) {
+		if (compound_head & 1)
 			continue;
-		}
+
+		/*
+		 * Include pages that specified by user via
+		 * makedumpfile extensions
+		 */
+		filter_pg = run_extension_callback(pfn, pcache);
+		if (filter_pg == PG_INCLUDE)
+			continue;
+
 		/*
 		 * Exclude the free page managed by a buddy
 		 * Use buddy identification of free pages whether cyclic or not.
 		 */
-		else if ((info->dump_level & DL_EXCLUDE_FREE)
+		if ((info->dump_level & DL_EXCLUDE_FREE)
 		    && info->page_is_buddy
 		    && info->page_is_buddy(flags, _mapcount, private, _count)) {
 			if ((ARRAY_LENGTH(zone.free_area) != NOT_FOUND_STRUCTURE) &&
@@ -6712,7 +6712,6 @@ check_order:
 		 * makedumpfile extensions
 		 */
 		else if (filter_pg == PG_EXCLUDE) {
-			nr_pages = 1;
 			pfn_counter = &pfn_extension;
 		}
 		/*
-- 
2.52.0




More information about the kexec mailing list