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

[Xen-changelog] [xen-4.0-testing] x86: Retry do_mmu_update() a few times when called on a pte whose type is in flux.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1285010457 -3600
# Node ID 21e0441e896dc3bd6f7f35a1a8181a5c62b7940e
# Parent  b369366c533f22fdbf7a132d4c9ee618827fa2fe
x86: Retry do_mmu_update() a few times when called on a pte whose type is in 
flux.

This can really happen -- all our PV Linux kernels have a race
between vmalloc_sync_all() and pgdir pinning/unpinning. The former is
protected by pgd_lock while the latter by mm->page_table_lock. Hence
they can happen concurrently, and vmalloc_sync_all() can attempt to
set_pmd() on a page directory which is in the process of being
pinned. This can confuse the hypervisor which may see a type change,
and hence fail do_mmu_update(). Until this patch. :-)

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
xen-unstable changeset:   22186:7167d6dd5c7c
xen-unstable date:        Mon Sep 20 20:11:43 2010 +0100
---
 xen/arch/x86/mm.c |    7 +++++++
 1 files changed, 7 insertions(+)

diff -r b369366c533f -r 21e0441e896d xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Sep 20 20:20:28 2010 +0100
+++ b/xen/arch/x86/mm.c Mon Sep 20 20:20:57 2010 +0100
@@ -3107,6 +3107,7 @@ int do_mmu_update(
         case MMU_NORMAL_PT_UPDATE:
         case MMU_PT_UPDATE_PRESERVE_AD:
         {
+            unsigned retries = 0;
             p2m_type_t p2mt;
 
             rc = xsm_mmu_normal_update(d, pg_owner, req.val);
@@ -3138,6 +3139,7 @@ int do_mmu_update(
                           (unsigned long)(req.ptr & ~PAGE_MASK));
             page = mfn_to_page(mfn);
 
+        retry:
             if ( page_lock(page) )
             {
                 switch ( page->u.inuse.type_info & PGT_type_mask )
@@ -3291,6 +3293,11 @@ int do_mmu_update(
                 okay = paging_write_guest_entry(
                     v, va, req.val, _mfn(mfn));
                 put_page_type(page);
+            }
+            else if ( retries++ < 5 )
+            {
+                /* Page type can be in flux, so we retry a few times. */
+                goto retry;
             }
 
             unmap_domain_page_with_cache(va, &mapcache);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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