[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


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: Olaf Hering <olaf@xxxxxxxxx>
  • Date: Tue, 02 Nov 2010 23:30:16 +0100
  • Delivery-date: Tue, 02 Nov 2010 15:38:50 -0700
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.