public inbox for kexec@lists.infradead.org
 help / color / mirror / Atom feed
From: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
To: kumagai-atsushi@mxc.nes.nec.co.jp
Cc: kexec@lists.infradead.org
Subject: [PATCH v2 06/10] Exclude free pages by looking up mem_map array
Date: Fri, 16 Nov 2012 14:02:02 +0900	[thread overview]
Message-ID: <20121116050202.8280.59537.stgit@localhost6.localdomain6> (raw)
In-Reply-To: <20121116050108.8280.14861.stgit@localhost6.localdomain6>

Add free page filtering logic in __exclude_unnecessary_pages.

Unlike other filtering levels, the number of free pages indicated by
buddy page is multiple. So I put this logic in the first position, in
front of page cache, to avoid filtering the pages that has already
been filtered as free pages.

Basically, this mem_map array logic is in cyclic mode only. The
exceptional case is that debug information necessary for mem_map logic
is not available enough. Then, it is switched to freelist logic.

In non cyclic mode, existing freelist logic is used.

Newly introduced page_is_buddy handler abstracts condition of buddy
page that varies depending on kernel versions. On the kernel versions
supported by makedumpfile, there are three kinds of buddy
conditions. Later patches will introduce them in order.

If failing to choose a correct page_is_buddy handler due to absence of
debug information, we switch the logic to freelist logic.

Signed-off-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
---

 makedumpfile.c |   45 ++++++++++++++++++++++++++++++++++++++++-----
 makedumpfile.h |    5 +++++
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 1a0151c..0e44a8b 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -58,6 +58,8 @@ do { \
 		*ptr_long_table = value; \
 } while (0)
 
+static void setup_page_is_buddy(void);
+
 void
 initialize_tables(void)
 {
@@ -2841,6 +2843,9 @@ out:
 	if (!get_value_for_old_linux())
 		return FALSE;
 
+	if (info->flag_cyclic && (info->dump_level & DL_EXCLUDE_FREE))
+		setup_page_is_buddy();
+
 	return TRUE;
 }
 
@@ -3663,6 +3668,18 @@ exclude_free_page(void)
 	return TRUE;
 }
 
+static void
+setup_page_is_buddy(void)
+{
+	if (OFFSET(page.private) == NOT_FOUND_STRUCTURE)
+		goto out;
+
+out:
+	if (!info->page_is_buddy)
+		DEBUG_MSG("Can't select page_is_buddy handler; "
+			  "follow free lists instead of mem_map array.\n");
+}
+
 /*
  * If using a dumpfile in kdump-compressed format as a source file
  * instead of /proc/vmcore, 1st-bitmap of a new dumpfile must be
@@ -3873,8 +3890,8 @@ __exclude_unnecessary_pages(unsigned long mem_map,
 	unsigned long long pfn_read_start, pfn_read_end, index_pg;
 	unsigned char page_cache[SIZE(page) * PGMM_CACHED];
 	unsigned char *pcache;
-	unsigned int _count;
-	unsigned long flags, mapping;
+	unsigned int _count, _mapcount = 0;
+	unsigned long flags, mapping, private = 0;
 
 	/*
 	 * Refresh the buffer of struct page, when changing mem_map.
@@ -3928,11 +3945,28 @@ __exclude_unnecessary_pages(unsigned long mem_map,
 		flags   = ULONG(pcache + OFFSET(page.flags));
 		_count  = UINT(pcache + OFFSET(page._count));
 		mapping = ULONG(pcache + OFFSET(page.mapping));
+		if (OFFSET(page._mapcount) != NOT_FOUND_STRUCTURE)
+			_mapcount = UINT(pcache + OFFSET(page._mapcount));
+		if (OFFSET(page.private) != NOT_FOUND_STRUCTURE)
+			private = ULONG(pcache + OFFSET(page.private));
 
 		/*
+		 * Exclude the free page managed by a buddy
+		 */
+		if ((info->dump_level & DL_EXCLUDE_FREE)
+		    && info->flag_cyclic
+		    && info->page_is_buddy
+		    && info->page_is_buddy(flags, _mapcount, private, _count)) {
+			int i;
+
+			for (i = 0; i < (1 << private); ++i)
+				clear_bit_on_2nd_bitmap_for_kernel(pfn + i);
+			pfn_free += i;
+		}
+		/*
 		 * Exclude the cache page without the private page.
 		 */
-		if ((info->dump_level & DL_EXCLUDE_CACHE)
+		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))
@@ -4013,7 +4047,7 @@ exclude_unnecessary_pages_cyclic(void)
 	 */
 	copy_bitmap_cyclic();
 
-	if (info->dump_level & DL_EXCLUDE_FREE)
+	if ((info->dump_level & DL_EXCLUDE_FREE) && !info->page_is_buddy)
 		if (!exclude_free_page())
 			return FALSE;
 
@@ -4022,7 +4056,8 @@ exclude_unnecessary_pages_cyclic(void)
 	 */
 	if (info->dump_level & DL_EXCLUDE_CACHE ||
 	    info->dump_level & DL_EXCLUDE_CACHE_PRI ||
-	    info->dump_level & DL_EXCLUDE_USER_DATA) {
+	    info->dump_level & DL_EXCLUDE_USER_DATA ||
+	    ((info->dump_level & DL_EXCLUDE_FREE) && info->page_is_buddy)) {
 
 		gettimeofday(&tv_start, NULL);
 
diff --git a/makedumpfile.h b/makedumpfile.h
index d69bcca..c236ece 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -1037,6 +1037,11 @@ struct DumpInfo {
 	 */
 	int flag_sadump_diskset;
 	enum sadump_format_type flag_sadump;         /* sadump format type */
+	/*
+	 * for filtering free pages managed by buddy system:
+	 */
+	int (*page_is_buddy)(unsigned long flags, unsigned int _mapcount,
+			     unsigned long private, unsigned int _count);
 };
 extern struct DumpInfo		*info;
 


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

  parent reply	other threads:[~2012-11-16  5:02 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-16  5:01 [PATCH v2 00/10] Support free page filtering looking up mem_map array HATAYAMA Daisuke
2012-11-16  5:01 ` [PATCH v2 01/10] Move page flags setup for old kernels after debuginfo initialization HATAYAMA Daisuke
2012-11-16  5:01 ` [PATCH v2 02/10] Add debuginfo interface for enum type size HATAYAMA Daisuke
2012-11-16  5:01 ` [PATCH v2 03/10] Add new parameters to various tables HATAYAMA Daisuke
2012-11-16  5:01 ` [PATCH v2 04/10] Add debuginfo-related processing for VMCOREINFO/VMLINUX HATAYAMA Daisuke
2012-11-16  5:01 ` [PATCH v2 05/10] Add hardcoded page flag values HATAYAMA Daisuke
2012-11-16  5:02 ` HATAYAMA Daisuke [this message]
2012-11-16  5:02 ` [PATCH v2 07/10] Add page_is_buddy for recent kernels HATAYAMA Daisuke
2012-11-16  5:02 ` [PATCH v2 08/10] Add page_is_buddy for PG_buddy HATAYAMA Daisuke
2012-11-27  6:00   ` Atsushi Kumagai
2012-11-27  7:30     ` Atsushi Kumagai
2012-11-27  8:53     ` Hatayama, Daisuke
2012-11-28  7:42       ` Atsushi Kumagai
2012-11-16  5:02 ` [PATCH v2 09/10] Add page_is_buddy for old kernels HATAYAMA Daisuke
2012-11-16  5:02 ` [PATCH v2 10/10] Warn cyclic buffer overrun and correct it if possible HATAYAMA Daisuke
2013-09-11  7:51   ` Atsushi Kumagai
2013-09-11  8:35     ` HATAYAMA Daisuke
2013-09-12  2:00       ` HATAYAMA Daisuke
2013-09-12  6:17         ` Atsushi Kumagai
2012-11-16  7:05 ` [PATCH v2 00/10] Support free page filtering looking up mem_map array 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=20121116050202.8280.59537.stgit@localhost6.localdomain6 \
    --to=d.hatayama@jp.fujitsu.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox