[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 3 of 3] RFC: xenpaging: use waitqueue in ept_get
# HG changeset patch # User Olaf Hering <olaf@xxxxxxxxx> # Date 1321996199 -3600 # Node ID 9d63ecd3969bb7a2e39841f6c859b4c23f750642 # Parent de6860cb9205b68d1287482288d1b7b9d0255609 RFC: xenpaging: use waitqueue in ept_get Signed-off-by: Olaf Hering <olaf@xxxxxxxxx> diff -r de6860cb9205 -r 9d63ecd3969b xen/arch/x86/mm/p2m-ept.c --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -505,7 +505,7 @@ out: } /* Read ept p2m entries */ -static mfn_t ept_get_entry(struct p2m_domain *p2m, +static unsigned long _ept_get_entry(struct p2m_domain *p2m, unsigned long gfn, p2m_type_t *t, p2m_access_t* a, p2m_query_t q, unsigned int *page_order) { @@ -516,7 +516,7 @@ static mfn_t ept_get_entry(struct p2m_do u32 index; int i; int ret = 0; - mfn_t mfn = _mfn(INVALID_MFN); + unsigned long mfn = INVALID_MFN; *t = p2m_mmio_dm; *a = p2m_access_n; @@ -582,17 +582,14 @@ static mfn_t ept_get_entry(struct p2m_do *t = ept_entry->sa_p2mt; *a = ept_entry->access; - mfn = _mfn(ept_entry->mfn); + mfn = ept_entry->mfn; if ( i ) { /* * We may meet super pages, and to split into 4k pages * to emulate p2m table */ - unsigned long split_mfn = mfn_x(mfn) + - (gfn_remainder & - ((1 << (i * EPT_TABLE_ORDER)) - 1)); - mfn = _mfn(split_mfn); + mfn += (gfn_remainder & ((1 << (i * EPT_TABLE_ORDER)) - 1)); } if ( page_order ) @@ -604,6 +601,41 @@ out: return mfn; } +static int +ept_get_entry_wait(unsigned long *mfn, int *populated, + struct p2m_domain *p2m, unsigned long gfn, + p2m_type_t *t, p2m_access_t *a, p2m_query_t q, + unsigned int *page_order) +{ + int ret = 1; + *mfn = _ept_get_entry(p2m, gfn, t, a, q, page_order); + + /* No further action in case of query */ + if ( q == p2m_query ) + goto done; + + /* Populate the page once in case of guest access, then go to sleep */ + if ( p2m_is_paging(*t) && current->domain == p2m->domain ) { + if ( *populated == 0 ) { + *populated = 1; + p2m_mem_paging_populate(p2m->domain, gfn); + } + ret = 0; + } +done: + return ret; +} +static mfn_t +ept_get_entry(struct p2m_domain *p2m, unsigned long gfn, + p2m_type_t *t, p2m_access_t *a, p2m_query_t q, + unsigned int *page_order) +{ + unsigned long mfn; + int populated = 0; + wait_event(p2m->wq, ept_get_entry_wait(&mfn, &populated, p2m, gfn, t, a, q, page_order)); + return _mfn(mfn); +} + /* WARNING: Only caller doesn't care about PoD pages. So this function will * always return 0 for PoD pages, not populate them. If that becomes necessary, * pass a p2m_query_t type along to distinguish. */ diff -r de6860cb9205 -r 9d63ecd3969b xen/arch/x86/mm/p2m.c --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -76,6 +76,7 @@ static void p2m_initialise(struct domain INIT_PAGE_LIST_HEAD(&p2m->pages); INIT_PAGE_LIST_HEAD(&p2m->pod.super); INIT_PAGE_LIST_HEAD(&p2m->pod.single); + init_waitqueue_head(&p2m->wq); p2m->domain = d; p2m->default_access = p2m_access_rwx; @@ -1072,6 +1073,8 @@ void p2m_mem_paging_resume(struct domain /* Unpause all vcpus that were paused because the ring was full */ wake_up(&d->mem_event->mem_paging.wq); + /* Unpause all vcpus that were paused because the gfn was paged */ + wake_up(&p2m->wq); } void p2m_mem_access_check(unsigned long gpa, bool_t gla_valid, unsigned long gla, diff -r de6860cb9205 -r 9d63ecd3969b xen/include/asm-x86/p2m.h --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -286,6 +286,7 @@ struct p2m_domain { unsigned reclaim_single; /* Last gpfn of a scan */ unsigned max_guest; /* gpfn of max guest demand-populate */ } pod; + struct waitqueue_head wq; }; /* get host p2m table */ _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |