|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |