mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
xen: introduce mark_page_free
This commit defines a new helper mark_page_free to extract common code, like following the same cache/TLB coherency policy, between free_heap_pages and the new function free_staticmem_pages, which will be introduced later. The PDX compression makes that conversion between the MFN and the page can be potentially non-trivial. As the function is internal, pass the MFN and the page. They are both expected to match. Signed-off-by: Penny Zheng <penny.zheng@arm.com> Acked-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Julien Grall <jgrall@amazon.com>
This commit is contained in:
1 parent
41c031ff43
commit
540a637c34
1 file changed
+48
-41
+48
-41
@@ -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 )
|
||||
{
|
||||
|
||||