public inbox for kexec@lists.infradead.org
 help / color / mirror / Atom feed
From: Petr Tesarik <ptesarik@suse.cz>
To: kexec@lists.infradead.org
Cc: Norbert Trapp <Norbert.Trapp@ts.fujitsu.com>
Subject: [PATCHv3 8/9] Add support for filtering out user pages under Xen4
Date: Fri, 24 Aug 2012 17:43:23 +0200	[thread overview]
Message-ID: <201208241743.23829.ptesarik@suse.cz> (raw)

In Xen-4.0+, usage of a page must be determined from its PGC_xxx
flags, which are stored in the highest bits of the _count field
of struct page_info.

Let's keep the original function for Xen3 only and add a new
function for walking the pages under Xen4. This avoids adding many
new conditionals to the inner loop and also makes the logic easier
to follow for all Xen versions.

Signed-off-by: Norbert Trapp <norbert.trapp@ts.fujitsu.com>
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>

---
 makedumpfile.c |  102 
+++++++++++++++++++++++++++++++++++++++++++++++++++++----
 makedumpfile.h |   25 +++++++++++++
 2 files changed, 121 insertions(+), 6 deletions(-)

--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -78,6 +78,31 @@ int get_mem_type(void);
 #define LSEEKED_PDATA	(3)
 
 /*
+ * Xen page flags
+ */
+#define BITS_PER_BYTE (8)
+#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
+#define PG_shift(idx)	(BITS_PER_LONG - (idx))
+#define PG_mask(x, idx)	(x ## UL << PG_shift(idx))
+ /* Cleared when the owning guest 'frees' this page. */
+#define PGC_allocated       PG_mask(1, 1)
+ /* Page is Xen heap? */
+#define PGC_xen_heap        PG_mask(1, 2)
+ /* Page is broken? */
+#define PGC_broken          PG_mask(1, 7)
+ /* Mutually-exclusive page states: { inuse, offlining, offlined, free }. */
+#define PGC_state           PG_mask(3, 9)
+#define PGC_state_inuse     PG_mask(0, 9)
+#define PGC_state_offlining PG_mask(1, 9)
+#define PGC_state_offlined  PG_mask(2, 9)
+#define PGC_state_free      PG_mask(3, 9)
+#define page_state_is(ci, st) (((ci)&PGC_state) == PGC_state_##st)
+
+ /* Count of references to this frame. */
+#define PGC_count_width   PG_shift(9)
+#define PGC_count_mask    ((1UL<<PGC_count_width)-1)
+
+/*
  * Memory flags
  */
 #define MEMORY_PAGETABLE_4L	(1 << 0)
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -5719,7 +5719,7 @@ is_select_domain(unsigned int id)
 }
 
 int
-exclude_xen_user_domain(void)
+exclude_xen3_user_domain(void)
 {
 	int i;
 	unsigned int count_info, _domain;
@@ -5728,9 +5728,6 @@ exclude_xen_user_domain(void)
 	unsigned long long phys_start, phys_end;
 	unsigned long long pfn, pfn_end;
 	unsigned long long j, size;
-	struct timeval tv_start;
-
-	gettimeofday(&tv_start, NULL);
 
 	/*
 	 * NOTE: the first half of bitmap is not used for Xen extraction
@@ -5781,13 +5778,106 @@ exclude_xen_user_domain(void)
 		}
 	}
 
+	return TRUE;
+}
+
+int
+exclude_xen4_user_domain(void)
+{
+	int i;
+	unsigned long count_info;
+	unsigned int  _domain;
+	unsigned int num_pt_loads = get_num_pt_loads();
+	unsigned long page_info_addr;
+	unsigned long long phys_start, phys_end;
+	unsigned long long pfn, pfn_end;
+	unsigned long long j, size;
+
+	/*
+	 * NOTE: the first half of bitmap is not used for Xen extraction
+	 */
+	for (i = 0; get_pt_load(i, &phys_start, &phys_end, NULL, NULL); i++) {
+
+		print_progress(PROGRESS_XEN_DOMAIN, i, num_pt_loads);
+
+		pfn     = paddr_to_pfn(phys_start);
+		pfn_end = paddr_to_pfn(phys_end);
+		size    = pfn_end - pfn;
+
+		for (j = 0; pfn < pfn_end; pfn++, j++) {
+			print_progress(PROGRESS_XEN_DOMAIN, j + (size * i),
+					size * num_pt_loads);
+
+			page_info_addr = info->frame_table_vaddr + pfn * 
SIZE(page_info);
+			if (!readmem(VADDR_XEN,
+			      page_info_addr + OFFSET(page_info.count_info),
+		 	      &count_info, sizeof(count_info))) {
+				clear_bit_on_2nd_bitmap(pfn);
+				continue;	/* page_info may not exist */
+			}
+
+			/* always keep Xen heap pages */
+			if (count_info & PGC_xen_heap)
+				continue;
+
+			/* delete free, offlined and broken pages */
+			if (page_state_is(count_info, free) ||
+			    page_state_is(count_info, offlined) ||
+			    count_info & PGC_broken) {
+				clear_bit_on_2nd_bitmap(pfn);
+				continue;
+			}
+
+			/* keep inuse pages not allocated to any domain
+			 * this covers e.g. Xen static data
+			 */
+			if (! (count_info & PGC_allocated))
+				continue;
+
+			/* Need to check the domain
+			 * keep:
+			 *  - anonymous (_domain == 0), or
+			 *  - selected domain page
+			 */
+			if (!readmem(VADDR_XEN,
+			      page_info_addr + OFFSET(page_info._domain),
+			      &_domain, sizeof(_domain))) {
+				ERRMSG("Can't get page_info._domain.\n");
+				return FALSE;
+			}
+
+			if (_domain == 0)
+				continue;
+			if (is_select_domain(_domain))
+				continue;
+			clear_bit_on_2nd_bitmap(pfn);
+		}
+	}
+
+	return TRUE;
+}
+
+int
+exclude_xen_user_domain(void)
+{
+	struct timeval tv_start;
+	int ret;
+
+	gettimeofday(&tv_start, NULL);
+
+	if (info->xen_crash_info.com &&
+	    info->xen_crash_info.com->xen_major_version >= 4)
+		ret = exclude_xen4_user_domain();
+	else
+		ret = exclude_xen3_user_domain();
+
 	/*
 	 * print [100 %]
 	 */
-	print_progress(PROGRESS_XEN_DOMAIN, num_pt_loads, num_pt_loads);
+	print_progress(PROGRESS_XEN_DOMAIN, 1, 1);
 	print_execution_time(PROGRESS_XEN_DOMAIN, &tv_start);
 
-	return TRUE;
+	return ret;
 }
 
 int



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

             reply	other threads:[~2012-08-24 15:43 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-24 15:43 Petr Tesarik [this message]
2012-11-05  6:04 ` [PATCHv3 8/9] Add support for filtering out user pages under Xen4 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=201208241743.23829.ptesarik@suse.cz \
    --to=ptesarik@suse.cz \
    --cc=Norbert.Trapp@ts.fujitsu.com \
    --cc=kexec@lists.infradead.org \
    /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