[PATCH 1/2] Generic handling of multi-page exclusions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When multiple pages are excluded from the dump, store the extents in the
DumpInfo structure and filter them in the normal loop. By doing it this
way, there is no need to process the whole region in the same cycle.

I chose to store the start and end PFN, rather than just the number of
pages, because this algorithm is more robust in case the memory map does
not cover the full range.

Signed-off-by: Petr Tesarik <ptesarik at suse.cz>
---
 makedumpfile.c | 33 +++++++++++++++++----------------
 makedumpfile.h |  7 +++++++
 2 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 5e81cc5..61ee886 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -4683,6 +4683,16 @@ __exclude_unnecessary_pages(unsigned long mem_map,
 			continue;
 
 		/*
+		 * If this is part of a multi-page exclusion, exclude this pfn.
+		 */
+		if (info->exclude_pfn_start <= pfn && pfn < info->exclude_pfn_end) {
+			if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle))
+				(*info->exclude_pfn_counter)++;
+			info->exclude_pfn_start = pfn + 1;
+			continue;
+		}
+
+		/*
 		 * Exclude the memory hole.
 		 */
 		if (is_xen_memory()) {
@@ -4732,23 +4742,14 @@ __exclude_unnecessary_pages(unsigned long mem_map,
 		if ((info->dump_level & DL_EXCLUDE_FREE)
 		    && info->page_is_buddy
 		    && info->page_is_buddy(flags, _mapcount, private, _count)) {
-			int i, nr_pages = 1 << private;
+			int nr_pages = 1 << private;
 
-			for (i = 0; i < nr_pages; ++i) {
-				/*
-				 * According to combination of
-				 * MAX_ORDER and size of cyclic
-				 * buffer, this clearing bit operation
-				 * can overrun the cyclic buffer.
-				 *
-				 * See check_cyclic_buffer_overrun()
-				 * for the detail.
-				 */
-				if (clear_bit_on_2nd_bitmap_for_kernel((pfn + i), cycle))
-					pfn_free++;
-			}
-			pfn += nr_pages - 1;
-			mem_map += (nr_pages - 1) * SIZE(page);
+			if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle))
+				pfn_free++;
+
+			info->exclude_pfn_start = pfn + 1;
+			info->exclude_pfn_end = pfn + nr_pages;
+			info->exclude_pfn_counter = &pfn_free;
 		}
 		/*
 		 * Exclude the cache page without the private page.
diff --git a/makedumpfile.h b/makedumpfile.h
index 951ed1b..fc6e89a 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -1078,6 +1078,13 @@ struct DumpInfo {
 	 */
 	int (*page_is_buddy)(unsigned long flags, unsigned int _mapcount,
 			     unsigned long private, unsigned int _count);
+
+	/*
+	 * for excluding multi-page regions
+	 */
+	unsigned long		exclude_pfn_start;
+	unsigned long		exclude_pfn_end;
+	unsigned long long	*exclude_pfn_counter;
 };
 extern struct DumpInfo		*info;
 
-- 
1.8.4.5




[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux