File 18741-x86-dom-cleanup-no-hack.patch of Package xen

# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1225377468 0
# Node ID 9e5cf6778a6d1057900c3709f544ac176ddfab67
# Parent  112e81ae5824e213b181a65f944b729ba270d658
x86: eliminate domain cleanup hack in favor of using the preemptable
flavors of the respective functions.

Signed-off-by: Jan Beulich <jbeulich@novell.com>

--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1639,32 +1639,23 @@ static int relinquish_memory(
         }
 
         if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
-            put_page_and_type(page);
+            ret = put_page_and_type_preemptible(page, 1);
+        switch ( ret )
+        {
+        case 0:
+            break;
+        case -EAGAIN:
+        case -EINTR:
+            set_bit(_PGT_pinned, &page->u.inuse.type_info);
+            put_page(page);
+            goto out;
+        default:
+            BUG();
+        }
 
         if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
             put_page(page);
 
-#ifdef DOMAIN_DESTRUCT_AVOID_RECURSION
-        /*
-         * Forcibly drop reference counts of page tables above top most (which
-         * were skipped to prevent long latencies due to deep recursion - see
-         * the special treatment in free_lX_table()).
-         */
-        y = page->u.inuse.type_info;
-        if ( (type < PGT_root_page_table) &&
-             unlikely(((y + PGT_type_mask) &
-                       (PGT_type_mask|PGT_validated)) == type) )
-        {
-            BUG_ON((y & PGT_count_mask) >=
-                   (page->count_info & PGC_count_mask));
-            while ( y & PGT_count_mask )
-            {
-                put_page_and_type(page);
-                y = page->u.inuse.type_info;
-            }
-        }
-#endif
-
         /*
          * Forcibly invalidate top-most, still valid page tables at this point
          * to break circular 'linear page table' references as well as clean up
@@ -1685,8 +1676,23 @@ static int relinquish_memory(
                         x & ~(PGT_validated|PGT_partial));
             if ( likely(y == x) )
             {
-                if ( free_page_type(page, x, 0) != 0 )
+                /* No need for atomic update of type_info here: noone else updates it. */
+                switch ( ret = free_page_type(page, x, 1) )
+                {
+                case 0:
+                    break;
+                case -EINTR:
+                    page->u.inuse.type_info |= PGT_validated;
+                    put_page(page);
+                    ret = -EAGAIN;
+                    goto out;
+                case -EAGAIN:
+                    page->u.inuse.type_info |= PGT_partial;
+                    put_page(page);
+                    goto out;
+                default:
                     BUG();
+                }
                 if ( x & PGT_partial )
                     page->u.inuse.type_info--;
                 break;
@@ -1833,11 +1839,6 @@ int domain_relinquish_resources(struct d
         /* fallthrough */
 
     case RELMEM_done:
-#ifdef DOMAIN_DESTRUCT_AVOID_RECURSION
-        ret = relinquish_memory(d, &d->page_list, PGT_l1_page_table);
-        if ( ret )
-            return ret;
-#endif
         break;
 
     default:
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -1343,7 +1343,7 @@ static void free_l1_table(struct page_in
 
 static int free_l2_table(struct page_info *page, int preemptible)
 {
-#if defined(CONFIG_COMPAT) || defined(DOMAIN_DESTRUCT_AVOID_RECURSION)
+#ifdef CONFIG_COMPAT
     struct domain *d = page_get_owner(page);
 #endif
     unsigned long pfn = page_to_mfn(page);
@@ -1351,11 +1351,6 @@ 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);
@@ -1385,11 +1380,6 @@ static int free_l3_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
-
     pl3e = map_domain_page(pfn);
 
     do {
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -41,14 +41,6 @@
 #define CONFIG_HOTPLUG 1
 #define CONFIG_HOTPLUG_CPU 1
 
-/*
- * Avoid deep recursion when tearing down pagetables during domain destruction,
- * causing dom0 to become unresponsive and Xen to miss time-critical softirq
- * deadlines. This will ultimately be replaced by built-in preemptibility of
- * get_page_type().
- */
-#define DOMAIN_DESTRUCT_AVOID_RECURSION 1
-
 #define HZ 100
 
 #define OPT_CONSOLE_STR "vga"
openSUSE Build Service is sponsored by