WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 2/3] xen-balloon: Add interface to retrieve ballooned

To: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Subject: [Xen-devel] [PATCH 2/3] xen-balloon: Add interface to retrieve ballooned pages
From: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
Date: Wed, 9 Mar 2011 18:07:33 -0500
Cc: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx, Ian.Campbell@xxxxxxxxxx
Delivery-date: Wed, 09 Mar 2011 15:11:41 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1299712054-18104-1-git-send-email-dgdegra@xxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1299712054-18104-1-git-send-email-dgdegra@xxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Pages that have been ballooned are useful for other Xen drivers doing
grant table actions, because these pages have valid struct page/PFNs but
have no valid MFN so are available for remapping.

Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
---
 drivers/xen/balloon.c |   73 +++++++++++++++++++++++++++++++++++++++++++++----
 include/xen/balloon.h |    3 ++
 2 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index f2fa9ec..9c35cec 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -128,14 +128,17 @@ static void balloon_append(struct page *page)
 }
 
 /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
-static struct page *balloon_retrieve(void)
+static struct page *balloon_retrieve(bool prefer_highmem)
 {
        struct page *page;
 
        if (list_empty(&ballooned_pages))
                return NULL;
 
-       page = list_entry(ballooned_pages.next, struct page, lru);
+       if (prefer_highmem)
+               page = list_entry(ballooned_pages.prev, struct page, lru);
+       else
+               page = list_entry(ballooned_pages.next, struct page, lru);
        list_del(&page->lru);
 
        if (PageHighMem(page)) {
@@ -240,7 +243,7 @@ static enum bp_state increase_reservation(unsigned long 
nr_pages)
        }
 
        for (i = 0; i < rc; i++) {
-               page = balloon_retrieve();
+               page = balloon_retrieve(false);
                BUG_ON(page == NULL);
 
                pfn = page_to_pfn(page);
@@ -270,7 +273,7 @@ static enum bp_state increase_reservation(unsigned long 
nr_pages)
        return BP_DONE;
 }
 
-static enum bp_state decrease_reservation(unsigned long nr_pages)
+static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
 {
        enum bp_state state = BP_DONE;
        unsigned long  pfn, i;
@@ -286,7 +289,7 @@ static enum bp_state decrease_reservation(unsigned long 
nr_pages)
                nr_pages = ARRAY_SIZE(frame_list);
 
        for (i = 0; i < nr_pages; i++) {
-               if ((page = alloc_page(GFP_BALLOON)) == NULL) {
+               if ((page = alloc_page(gfp)) == NULL) {
                        pr_info("xen_balloon: %s: Cannot allocate memory\n", 
__func__);
                        nr_pages = i;
                        state = BP_EAGAIN;
@@ -348,7 +351,7 @@ static void balloon_process(struct work_struct *work)
                        state = increase_reservation(credit);
 
                if (credit < 0)
-                       state = decrease_reservation(-credit);
+                       state = decrease_reservation(-credit, GFP_BALLOON);
 
                state = update_schedule(state);
 
@@ -374,6 +377,64 @@ void balloon_set_new_target(unsigned long target)
 }
 EXPORT_SYMBOL_GPL(balloon_set_new_target);
 
+/**
+ * alloc_xenballooned_pages - get pages that have been ballooned out
+ * @nr_pages: Number of pages to get
+ * @pages: pages returned
+ * @return 0 on success, error otherwise
+ */
+int alloc_xenballooned_pages(int nr_pages, struct page** pages)
+{
+       int pgno = 0;
+       struct page* page;
+       mutex_lock(&balloon_mutex);
+       while (pgno < nr_pages) {
+               page = balloon_retrieve(true);
+               if (page) {
+                       pages[pgno++] = page;
+               } else {
+                       enum bp_state st;
+                       st = decrease_reservation(nr_pages - pgno, 
GFP_HIGHUSER);
+                       if (st != BP_DONE)
+                               goto out_undo;
+               }
+       }
+       mutex_unlock(&balloon_mutex);
+       return 0;
+ out_undo:
+       while (pgno)
+               balloon_append(pages[--pgno]);
+       /* Free the memory back to the kernel soon */
+       schedule_delayed_work(&balloon_worker, 0);
+       mutex_unlock(&balloon_mutex);
+       return -ENOMEM;
+}
+EXPORT_SYMBOL(alloc_xenballooned_pages);
+
+/**
+ * free_xenballooned_pages - return pages retrieved with get_ballooned_pages
+ * @nr_pages: Number of pages
+ * @pages: pages to return
+ */
+void free_xenballooned_pages(int nr_pages, struct page** pages)
+{
+       int i;
+
+       mutex_lock(&balloon_mutex);
+
+       for (i = 0; i < nr_pages; i++) {
+               if (pages[i])
+                       balloon_append(pages[i]);
+       }
+
+       /* The balloon may be too large now. Shrink it if needed. */
+       if (current_target() != balloon_stats.current_pages)
+               schedule_delayed_work(&balloon_worker, 0);
+
+       mutex_unlock(&balloon_mutex);
+}
+EXPORT_SYMBOL(free_xenballooned_pages);
+
 static int __init balloon_init(void)
 {
        unsigned long pfn, nr_pages, extra_pfn_end;
diff --git a/include/xen/balloon.h b/include/xen/balloon.h
index f72e479..a2b22f0 100644
--- a/include/xen/balloon.h
+++ b/include/xen/balloon.h
@@ -20,3 +20,6 @@ struct balloon_stats {
 extern struct balloon_stats balloon_stats;
 
 void balloon_set_new_target(unsigned long target);
+
+int alloc_xenballooned_pages(int nr_pages, struct page** pages);
+void free_xenballooned_pages(int nr_pages, struct page** pages);
-- 
1.7.3.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel