[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


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: Olaf Hering <olaf@xxxxxxxxx>
  • Date: Tue, 22 Nov 2011 22:13:25 +0100
  • Delivery-date: Tue, 22 Nov 2011 21:14:31 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

# 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


 


Rackspace

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