[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/2] x86/ept: batch PML p2m type-changes into single locked region



The current p2m type-change loop in ept_vcpu_flush_pml_buffer() relies on
each call to p2m_change_type_one() taking the p2m lock, doing the change
and then dropping the lock and flushing the p2m.  Instead take the p2m lock
outside of the loop, so that calls to gfn_{,un}lock() inside
p2m_change_type_one() just take the p2m lock recursively, and more
importantly, the flush is deferred until the p2m is unlocked in
ept_vcpu_flush_pml_buffer().

No functional change intended in the end result of
ept_vcpu_flush_pml_buffer(), however a possibly noticeable performance
improvement is expected.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
 xen/arch/x86/mm/p2m-ept.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index 015911ba6c80..62fc8e50689f 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -1375,6 +1375,8 @@ static void cf_check ept_flush_pml_buffers(struct 
p2m_domain *p2m)
 
 void ept_vcpu_flush_pml_buffer(struct vcpu *v)
 {
+    struct domain *d = v->domain;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
     uint64_t *pml_buf;
     unsigned long pml_idx;
 
@@ -1401,6 +1403,12 @@ void ept_vcpu_flush_pml_buffer(struct vcpu *v)
     else
         pml_idx++;
 
+    /*
+     * Take the lock outside of the loop, so all the type changes are done
+     * inside of the same locked region and the EPT flush is deferred until the
+     * end of the loop.
+     */
+    p2m_lock(p2m);
     for ( ; pml_idx < NR_PML_ENTRIES; pml_idx++ )
     {
         unsigned long gfn = pml_buf[pml_idx] >> PAGE_SHIFT;
@@ -1413,11 +1421,12 @@ void ept_vcpu_flush_pml_buffer(struct vcpu *v)
          * are very rare, and additional cost is negligible, but a missing mark
          * is extremely difficult to debug.
          */
-        p2m_change_type_one(v->domain, gfn, p2m_ram_logdirty, p2m_ram_rw);
+        p2m_change_type_one(d, gfn, p2m_ram_logdirty, p2m_ram_rw);
 
         /* HVM guest: pfn == gfn */
-        paging_mark_pfn_dirty(v->domain, _pfn(gfn));
+        paging_mark_pfn_dirty(d, _pfn(gfn));
     }
+    p2m_unlock(p2m);
 
     unmap_domain_page(pml_buf);
 
-- 
2.49.0




 


Rackspace

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