All of lore.kernel.org
 help / color / mirror / Atom feed
From: Petr Tesarik <ptesarik@suse.cz>
To: Atsushi Kumagai <kumagai-atsushi@mxc.nes.nec.co.jp>
Cc: Petr Tesarik <ptesarik@suse.cz>, kexec@lists.infradead.org
Subject: [PATCH v2 2/3] Generic handling of multi-page exclusions
Date: Fri,  4 Apr 2014 19:25:08 +0200	[thread overview]
Message-ID: <25702884512808755449395c1622f2aed7b3be00.1396632131.git.ptesarik@suse.cz> (raw)
In-Reply-To: <cover.1396632131.git.ptesarik@suse.cz>
In-Reply-To: <cover.1396632131.git.ptesarik@suse.cz>

When multiple pages are excluded from the dump, store the extents in the
mem_map_data structure, and check if anything is still pending on the
next invocation of __exclude_unnecessary_pages for the same mem_map.

The start PFN of the excluded extent is set to the end of the current
cycle (which is equal to the start of the next cycle, see update_cycle),
so only the part of the excluded region which falls beyond current cycle
buffer is valid. If the excluded region is completely processed in the
current cycle, the start PFN is even bigger than the end PFN. That
causes nothing to be done at the beginning of the next cycle.

There is no check whether the adjusted pfn_start is still within the
current cycle. Nothing bad happens if it isn't, because exclude_range()
is used again to exclude the remaining part, so even if the excluded
region happens to span more than two cycles, the code will still work
correctly.

Note that clear_bit_on_2nd_bitmap_for_kernel() accepts PFNs outside the
current cyclic range. It willreturn FALSE, so such PFNs are not counted.

Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
---
 makedumpfile.c | 47 +++++++++++++++++++++++++++++++++--------------
 makedumpfile.h |  7 +++++++
 2 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 81c687b..9ffb901 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -2385,6 +2385,9 @@ dump_mem_map(unsigned long long pfn_start,
 	mmd->pfn_end   = pfn_end;
 	mmd->mem_map   = mem_map;
 
+	mmd->exclude_pfn_start = 0ULL;
+	mmd->exclude_pfn_end   = 0ULL;
+
 	DEBUG_MSG("mem_map (%d)\n", num_mm);
 	DEBUG_MSG("  mem_map    : %lx\n", mem_map);
 	DEBUG_MSG("  pfn_start  : %llx\n", pfn_start);
@@ -4657,6 +4660,21 @@ initialize_2nd_bitmap_cyclic(struct cycle *cycle)
 	return TRUE;
 }
 
+static void
+exclude_range(unsigned long long *counter, struct mem_map_data *mmd,
+    unsigned long long pfn, unsigned long long endpfn, struct cycle *cycle)
+{
+	while (pfn < endpfn) {
+		if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle))
+			(*counter)++;
+		++pfn;
+	}
+
+	mmd->exclude_pfn_start = cycle ? cycle->end_pfn : ULONGLONG_MAX;
+	mmd->exclude_pfn_end = endpfn;
+	mmd->exclude_pfn_counter = counter;
+}
+
 int
 __exclude_unnecessary_pages(struct mem_map_data *mmd, struct cycle *cycle)
 {
@@ -4671,6 +4689,18 @@ __exclude_unnecessary_pages(struct mem_map_data *mmd, struct cycle *cycle)
 	unsigned long flags, mapping, private = 0;
 
 	/*
+	 * If a multi-page exclusion is pending, do it first
+	 */
+	if (mmd->exclude_pfn_start < mmd->exclude_pfn_end) {
+		exclude_range(mmd->exclude_pfn_counter, mmd,
+			mmd->exclude_pfn_start, mmd->exclude_pfn_end,
+			cycle);
+
+		mem_map += (mmd->exclude_pfn_end - pfn_start) * SIZE(page);
+		pfn_start = mmd->exclude_pfn_end;
+	}
+
+	/*
 	 * Refresh the buffer of struct page, when changing mem_map.
 	 */
 	pfn_read_start = ULONGLONG_MAX;
@@ -4734,21 +4764,10 @@ __exclude_unnecessary_pages(struct mem_map_data *mmd, struct cycle *cycle)
 		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;
+
+			exclude_range(&pfn_free, mmd, pfn, pfn + nr_pages, cycle);
 
-			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);
 		}
diff --git a/makedumpfile.h b/makedumpfile.h
index 951ed1b..dfad569 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -816,6 +816,13 @@ struct mem_map_data {
 	unsigned long long	pfn_start;
 	unsigned long long	pfn_end;
 	unsigned long	mem_map;
+
+	/*
+	 * for excluding multi-page regions
+	 */
+	unsigned long		exclude_pfn_start;
+	unsigned long		exclude_pfn_end;
+	unsigned long long	*exclude_pfn_counter;
 };
 
 struct dump_bitmap {
-- 
1.8.4.5


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

  parent reply	other threads:[~2014-04-04 17:25 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-04 17:25 [PATCH v2 0/3] Generic multi-page exclusion Petr Tesarik
2014-04-04 17:25 ` [PATCH v2 1/3] Pass mmd pointer to __exclude_unnecessary_pages Petr Tesarik
2014-04-04 17:25 ` Petr Tesarik [this message]
2014-04-08  1:49   ` [PATCH v2 2/3] Generic handling of multi-page exclusions HATAYAMA Daisuke
2014-04-08  6:54     ` Petr Tesarik
2014-04-08  8:19       ` HATAYAMA Daisuke
2014-04-08  9:00         ` Atsushi Kumagai
2014-04-09  7:27           ` HATAYAMA Daisuke
2014-04-15  4:18             ` Atsushi Kumagai
2014-04-15  8:27               ` HATAYAMA Daisuke
2014-04-15 10:06                 ` Atsushi Kumagai
2014-04-08 10:07         ` Petr Tesarik
2014-04-09  7:12           ` HATAYAMA Daisuke
2014-04-08  7:06     ` Atsushi Kumagai
2014-04-10 10:47       ` Petr Tesarik
2014-04-11  1:59         ` HATAYAMA Daisuke
2014-04-15  1:20           ` Atsushi Kumagai
2014-04-15  6:23             ` Petr Tesarik
2014-04-15  8:09             ` HATAYAMA Daisuke
2014-04-04 17:25 ` [PATCH v2 3/3] Get rid of overrun adjustments Petr Tesarik
2014-04-08  7:02 ` [PATCH v2 0/3] Generic multi-page exclusion Atsushi Kumagai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=25702884512808755449395c1622f2aed7b3be00.1396632131.git.ptesarik@suse.cz \
    --to=ptesarik@suse.cz \
    --cc=kexec@lists.infradead.org \
    --cc=kumagai-atsushi@mxc.nes.nec.co.jp \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.