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

[Xen-changelog] [xen-unstable] x86: No need to take full reference when doing mmu_update on a foreign



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1172751293 0
# Node ID 0de2f7d8d89f0bb134f60b5746ae7920503ff50d
# Parent  9d36026b1b431990163caf09da715cacdab7cae7
x86: No need to take full reference when doing mmu_update on a foreign
domain. Also fix a pre-existing race setting PGT_pinned versus
clearing it during domain_kill().
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/mm.c       |   19 +++++++++++--------
 xen/include/xen/sched.h |    9 +++++++--
 2 files changed, 18 insertions(+), 10 deletions(-)

diff -r 9d36026b1b43 -r 0de2f7d8d89f xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu Mar 01 11:38:55 2007 +0000
+++ b/xen/arch/x86/mm.c Thu Mar 01 12:14:53 2007 +0000
@@ -1853,7 +1853,7 @@ static void process_deferred_ops(void)
 
     if ( unlikely(info->foreign != NULL) )
     {
-        put_domain(info->foreign);
+        rcu_unlock_domain(info->foreign);
         info->foreign = NULL;
     }
 }
@@ -1885,8 +1885,7 @@ static int set_foreigndom(domid_t domid)
         switch ( domid )
         {
         case DOMID_IO:
-            get_knownalive_domain(dom_io);
-            info->foreign = dom_io;
+            info->foreign = rcu_lock_domain(dom_io);
             break;
         default:
             MEM_LOG("Dom %u cannot set foreign dom", d->domain_id);
@@ -1896,18 +1895,16 @@ static int set_foreigndom(domid_t domid)
     }
     else
     {
-        info->foreign = e = get_domain_by_id(domid);
+        info->foreign = e = rcu_lock_domain_by_id(domid);
         if ( e == NULL )
         {
             switch ( domid )
             {
             case DOMID_XEN:
-                get_knownalive_domain(dom_xen);
-                info->foreign = dom_xen;
+                info->foreign = rcu_lock_domain(dom_xen);
                 break;
             case DOMID_IO:
-                get_knownalive_domain(dom_io);
-                info->foreign = dom_io;
+                info->foreign = rcu_lock_domain(dom_io);
                 break;
             default:
                 MEM_LOG("Unknown domain '%u'", domid);
@@ -2043,6 +2040,12 @@ int do_mmuext_op(
             /* A page is dirtied when its pin status is set. */
             mark_dirty(d, mfn);
            
+            /* We can race domain destruction (domain_relinquish_resources). */
+            if ( unlikely(this_cpu(percpu_mm_info).foreign != NULL) &&
+                 test_bit(_DOMF_dying, &FOREIGNDOM->domain_flags) &&
+                 test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
+                put_page_and_type(page);
+
             break;
 
         case MMUEXT_UNPIN_TABLE:
diff -r 9d36026b1b43 -r 0de2f7d8d89f xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Thu Mar 01 11:38:55 2007 +0000
+++ b/xen/include/xen/sched.h   Thu Mar 01 12:14:53 2007 +0000
@@ -292,10 +292,15 @@ static inline void rcu_unlock_domain(str
     rcu_read_unlock(&domlist_read_lock);
 }
 
+static inline struct domain *rcu_lock_domain(struct domain *d)
+{
+    rcu_read_lock(d);
+    return d;
+}
+
 static inline struct domain *rcu_lock_current_domain(void)
 {
-    rcu_read_lock(&domlist_read_lock);
-    return current->domain;
+    return rcu_lock_domain(current->domain);
 }
 
 struct domain *get_domain_by_id(domid_t dom);

_______________________________________________
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®.