[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 06/16] xenpaging: drop paged pages in guest_remove_page
Simply drop paged-pages in guest_remove_page(), and notify xenpaging to drop reference to the gfn. This version does not work for some reasons. The guest hangs after pages got dropped. Signed-off-by: Olaf Hering <olaf@xxxxxxxxx> --- tools/xenpaging/xenpaging.c | 10 ++++++++ xen/arch/x86/mm/p2m.c | 51 +++++++++++++++++++++++++++++++++-------- xen/common/memory.c | 8 ++++++ xen/include/asm-x86/p2m.h | 4 +++ xen/include/public/mem_event.h | 1 5 files changed, 65 insertions(+), 9 deletions(-) --- xen-unstable.hg-4.1.22344.orig/tools/xenpaging/xenpaging.c +++ xen-unstable.hg-4.1.22344/tools/xenpaging/xenpaging.c @@ -586,6 +586,15 @@ int main(int argc, char *argv[]) goto out; } + if ( req.flags & MEM_EVENT_FLAG_DROP_PAGE ) + { + DPRINTF("Dropping page %"PRIx64" p2m %x\n", req.gfn, req.p2mt); + + /* Notify policy of page being dropped */ + policy_notify_paged_in(paging->mem_event.domain_id, req.gfn); + } + else + { /* Populate the page */ rc = xenpaging_populate_page(xch, paging, &req.gfn, fd, i); if ( rc != 0 ) @@ -606,6 +615,7 @@ int main(int argc, char *argv[]) ERROR("Error resuming page"); goto out; } + } /* Evict a new page to replace the one we just paged in */ evict_victim(xch, paging, domain_id, &victims[i], fd, i); --- xen-unstable.hg-4.1.22344.orig/xen/arch/x86/mm/p2m.c +++ xen-unstable.hg-4.1.22344/xen/arch/x86/mm/p2m.c @@ -1984,11 +1984,11 @@ static void audit_p2m(struct p2m_domain { mpbad++; P2M_PRINTK("map mismatch mfn %#lx -> gfn %#lx -> mfn %#lx" - " (-> gfn %#lx)\n", + " (-> gfn %#lx) p2mt %x\n", mfn, gfn, mfn_x(p2mfn), (mfn_valid(p2mfn) ? get_gpfn_from_mfn(mfn_x(p2mfn)) - : -1u)); + : -1u), type); /* This m2p entry is stale: the domain has another frame in * this physical slot. No great disaster, but for neatness, * blow away the m2p entry. */ @@ -2001,12 +2001,12 @@ static void audit_p2m(struct p2m_domain if ( lp2mfn != mfn_x(p2mfn) ) { P2M_PRINTK("linear mismatch gfn %#lx -> mfn %#lx " - "(!= mfn %#lx)\n", gfn, lp2mfn, mfn_x(p2mfn)); + "(!= mfn %#lx) p2mt %x\n", gfn, lp2mfn, mfn_x(p2mfn), type); } } // P2M_PRINTK("OK: mfn=%#lx, gfn=%#lx, p2mfn=%#lx, lp2mfn=%#lx\n", - // mfn, gfn, p2mfn, lp2mfn); + // mfn, gfn, mfn_x(p2mfn), lp2mfn); } spin_unlock(&d->page_alloc_lock); @@ -2132,11 +2132,9 @@ static void audit_p2m(struct p2m_domain !p2m_is_shared(type) ) { pmbad++; - printk("mismatch: gfn %#lx -> mfn %#lx" - " -> gfn %#lx\n", gfn, mfn, m2pfn); P2M_PRINTK("mismatch: gfn %#lx -> mfn %#lx" - " -> gfn %#lx\n", gfn, mfn, m2pfn); - BUG(); + " -> gfn %#lx (p2mt %x)\n", gfn, mfn, m2pfn, type); + // BUG(); } } unmap_domain_page(l1e); @@ -2168,7 +2166,7 @@ static void audit_p2m(struct p2m_domain //P2M_PRINTK("p2m audit complete\n"); //if ( orphans_i | orphans_d | mpbad | pmbad ) // P2M_PRINTK("p2m audit found %lu orphans (%lu inval %lu debug)\n", - // orphans_i + orphans_d, orphans_i, orphans_d, + // orphans_i + orphans_d, orphans_i, orphans_d); if ( mpbad | pmbad ) P2M_PRINTK("p2m audit found %lu odd p2m, %lu bad m2p entries\n", pmbad, mpbad); @@ -2195,6 +2193,8 @@ p2m_remove_page(struct p2m_domain *p2m, P2M_DEBUG("removing gfn=%#lx mfn=%#lx\n", gfn, mfn); + if (mfn_valid(_mfn(mfn))) + { for ( i = 0; i < (1UL << page_order); i++ ) { mfn_return = p2m->get_entry(p2m, gfn + i, &t, p2m_query); @@ -2203,6 +2203,9 @@ p2m_remove_page(struct p2m_domain *p2m, ASSERT( !p2m_is_valid(t) || mfn + i == mfn_x(mfn_return) ); } set_p2m_entry(p2m, gfn, _mfn(INVALID_MFN), page_order, p2m_invalid); + } + else + P2M_DEBUG("set_p2m_entry %x\n", set_p2m_entry(p2m, gfn, _mfn(INVALID_MFN), page_order, p2m_invalid)); } void @@ -2751,6 +2754,36 @@ int p2m_mem_paging_evict(struct p2m_doma return 0; } +void p2m_mem_paging_drop_page(struct p2m_domain *p2m, unsigned long gfn) +{ + struct vcpu *v = current; + mem_event_request_t req; + p2m_type_t p2mt; + struct domain *d = p2m->domain; + + memset(&req, 0, sizeof(req)); + + /* Check that there's space on the ring for this request */ + if ( mem_event_check_ring(d) ) + return; + + gfn_to_mfn(p2m, gfn, &p2mt); + /* Pause domain */ + if ( 0 && v->domain->domain_id == d->domain_id ) + { + vcpu_pause_nosync(v); + req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED; + } + + /* Send request to pager */ + req.flags |= MEM_EVENT_FLAG_DROP_PAGE; + req.gfn = gfn; + req.p2mt = p2mt; + req.vcpu_id = v->vcpu_id; + + mem_event_put_request(d, &req); +} + void p2m_mem_paging_populate(struct p2m_domain *p2m, unsigned long gfn) { struct vcpu *v = current; --- xen-unstable.hg-4.1.22344.orig/xen/common/memory.c +++ xen-unstable.hg-4.1.22344/xen/common/memory.c @@ -162,6 +162,14 @@ int guest_remove_page(struct domain *d, #ifdef CONFIG_X86 mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(d), gmfn, &p2mt)); + if ( unlikely(p2m_is_paging(p2mt)) ) + { + gdprintk(XENLOG_INFO, "Domain %u invalidate paged gfn %lx/%x\n", + d->domain_id, gmfn, p2mt); + guest_physmap_remove_page(d, gmfn, mfn, 0); + p2m_mem_paging_drop_page(p2m_get_hostp2m(d), gmfn); + return 1; + } #else mfn = gmfn_to_mfn(d, gmfn); #endif --- xen-unstable.hg-4.1.22344.orig/xen/include/asm-x86/p2m.h +++ xen-unstable.hg-4.1.22344/xen/include/asm-x86/p2m.h @@ -480,6 +480,8 @@ int set_shared_p2m_entry(struct p2m_doma int p2m_mem_paging_nominate(struct p2m_domain *p2m, unsigned long gfn); /* Evict a frame */ int p2m_mem_paging_evict(struct p2m_domain *p2m, unsigned long gfn); +/* Tell xenpaging to drop a paged out frame */ +void p2m_mem_paging_drop_page(struct p2m_domain *p2m, unsigned long gfn); /* Start populating a paged out frame */ void p2m_mem_paging_populate(struct p2m_domain *p2m, unsigned long gfn); /* Prepare the p2m for paging a frame in */ @@ -487,6 +489,8 @@ int p2m_mem_paging_prep(struct p2m_domai /* Resume normal operation (in case a domain was paused) */ void p2m_mem_paging_resume(struct p2m_domain *p2m); #else +static inline void p2m_mem_paging_drop_page(struct p2m_domain *p2m, unsigned long gfn) +{ } static inline void p2m_mem_paging_populate(struct p2m_domain *p2m, unsigned long gfn) { } #endif --- xen-unstable.hg-4.1.22344.orig/xen/include/public/mem_event.h +++ xen-unstable.hg-4.1.22344/xen/include/public/mem_event.h @@ -37,6 +37,7 @@ #define MEM_EVENT_FLAG_VCPU_PAUSED (1 << 0) #define MEM_EVENT_FLAG_DOM_PAUSED (1 << 1) #define MEM_EVENT_FLAG_OUT_OF_MEM (1 << 2) +#define MEM_EVENT_FLAG_DROP_PAGE (1 << 3) typedef struct mem_event_shared_page { _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |