[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 3/4] xen: separate a function merge_free_trunks from



This function will be used when scrubbing a page from idle vcpus.

Signed-off-by: Bob Liu <bob.liu@xxxxxxxxxx>
---
 xen/common/page_alloc.c |  137 +++++++++++++++++++++++++----------------------
 1 file changed, 74 insertions(+), 63 deletions(-)

diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index 723d273..5698596 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -827,73 +827,14 @@ static int reserve_offlined_page(struct page_info *head)
     return count;
 }
 
-/* Free 2^@order set of pages. */
-static void free_heap_pages(
+/* Caller must hold heap lock */
+static void merge_free_trunks(
     struct page_info *pg, unsigned int order, bool_t need_scrub)
 {
-    unsigned long mask, mfn = page_to_mfn(pg);
-    unsigned int i, node = phys_to_nid(page_to_maddr(pg)), tainted = 0;
+    unsigned long mask;
+    unsigned int node = phys_to_nid(page_to_maddr(pg));
     unsigned int zone = page_to_zone(pg);
 
-    ASSERT(order <= MAX_ORDER);
-    ASSERT(node >= 0);
-
-    spin_lock(&heap_lock);
-
-    for ( i = 0; i < (1 << order); i++ )
-    {
-        /*
-         * Cannot assume that count_info == 0, as there are some corner cases
-         * where it isn't the case and yet it isn't a bug:
-         *  1. page_get_owner() is NULL
-         *  2. page_get_owner() is a domain that was never accessible by
-         *     its domid (e.g., failed to fully construct the domain).
-         *  3. page was never addressable by the guest (e.g., it's an
-         *     auto-translate-physmap guest and the page was never included
-         *     in its pseudophysical address space).
-         * In all the above cases there can be no guest mappings of this page.
-         */
-        ASSERT(!page_state_is(&pg[i], offlined));
-        pg[i].count_info =
-            ((pg[i].count_info & PGC_broken) |
-             (page_state_is(&pg[i], offlining)
-              ? PGC_state_offlined : PGC_state_free));
-        if ( page_state_is(&pg[i], offlined) )
-            tainted = 1;
-
-        /* If a page has no owner it will need no safety TLB flush. */
-        pg[i].u.free.need_tlbflush = (page_get_owner(&pg[i]) != NULL);
-        if ( pg[i].u.free.need_tlbflush )
-            pg[i].tlbflush_timestamp = tlbflush_current_time();
-
-        /* This page is not a guest frame any more. */
-        page_set_owner(&pg[i], NULL); /* set_gpfn_from_mfn snoops pg owner */
-        set_gpfn_from_mfn(mfn + i, INVALID_M2P_ENTRY);
-    }
-
-    avail[node][zone] += 1 << order;
-    total_avail_pages += 1 << order;
-
-    if ( opt_tmem )
-        midsize_alloc_zone_pages = max(
-            midsize_alloc_zone_pages, total_avail_pages / MIDSIZE_ALLOC_FRAC);
-
-    if ( need_scrub )
-    {
-        /* Specail for tainted case */
-        if ( tainted )
-        {
-            for ( i = 0; i < (1 << order); i++ )
-                scrub_one_page(&pg[i]);
-            need_scrub = 0;
-        }
-        else
-        {
-            for ( i = 0; i < (1 << order); i++ )
-                pg[i].count_info |= PGC_need_scrub;
-        }
-    }
-
     /* Merge chunks as far as possible. */
     while ( order < MAX_ORDER )
     {
@@ -961,6 +902,76 @@ static void free_heap_pages(
     {
         page_list_add_tail(pg, &heap(node, zone, order));
     }
+}
+
+/* Free 2^@order set of pages. */
+static void free_heap_pages(
+    struct page_info *pg, unsigned int order, bool_t need_scrub)
+{
+    unsigned long mfn = page_to_mfn(pg);
+    unsigned int i, node = phys_to_nid(page_to_maddr(pg)), tainted = 0;
+    unsigned int zone = page_to_zone(pg);
+
+    ASSERT(order <= MAX_ORDER);
+    ASSERT(node >= 0);
+
+    spin_lock(&heap_lock);
+
+    for ( i = 0; i < (1 << order); i++ )
+    {
+        /*
+         * Cannot assume that count_info == 0, as there are some corner cases
+         * where it isn't the case and yet it isn't a bug:
+         *  1. page_get_owner() is NULL
+         *  2. page_get_owner() is a domain that was never accessible by
+         *     its domid (e.g., failed to fully construct the domain).
+         *  3. page was never addressable by the guest (e.g., it's an
+         *     auto-translate-physmap guest and the page was never included
+         *     in its pseudophysical address space).
+         * In all the above cases there can be no guest mappings of this page.
+         */
+        ASSERT(!page_state_is(&pg[i], offlined));
+        pg[i].count_info =
+            ((pg[i].count_info & PGC_broken) |
+             (page_state_is(&pg[i], offlining)
+              ? PGC_state_offlined : PGC_state_free));
+        if ( page_state_is(&pg[i], offlined) )
+            tainted = 1;
+
+        /* If a page has no owner it will need no safety TLB flush. */
+        pg[i].u.free.need_tlbflush = (page_get_owner(&pg[i]) != NULL);
+        if ( pg[i].u.free.need_tlbflush )
+            pg[i].tlbflush_timestamp = tlbflush_current_time();
+
+        /* This page is not a guest frame any more. */
+        page_set_owner(&pg[i], NULL); /* set_gpfn_from_mfn snoops pg owner */
+        set_gpfn_from_mfn(mfn + i, INVALID_M2P_ENTRY);
+    }
+
+    avail[node][zone] += 1 << order;
+    total_avail_pages += 1 << order;
+
+    if ( opt_tmem )
+        midsize_alloc_zone_pages = max(
+            midsize_alloc_zone_pages, total_avail_pages / MIDSIZE_ALLOC_FRAC);
+
+    if ( need_scrub )
+    {
+        /* Specail for tainted case */
+        if ( tainted )
+        {
+            for ( i = 0; i < (1 << order); i++ )
+                scrub_one_page(&pg[i]);
+            need_scrub = 0;
+        }
+        else
+        {
+            for ( i = 0; i < (1 << order); i++ )
+                pg[i].count_info |= PGC_need_scrub;
+        }
+    }
+
+    merge_free_trunks(pg, order, need_scrub);
 
     if ( tainted )
         reserve_offlined_page(pg);
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.