xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Wei Liu <wei.liu2@citrix.com>
To: xen-devel@lists.xen.org
Cc: Wei Liu <wei.liu2@citrix.com>,
	ian.campbell@citrix.com, stefano.stabellini@eu.citrix.com,
	david.vrabel@citrix.com, boris.ostrovsky@oracle.com
Subject: [PATCH RFC 08/10] xen/balloon: implement migratepage
Date: Wed, 15 Oct 2014 16:54:17 +0100	[thread overview]
Message-ID: <1413388459-4663-9-git-send-email-wei.liu2@citrix.com> (raw)
In-Reply-To: <1413388459-4663-1-git-send-email-wei.liu2@citrix.com>

This patch replaces the xen_balloon_migratepage stub with actual
implementation.

It's implemented in two macro steps:
1. populate old page with machine page and remove it from balloon driver
2. give up machine page that backs new page and queue it to balloon
   driver

Old page is the page owned by balloon driver, new page is a page
isolated by core mm compaction thread.

The aforementioned steps swaps a ballooned out page with a usable page.
>From guest's point of view, it de-fragments physical address space.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
 drivers/xen/balloon.c |   94 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 92 insertions(+), 2 deletions(-)

diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 815e1d5..112190e 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -727,13 +727,103 @@ static struct notifier_block balloon_cpu_notifier = {
 
 static const struct address_space_operations xen_balloon_aops;
 #ifdef CONFIG_BALLOON_COMPACTION
+/*
+ * xen_balloon_migratepage - perform the balloon page migration on behalf of
+ *                           a compation thread.     (called under page lock)
+ * @mapping: the page->mapping which will be assigned to the new migrated page
+ * @newpage: page that will replace the isolated page after migration finishes
+ * @page   : the isolated (old) page that is about to be migrated to newpage.
+ * @mode   : compaction mode -- not used for balloon page migration.
+ *
+ * After a ballooned page gets isolated by compaction procedures, this
+ * is the function that performs the page migration on behalf of a
+ * compaction thread. The page migration for Xen balloon is done in
+ * these two macro steps:
+ *
+ *  A. back @page with machine page
+ *  B. release machine that backs @newpage
+ *
+ * Logically the above steps should work in reversed order (first B
+ * then A). But if we fail in A (in BA order) due to memory pressure
+ * in Xen we might not get back @newpage easily. With current order,
+ * we can safely return -EAGAIN if step A fails (either due to memory
+ * cap for guest or out of memory in hypervisor).
+ *
+ * This function preforms the balloon page migration task.
+ * Called through balloon_mapping->a_ops->migratepage
+ */
 static int xen_balloon_migratepage(struct address_space *mapping,
 				   struct page *newpage, struct page *page,
 				   enum migrate_mode mode)
 {
-	return -EAGAIN;
-}
+	struct xen_balloon *xb;
+	struct balloon_dev_info *info = balloon_page_device(page);
+	unsigned long flags;
+	unsigned long pfn;
+	xen_pfn_t frame;
+	int rc;
+
+	BUG_ON(!info);
+	BUG_ON(info->balloon_device != &xen_balloon);
+
+	xb = info->balloon_device;
+
+	/* Avoid contention if we're increasing / decreasing
+	 * reservation.
+	 */
+	if (!mutex_trylock(&xb->balloon_mutex))
+		return -EAGAIN;
+
+	kmap_flush_unused();
+
+	/*
+	 * Step A:
+	 * Back page with machine page
+	 */
+	frame = page_to_pfn(page);
+
+	rc = __memory_op_hypercall(XENMEM_populate_physmap, &frame, 1);
+	if (rc != 1) {
+		rc = -EAGAIN;
+		goto out;
+	}
+	/*
+	 * It's safe to delete page->lru here because this page is at
+	 * an isolated migration list, and this step is expected to happen here
+	 */
+	balloon_page_delete(page);
+
+	if (!xen_feature(XENFEAT_auto_translated_physmap))
+		__link_back_to_pagetable(page, frame,
+					 mfn_pte(frame, PAGE_KERNEL));
+
+	/*
+	 * Step B:
+	 * Give up newpage's backing machine page and add it to list
+	 */
+	pfn = page_to_pfn(newpage);
+	frame = pfn_to_mfn(pfn);
+	scrub_page(newpage);
 
+	if (!xen_feature(XENFEAT_auto_translated_physmap))
+		__replace_mapping_with_scratch_page(newpage);
+
+	rc = __memory_op_hypercall(XENMEM_decrease_reservation, &frame, 1);
+	BUG_ON(rc != 1);
+
+	spin_lock_irqsave(&info->pages_lock, flags);
+	balloon_page_insert(newpage, mapping, &info->pages);
+	info->isolated_pages--;
+	spin_unlock_irqrestore(&info->pages_lock, flags);
+
+	rc = MIGRATEPAGE_BALLOON_SUCCESS;
+
+	flush_tlb_all();
+out:
+	mutex_unlock(&xb->balloon_mutex);
+
+	return rc;
+}
 static const struct address_space_operations xen_balloon_aops = {
 	.migratepage = xen_balloon_migratepage,
 };
-- 
1.7.10.4

  parent reply	other threads:[~2014-10-15 15:54 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-15 15:54 [PATCH RFC 00/10] Xen balloon page compaction support Wei Liu
2014-10-15 15:54 ` [PATCH RFC 01/10] balloon_compaction: don't BUG() when it is not necessary Wei Liu
2014-10-15 15:54 ` [PATCH RFC 02/10] xen/balloon: fix code comment for free_xenballooned_pages Wei Liu
2014-10-15 15:54 ` [PATCH RFC 03/10] xen/balloon: consolidate data structures Wei Liu
2014-10-15 15:54 ` [PATCH RFC 04/10] xen/balloon: factor out function to update balloon stats Wei Liu
2014-10-15 15:54 ` [PATCH RFC 05/10] xen/balloon: rework increase_reservation Wei Liu
2014-10-15 15:54 ` [PATCH RFC 06/10] xen/balloon: make use of generic balloon driver Wei Liu
2014-10-15 15:54 ` [PATCH RFC 07/10] xen/balloon: factor out some helper functions Wei Liu
2014-10-15 15:54 ` Wei Liu [this message]
2014-10-15 16:16   ` [PATCH RFC 08/10] xen/balloon: implement migratepage David Vrabel
2014-10-16  9:28     ` Ian Campbell
2014-10-15 15:54 ` [PATCH RFC 09/10] balloon: BALLOON_COMPACTION now depends on XEN_BALLOON Wei Liu
2014-10-15 15:54 ` [PATCH RFC 10/10] XXX: balloon bitmap and sysrq key to dump bitmap Wei Liu
2014-10-15 16:25 ` [PATCH RFC 00/10] Xen balloon page compaction support David Vrabel
2014-10-15 16:30   ` Wei Liu
2014-10-16  9:31     ` David Vrabel
2014-10-15 16:54 ` Andrew Cooper
2014-10-15 17:00   ` Wei Liu
2014-10-15 17:14     ` Andrew Cooper
2014-10-16  9:12       ` Wei Liu
2014-10-16  9:26       ` Ian Campbell
2014-10-17 12:35         ` Andrew Cooper

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=1413388459-4663-9-git-send-email-wei.liu2@citrix.com \
    --to=wei.liu2@citrix.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=david.vrabel@citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xen.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;
as well as URLs for NNTP newsgroup(s).