@@ -1376,6 +1376,53 @@ bool scrub_free_pages(void)
return node_to_scrub(false) != NUMA_NO_NODE;
}
+static void mark_page_free(struct page_info *pg, mfn_t mfn)
+{
+ ASSERT(mfn_x(mfn) == mfn_x(page_to_mfn(pg)));
+
+ /*
+ * 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.
+ */
+ switch ( pg->count_info & PGC_state )
+ {
+ case PGC_state_inuse:
+ BUG_ON(pg->count_info & PGC_broken);
+ pg->count_info = PGC_state_free;
+ break;
+
+ case PGC_state_offlining:
+ pg->count_info = (pg->count_info & PGC_broken) |
+ PGC_state_offlined;
+ tainted = 1;
+ break;
+
+ default:
+ printk(XENLOG_ERR
+ "pg MFN %"PRI_mfn" c=%#lx o=%u v=%#lx t=%#x\n",
+ mfn_x(mfn),
+ pg->count_info, pg->v.free.order,
+ pg->u.free.val, pg->tlbflush_timestamp);
+ BUG();
+ }
+
+ /* If a page has no owner it will need no safety TLB flush. */
+ pg->u.free.need_tlbflush = (page_get_owner(pg) != NULL);
+ if ( pg->u.free.need_tlbflush )
+ page_set_tlbflush_timestamp(pg);
+
+ /* This page is not a guest frame any more. */
+ page_set_owner(pg, NULL); /* set_gpfn_from_mfn snoops pg owner */
+ set_gpfn_from_mfn(mfn_x(mfn), INVALID_M2P_ENTRY);
+}
+
/* Free 2^@order set of pages. */
static void free_heap_pages(
struct page_info *pg, unsigned int order, bool need_scrub)
@@ -1392,47 +1439,7 @@ static void free_heap_pages(
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.
- */
- switch ( pg[i].count_info & PGC_state )
- {
- case PGC_state_inuse:
- BUG_ON(pg[i].count_info & PGC_broken);
- pg[i].count_info = PGC_state_free;
- break;
-
- case PGC_state_offlining:
- pg[i].count_info = (pg[i].count_info & PGC_broken) |
- PGC_state_offlined;
- tainted = 1;
- break;
-
- default:
- printk(XENLOG_ERR
- "pg[%u] MFN %"PRI_mfn" c=%#lx o=%u v=%#lx t=%#x\n",
- i, mfn_x(mfn) + i,
- pg[i].count_info, pg[i].v.free.order,
- pg[i].u.free.val, pg[i].tlbflush_timestamp);
- BUG();
- }
-
- /* 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 )
- page_set_tlbflush_timestamp(&pg[i]);
-
- /* 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_x(mfn) + i, INVALID_M2P_ENTRY);
+ mark_page_free(&pg[i], mfn_add(mfn, i));
if ( need_scrub )
{