[PATCH makedumpfile v2 7/9] Add PG_INCLUDE_HEAD extension return status

Stephen Brennan <[email protected]>
Newsgroups org.infradead.lists.kexec
Message-ID <[email protected]>
Prior to patch "Do not call extensions for tail pages", extensions were
called for tail pages in many cases, yet their decisions on tail pages
were not respected when they conflicted with our decision on the head
page. Since that patch, we do not call extensions for tail pages.
Instead, we apply the decision of the head page for the entirety of the
compound page, which is consistent with how we handle compound pages in
general.

However, some extensions may want more fine-grained control. One such
policy may be to include only the head page, excluding tail pages. For
example, this is useful for an extension which includes just the first
page of ELF file headers within the page cache. Since page cache data
frequently uses larger folios, including just the head can avoid
unnecessary overhead.

So, add a new return status PG_INCLUDE_HEAD, which behaves as described,
including just the head of a compound page.

Signed-off-by: Stephen Brennan <[email protected]>
---
 extension.c    | 2 +-
 extension.h    | 7 ++++---
 makedumpfile.c | 9 +++++++++
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/extension.c b/extension.c
index 9b29f0c..a7360d0 100644
--- a/extension.c
+++ b/extension.c
@@ -314,7 +314,7 @@ int run_extension_callback(unsigned long pfn, const void *pcache, const struct p
 	for (int i = 0; i < handle_cbs_len; i++) {
 		if (handle_cbs[i]->cb) {
 			result = handle_cbs[i]->cb(pfn, pcache, inf);
-			if (result == PG_INCLUDE) {
+			if (result == PG_INCLUDE || result == PG_INCLUDE_HEAD) {
 				ret = result;
 				goto out;
 			} else if (result == PG_EXCLUDE) {
diff --git a/extension.h b/extension.h
index 22af9a6..3edfbeb 100644
--- a/extension.h
+++ b/extension.h
@@ -4,9 +4,10 @@
 
 struct pginfo;
 enum {
-	PG_INCLUDE,	// Exntesion will keep the page
-	PG_EXCLUDE,	// Exntesion will discard the page
-	PG_UNDECID,	// Exntesion makes no decision
+	PG_INCLUDE,		// Extension will keep the full page
+	PG_INCLUDE_HEAD,	// Extension will keep just the head page
+	PG_EXCLUDE,		// Extension will discard the full page
+	PG_UNDECID,		// Extension makes no decision
 };
 int run_extension_callback(unsigned long pfn, const void *pcache, const struct pginfo *i);
 void init_extensions(void);
diff --git a/makedumpfile.c b/makedumpfile.c
index 6c62930..7277e42 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -6666,6 +6666,15 @@ check_order:
 			 * retained by an extension. */
 			num_extension_retained += nr_pages;
 			continue;
+		} else if (filter_pg == PG_INCLUDE_HEAD) {
+			num_extension_retained += 1;
+			if (nr_pages == 1)
+				continue;
+
+			/* FALL THROUGH and exclude tail pages */
+			pfn++;
+			mem_map += SIZE(page);
+			nr_pages--;
 		}
 
 		/*
-- 
2.52.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.