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

[PATCH 2/2] xen/mm: reset PFN_ORDER for offlined buddy heads



Ensure offlined buddy head pages are annotated as order-0 pages.

When a buddy containing pages marked for offlining is processed,
reserve_offlined_page() rebuilds any surviving healthy buddies
and moves the offlined subpages onto the offlined lists.

If the buddy head itself is offlined it was previously left
annotated with the original buddy order even though it has
been split into a single page.

This has no functional impact as the order of an offlined
page is not used for any decision making and onlining, but
it is misleading when inspecting the page's metadata.

Reset PFN_ORDER(cur_head) to 0 for an offlined buddy head
when moving it to the offlined list so the page's stored
order reflects its actual size.

Also update the regression test to assert the consistent
behavior.

Signed-off-by: Bernhard Kaindl <bernhard.kaindl@xxxxxxxxxx>
---
 tools/tests/native/offline-head-order.c | 8 --------
 xen/common/page_alloc.c                 | 7 +++++++
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/tools/tests/native/offline-head-order.c 
b/tools/tests/native/offline-head-order.c
index 5c666a319523..5239fc34518f 100644
--- a/tools/tests/native/offline-head-order.c
+++ b/tools/tests/native/offline-head-order.c
@@ -40,9 +40,7 @@ static void test_offline_head_order(int start_mfn)
     ASSERT(status == PG_OFFLINE_STATUS_OFFLINED);
 
     /* Check the order of the offlined head page. */
-    EXPECT_FAIL_BEGIN(); /* PFN_ORDER(page) should 0, but is still 1 */
     ASSERT(PFN_ORDER(page) == 0);
-    EXPECT_FAIL_END(1);
 
     /*
      * Allocate the successor page of the offlined page. This prevents
@@ -52,12 +50,6 @@ static void test_offline_head_order(int start_mfn)
     ASSERT(pg == page + 1);
     ASSERT(FREE_PAGES == 0);
 
-    /*
-     * The order of the split head page is still 1. Online the page again to
-     * confirm that onlining it causes the order to be corrected to 0.
-     */
-    ASSERT(PFN_ORDER(page) == 1);
-
     /* Online the offlined former head page. */
     ASSERT(online_page(page_to_mfn(page), &status) == 0);
     ASSERT(status & PG_ONLINE_ONLINED);
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index dd0b7c67008d..1801afc96a0a 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -1485,6 +1485,13 @@ static int reserve_offlined_page(struct page_info *head)
         ASSERT(node_avail_pages[node] > 0);
         node_avail_pages[node]--;
 
+        /*
+         * All offlined pages are standalone pages: If this offlined page was
+         * the head of a higher-order buddy, we need to reset its order to 0:
+         */
+        if ( cur_head == head && head_order != 0 )
+            PFN_ORDER(cur_head) = 0;
+
         page_list_add_tail(cur_head,
                            test_bit(_PGC_broken, &cur_head->count_info) ?
                            &page_broken_list : &page_offlined_list);
-- 
2.39.5




 


Rackspace

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