[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC XEN PATCH v3 27/39] xen/pmem: release PMEM pages on HVM domain destruction
A new step RELMEM_pmem is added and taken before RELMEM_xen to release all PMEM pages mapped to a HVM domain. Signed-off-by: Haozhong Zhang <haozhong.zhang@xxxxxxxxx> --- Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Cc: George Dunlap <George.Dunlap@xxxxxxxxxxxxx> --- xen/arch/x86/domain.c | 32 ++++++++++++++++++++++++++++---- xen/arch/x86/mm.c | 9 +++++++-- xen/common/pmem.c | 10 ++++++++++ xen/include/asm-x86/domain.h | 1 + xen/include/xen/pmem.h | 6 ++++++ 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index dbddc536d3..1c4e788780 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1755,11 +1755,15 @@ static int relinquish_memory( { struct page_info *page; unsigned long x, y; + bool is_pmem_list = (list == &d->pmem_page_list); int ret = 0; /* Use a recursive lock, as we may enter 'free_domheap_page'. */ spin_lock_recursive(&d->page_alloc_lock); + if ( is_pmem_list ) + spin_lock(&d->pmem_lock); + while ( (page = page_list_remove_head(list)) ) { /* Grab a reference to the page so it won't disappear from under us. */ @@ -1841,8 +1845,9 @@ static int relinquish_memory( } } - /* Put the page on the list and /then/ potentially free it. */ - page_list_add_tail(page, &d->arch.relmem_list); + if ( !is_pmem_list ) + /* Put the page on the list and /then/ potentially free it. */ + page_list_add_tail(page, &d->arch.relmem_list); put_page(page); if ( hypercall_preempt_check() ) @@ -1852,10 +1857,13 @@ static int relinquish_memory( } } - /* list is empty at this point. */ - page_list_move(list, &d->arch.relmem_list); + if ( !is_pmem_list ) + /* list is empty at this point. */ + page_list_move(list, &d->arch.relmem_list); out: + if ( is_pmem_list ) + spin_unlock(&d->pmem_lock); spin_unlock_recursive(&d->page_alloc_lock); return ret; } @@ -1922,13 +1930,29 @@ int domain_relinquish_resources(struct domain *d) return ret; } +#ifndef CONFIG_NVDIMM_PMEM d->arch.relmem = RELMEM_xen; +#else + d->arch.relmem = RELMEM_pmem; +#endif spin_lock(&d->page_alloc_lock); page_list_splice(&d->arch.relmem_list, &d->page_list); INIT_PAGE_LIST_HEAD(&d->arch.relmem_list); spin_unlock(&d->page_alloc_lock); +#ifdef CONFIG_NVDIMM_PMEM + /* Fallthrough. Relinquish every page of PMEM. */ + case RELMEM_pmem: + if ( is_hvm_domain(d) ) + { + ret = relinquish_memory(d, &d->pmem_page_list, ~0UL); + if ( ret ) + return ret; + } + d->arch.relmem = RELMEM_xen; +#endif + /* Fallthrough. Relinquish every page of memory. */ case RELMEM_xen: ret = relinquish_memory(d, &d->xenpage_list, ~0UL); diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 93ccf198c9..26f9e5a13e 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -106,6 +106,7 @@ #include <xen/efi.h> #include <xen/grant_table.h> #include <xen/hypercall.h> +#include <xen/pmem.h> #include <asm/paging.h> #include <asm/shadow.h> #include <asm/page.h> @@ -2341,8 +2342,12 @@ void put_page(struct page_info *page) if ( unlikely((nx & PGC_count_mask) == 0) ) { - if ( !is_pmem_page(page) /* PMEM page is not allocated from Xen heap. */ - && cleanup_page_cacheattr(page) == 0 ) +#ifdef CONFIG_NVDIMM_PMEM + if ( is_pmem_page(page) ) + pmem_page_cleanup(page); + else +#endif + if ( cleanup_page_cacheattr(page) == 0 ) free_domheap_page(page); else gdprintk(XENLOG_WARNING, diff --git a/xen/common/pmem.c b/xen/common/pmem.c index 2f9ad64a26..8b9378dce6 100644 --- a/xen/common/pmem.c +++ b/xen/common/pmem.c @@ -741,6 +741,16 @@ int pmem_populate(struct xen_pmem_map_args *args) return rc; } +void pmem_page_cleanup(struct page_info *page) +{ + ASSERT(is_pmem_page(page)); + ASSERT((page->count_info & PGC_count_mask) == 0); + + page->count_info = PGC_pmem_page | PGC_state_free; + page_set_owner(page, NULL); + set_gpfn_from_mfn(page_to_mfn(page), INVALID_M2P_ENTRY); +} + int __init pmem_dom0_setup_permission(struct domain *d) { struct list_head *cur; diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index fb8bf17458..8322546b5d 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -303,6 +303,7 @@ struct arch_domain enum { RELMEM_not_started, RELMEM_shared, + RELMEM_pmem, RELMEM_xen, RELMEM_l4, RELMEM_l3, diff --git a/xen/include/xen/pmem.h b/xen/include/xen/pmem.h index 2dab90530b..dfbc412065 100644 --- a/xen/include/xen/pmem.h +++ b/xen/include/xen/pmem.h @@ -21,6 +21,7 @@ #ifdef CONFIG_NVDIMM_PMEM #include <public/sysctl.h> +#include <xen/mm.h> #include <xen/types.h> int pmem_register(unsigned long smfn, unsigned long emfn, unsigned int pxm); @@ -46,6 +47,7 @@ struct xen_pmem_map_args { }; int pmem_populate(struct xen_pmem_map_args *args); +void pmem_page_cleanup(struct page_info *page); #else /* !CONFIG_X86 */ @@ -64,6 +66,10 @@ static inline int pmem_populate(...) return -ENOSYS; } +static inline void pmem_page_cleanup(...) +{ +} + #endif /* CONFIG_X86 */ #endif /* CONFIG_NVDIMM_PMEM */ -- 2.14.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |