Hugepage filtering. OBS-URL: https://build.opensuse.org/request/show/237231 OBS-URL: https://build.opensuse.org/package/show/Kernel:kdump/makedumpfile?expand=0&rev=85
128 lines
3.7 KiB
Diff
128 lines
3.7 KiB
Diff
From: Petr Tesarik <ptesarik@suse.cz>
|
|
Date: Fri Jun 13 11:57:03 2014 +0200
|
|
Subject: Treat compound pages as a single entity
|
|
References: bnc#873232
|
|
Patch-mainline: not yet
|
|
|
|
For a compound page, the head page determines whether the page should be
|
|
kept or excluded.
|
|
|
|
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
|
|
|
|
---
|
|
makedumpfile.c | 57 +++++++++++++++++++++++++++++++++++++++++++--------------
|
|
1 file changed, 43 insertions(+), 14 deletions(-)
|
|
|
|
--- a/makedumpfile.c
|
|
+++ b/makedumpfile.c
|
|
@@ -4652,6 +4652,7 @@ __exclude_unnecessary_pages(unsigned lon
|
|
unsigned char *pcache;
|
|
unsigned int _count, _mapcount = 0;
|
|
unsigned long flags, mapping, private = 0;
|
|
+ int nr_pages;
|
|
|
|
/*
|
|
* If a multi-page exclusion is pending, do it first
|
|
@@ -4671,7 +4672,13 @@ __exclude_unnecessary_pages(unsigned lon
|
|
pfn_read_start = ULONGLONG_MAX;
|
|
pfn_read_end = 0;
|
|
|
|
- for (pfn = pfn_start; pfn < pfn_end; pfn++, mem_map += SIZE(page)) {
|
|
+ for (pfn = pfn_start; pfn < pfn_end; pfn += nr_pages, mem_map += nr_pages * SIZE(page)) {
|
|
+ unsigned long long *pfn_counter;
|
|
+
|
|
+ /*
|
|
+ * Process one page by default.
|
|
+ */
|
|
+ nr_pages = 1;
|
|
|
|
/*
|
|
* If this pfn doesn't belong to target region, skip this pfn.
|
|
@@ -4723,18 +4730,32 @@ __exclude_unnecessary_pages(unsigned lon
|
|
private = ULONG(pcache + OFFSET(page.private));
|
|
|
|
/*
|
|
+ * Check for compound pages.
|
|
+ */
|
|
+ if (isCompoundHead(flags) && (pfn + 1 <= pfn_read_end)) {
|
|
+ unsigned char *ptail;
|
|
+ unsigned long order;
|
|
+
|
|
+ ptail = pcache + SIZE(page);
|
|
+ order = ULONG(ptail + OFFSET(page.lru) +
|
|
+ OFFSET(list_head.prev));
|
|
+ if (order && order < sizeof(unsigned long) * 8 &&
|
|
+ (pfn & ((1UL << order) - 1)) == 0 &&
|
|
+ (OFFSET(page.private) == NOT_FOUND_STRUCTURE ||
|
|
+ ULONG(ptail + OFFSET(page.private)) == mem_map)) {
|
|
+ nr_pages = 1UL << order;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /*
|
|
* Exclude the free page managed by a buddy
|
|
* Use buddy identification of free pages whether cyclic or not.
|
|
*/
|
|
if ((info->dump_level & DL_EXCLUDE_FREE)
|
|
&& info->page_is_buddy
|
|
&& info->page_is_buddy(flags, _mapcount, private, _count)) {
|
|
- int nr_pages = 1 << private;
|
|
-
|
|
- exclude_range(&pfn_free, pfn, pfn + nr_pages, cycle);
|
|
-
|
|
- pfn += nr_pages - 1;
|
|
- mem_map += (nr_pages - 1) * SIZE(page);
|
|
+ nr_pages = 1 << private;
|
|
+ pfn_counter = &pfn_free;
|
|
}
|
|
/*
|
|
* Exclude the cache page without the private page.
|
|
@@ -4742,8 +4763,7 @@ __exclude_unnecessary_pages(unsigned lon
|
|
else if ((info->dump_level & DL_EXCLUDE_CACHE)
|
|
&& (isLRU(flags) || isSwapCache(flags))
|
|
&& !isPrivate(flags) && !isAnon(mapping)) {
|
|
- if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle))
|
|
- pfn_cache++;
|
|
+ pfn_counter = &pfn_cache;
|
|
}
|
|
/*
|
|
* Exclude the cache page with the private page.
|
|
@@ -4751,23 +4771,32 @@ __exclude_unnecessary_pages(unsigned lon
|
|
else if ((info->dump_level & DL_EXCLUDE_CACHE_PRI)
|
|
&& (isLRU(flags) || isSwapCache(flags))
|
|
&& !isAnon(mapping)) {
|
|
- if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle))
|
|
- pfn_cache_private++;
|
|
+ pfn_counter = &pfn_cache_private;
|
|
}
|
|
/*
|
|
* Exclude the data page of the user process.
|
|
*/
|
|
else if ((info->dump_level & DL_EXCLUDE_USER_DATA)
|
|
&& isAnon(mapping)) {
|
|
- if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle))
|
|
- pfn_user++;
|
|
+ pfn_counter = &pfn_user;
|
|
}
|
|
/*
|
|
* Exclude the hwpoison page.
|
|
*/
|
|
else if (isHWPOISON(flags)) {
|
|
+ pfn_counter = &pfn_hwpoison;
|
|
+ }
|
|
+ /*
|
|
+ * Page not excluded
|
|
+ */
|
|
+ else
|
|
+ continue;
|
|
+
|
|
+ if (nr_pages == 1) {
|
|
if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle))
|
|
- pfn_hwpoison++;
|
|
+ (*pfn_counter)++;
|
|
+ } else {
|
|
+ exclude_range(pfn_counter, pfn, pfn + nr_pages, cycle);
|
|
}
|
|
}
|
|
return TRUE;
|