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

[Xen-devel] [PATCH] x86: fix domain cleanup



The preemptable page type handling changes modified free_page_type()
behavior without adjusting the call site in relinquish_memory(): Any
type reference left pending when leaving hypercall handlers is
associated with a page reference, and when successful free_page_type()
decrements the type refcount - hence relinquish_memory() must now also
drop the page reference.

Also, the recursion avoidance during domain shutdown somehow (probably
by me when I merged the patch up to a newer snapshot) got screwed up:
The avoidance logic in mm.c should short circuit levels below the top
one currently being processed, rather than the top one itself.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

Index: 2008-10-27/xen/arch/x86/domain.c
===================================================================
--- 2008-10-27.orig/xen/arch/x86/domain.c       2008-10-24 11:21:38.000000000 
+0200
+++ 2008-10-27/xen/arch/x86/domain.c    2008-10-27 11:11:36.000000000 +0100
@@ -1687,6 +1687,7 @@ static int relinquish_memory(
             {
                 if ( free_page_type(page, x, 0) != 0 )
                     BUG();
+                put_page(page);
                 break;
             }
         }
Index: 2008-10-27/xen/arch/x86/mm.c
===================================================================
--- 2008-10-27.orig/xen/arch/x86/mm.c   2008-10-17 08:29:02.000000000 +0200
+++ 2008-10-27/xen/arch/x86/mm.c        2008-10-27 11:11:36.000000000 +0100
@@ -1343,7 +1343,7 @@ static void free_l1_table(struct page_in
 
 static int free_l2_table(struct page_info *page, int preemptible)
 {
-#ifdef CONFIG_COMPAT
+#if defined(CONFIG_COMPAT) || defined(DOMAIN_DESTRUCT_AVOID_RECURSION)
     struct domain *d = page_get_owner(page);
 #endif
     unsigned long pfn = page_to_mfn(page);
@@ -1351,6 +1351,11 @@ static int free_l2_table(struct page_inf
     unsigned int  i = page->nr_validated_ptes - 1;
     int err = 0;
 
+#ifdef DOMAIN_DESTRUCT_AVOID_RECURSION
+    if ( d->arch.relmem == RELMEM_l3 )
+        return 0;
+#endif
+
     pl2e = map_domain_page(pfn);
 
     ASSERT(page->nr_validated_ptes);
@@ -1381,7 +1386,7 @@ static int free_l3_table(struct page_inf
     int rc = 0;
 
 #ifdef DOMAIN_DESTRUCT_AVOID_RECURSION
-    if ( d->arch.relmem == RELMEM_l3 )
+    if ( d->arch.relmem == RELMEM_l4 )
         return 0;
 #endif
 
@@ -1424,11 +1429,6 @@ static int free_l4_table(struct page_inf
     unsigned int  i = page->nr_validated_ptes - !page->partial_pte;
     int rc = 0;
 
-#ifdef DOMAIN_DESTRUCT_AVOID_RECURSION
-    if ( d->arch.relmem == RELMEM_l4 )
-        return 0;
-#endif
-
     do {
         if ( is_guest_l4_slot(d, i) )
             rc = put_page_from_l4e(pl4e[i], pfn, preemptible);




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