[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] xen/p2m: put reference for level 2 superpage
commit 3e2121ce479bfcf9ad887ac77f2aa648f027ee5e Author: Penny Zheng <Penny.Zheng@xxxxxxx> AuthorDate: Tue May 28 13:56:03 2024 +0100 Commit: Julien Grall <jgrall@xxxxxxxxxx> CommitDate: Fri Jun 14 10:45:55 2024 +0100 xen/p2m: put reference for level 2 superpage We are doing foreign memory mapping for static shared memory, and there is a great possibility that it could be super mapped. But today, p2m_put_l3_page could not handle superpages. This commits implements a new function p2m_put_l2_superpage to handle level 2 superpages, specifically for helping put extra references for foreign superpages. Modify relinquish_p2m_mapping as well to take into account preemption when we have a level-2 foreign mapping. Currently level 1 superpages are not handled because Xen is not preemptible and therefore some work is needed to handle such superpages, for which at some point Xen might end up freeing memory and therefore for such a big mapping it could end up in a very long operation. Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx> Signed-off-by: Luca Fancellu <luca.fancellu@xxxxxxx> Reviewed-by: Julien Grall <jgrall@xxxxxxxxxx> --- xen/arch/arm/mmu/p2m.c | 81 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/xen/arch/arm/mmu/p2m.c b/xen/arch/arm/mmu/p2m.c index 41fcca011c..1725cca649 100644 --- a/xen/arch/arm/mmu/p2m.c +++ b/xen/arch/arm/mmu/p2m.c @@ -753,34 +753,72 @@ static int p2m_mem_access_radix_set(struct p2m_domain *p2m, gfn_t gfn, return rc; } -/* - * Put any references on the single 4K page referenced by pte. - * TODO: Handle superpages, for now we only take special references for leaf - * pages (specifically foreign ones, which can't be super mapped today). - */ -static void p2m_put_l3_page(const lpae_t pte) +static void p2m_put_foreign_page(struct page_info *pg) { - mfn_t mfn = lpae_get_mfn(pte); - - ASSERT(p2m_is_valid(pte)); - /* - * TODO: Handle other p2m types - * * It's safe to do the put_page here because page_alloc will * flush the TLBs if the page is reallocated before the end of * this loop. */ - if ( p2m_is_foreign(pte.p2m.type) ) + put_page(pg); +} + +/* Put any references on the single 4K page referenced by mfn. */ +static void p2m_put_l3_page(mfn_t mfn, p2m_type_t type) +{ + /* TODO: Handle other p2m types */ + if ( p2m_is_foreign(type) ) { ASSERT(mfn_valid(mfn)); - put_page(mfn_to_page(mfn)); + p2m_put_foreign_page(mfn_to_page(mfn)); } /* Detect the xenheap page and mark the stored GFN as invalid. */ - else if ( p2m_is_ram(pte.p2m.type) && is_xen_heap_mfn(mfn) ) + else if ( p2m_is_ram(type) && is_xen_heap_mfn(mfn) ) page_set_xenheap_gfn(mfn_to_page(mfn), INVALID_GFN); } +/* Put any references on the superpage referenced by mfn. */ +static void p2m_put_l2_superpage(mfn_t mfn, p2m_type_t type) +{ + struct page_info *pg; + unsigned int i; + + /* + * TODO: Handle other p2m types, but be aware that any changes to handle + * different types should require an update on the relinquish code to handle + * preemption. + */ + if ( !p2m_is_foreign(type) ) + return; + + ASSERT(mfn_valid(mfn)); + + pg = mfn_to_page(mfn); + + for ( i = 0; i < XEN_PT_LPAE_ENTRIES; i++, pg++ ) + p2m_put_foreign_page(pg); +} + +/* Put any references on the page referenced by pte. */ +static void p2m_put_page(const lpae_t pte, unsigned int level) +{ + mfn_t mfn = lpae_get_mfn(pte); + + ASSERT(p2m_is_valid(pte)); + + /* + * TODO: Currently we don't handle level 1 super-page, Xen is not + * preemptible and therefore some work is needed to handle such + * superpages, for which at some point Xen might end up freeing memory + * and therefore for such a big mapping it could end up in a very long + * operation. + */ + if ( level == 2 ) + return p2m_put_l2_superpage(mfn, pte.p2m.type); + else if ( level == 3 ) + return p2m_put_l3_page(mfn, pte.p2m.type); +} + /* Free lpae sub-tree behind an entry */ static void p2m_free_entry(struct p2m_domain *p2m, lpae_t entry, unsigned int level) @@ -809,9 +847,9 @@ static void p2m_free_entry(struct p2m_domain *p2m, #endif p2m->stats.mappings[level]--; - /* Nothing to do if the entry is a super-page. */ - if ( level == 3 ) - p2m_put_l3_page(entry); + + p2m_put_page(entry, level); + return; } @@ -1558,9 +1596,12 @@ int relinquish_p2m_mapping(struct domain *d) count++; /* - * Arbitrarily preempt every 512 iterations. + * Arbitrarily preempt every 512 iterations or when we have a level-2 + * foreign mapping. */ - if ( !(count % 512) && hypercall_preempt_check() ) + if ( (!(count % 512) || + (p2m_is_foreign(t) && (order > XEN_PT_LEVEL_ORDER(2)))) && + hypercall_preempt_check() ) { rc = -ERESTART; break; -- generated by git-patchbot for /home/xen/git/xen.git#master
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |