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

[Xen-ia64-devel] [PATCH 1/2] prevent soft lockup warning: xen part



This patch depends on the patch I sent it out to xen-devel.

# HG changeset patch
# User yamahata@xxxxxxxxxxxxx
# Date 1186647950 -32400
# Node ID f18667f3d03d79c75ae0fb1a313a10357510aca1
# Parent  68e56e0339b6bf42a694c2c435106b2a7bf286c3
prevent soft lockup when domain destroy. xen part.
Make domain destroy hypercall return error when necessary.
PATCHNAME: prevent_soft_lockup_xen_part

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>

diff -r 68e56e0339b6 -r f18667f3d03d xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Thu Aug 09 16:55:22 2007 +0900
+++ b/xen/arch/ia64/xen/domain.c        Thu Aug 09 17:25:50 2007 +0900
@@ -559,6 +559,7 @@ int arch_domain_create(struct domain *d)
                goto fail_nomem;
 
        memset(&d->arch.mm, 0, sizeof(d->arch.mm));
+       d->arch.mm_teardown_offset = 0;
 
        if ((d->arch.mm.pgd = pgd_alloc(&d->arch.mm)) == NULL)
            goto fail_nomem;
@@ -934,12 +935,15 @@ static void relinquish_memory(struct dom
 
 int domain_relinquish_resources(struct domain *d)
 {
+    int ret;
     /* Relinquish guest resources for VT-i domain. */
     if (d->vcpu[0] && VMX_DOMAIN(d->vcpu[0]))
            vmx_relinquish_guest_resources(d);
 
     /* Tear down shadow mode stuff. */
-    mm_teardown(d);
+    ret = mm_teardown(d);
+    if (ret != 0)
+        return ret;
 
     /* Relinquish every page of memory. */
     relinquish_memory(d, &d->xenpage_list);
diff -r 68e56e0339b6 -r f18667f3d03d xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Thu Aug 09 16:55:22 2007 +0900
+++ b/xen/arch/ia64/xen/mm.c    Thu Aug 09 17:25:50 2007 +0900
@@ -177,6 +177,7 @@
 #include <linux/efi.h>
 #include <xen/guest_access.h>
 #include <asm/page.h>
+#include <asm/event.h>
 #include <public/memory.h>
 
 static void domain_page_flush_and_put(struct domain* d, unsigned long mpaddr,
@@ -213,6 +214,18 @@ alloc_dom_xen_and_dom_io(void)
      */
     dom_io = alloc_domain(DOMID_IO);
     BUG_ON(dom_io == NULL);
+}
+
+static int
+mm_teardown_can_skip(struct domain* d, unsigned long offset)
+{
+    return d->arch.mm_teardown_offset > offset;
+}
+
+static void
+mm_teardown_update_offset(struct domain* d, unsigned long offset)
+{
+    d->arch.mm_teardown_offset = offset;
 }
 
 static void
@@ -252,46 +265,73 @@ mm_teardown_pte(struct domain* d, volati
     }
 }
 
-static void
+static int
 mm_teardown_pmd(struct domain* d, volatile pmd_t* pmd, unsigned long offset)
 {
     unsigned long i;
     volatile pte_t* pte = pte_offset_map(pmd, offset);
 
     for (i = 0; i < PTRS_PER_PTE; i++, pte++) {
-        if (!pte_present(*pte)) // acquire semantics
+        unsigned long cur_offset = offset + (i << PAGE_SHIFT);
+        if (mm_teardown_can_skip(d, cur_offset + PAGE_SIZE))
             continue;
-        mm_teardown_pte(d, pte, offset + (i << PAGE_SHIFT));
-    }
-}
-
-static void
+        if (!pte_present(*pte)) { // acquire semantics
+            mm_teardown_update_offset(d, cur_offset);
+            continue;
+        }
+        mm_teardown_update_offset(d, cur_offset);
+        mm_teardown_pte(d, pte, cur_offset);
+        if (hypercall_preempt_check())
+            return -EAGAIN;
+    }
+    return 0;
+}
+
+static int
 mm_teardown_pud(struct domain* d, volatile pud_t *pud, unsigned long offset)
 {
     unsigned long i;
     volatile pmd_t *pmd = pmd_offset(pud, offset);
 
     for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
-        if (!pmd_present(*pmd)) // acquire semantics
+        unsigned long cur_offset = offset + (i << PMD_SHIFT);
+        if (mm_teardown_can_skip(d, cur_offset + PMD_SIZE))
             continue;
-        mm_teardown_pmd(d, pmd, offset + (i << PMD_SHIFT));
-    }
-}
-
-static void
+        if (!pmd_present(*pmd)) { // acquire semantics
+            mm_teardown_update_offset(d, cur_offset);
+            continue;
+        }
+        if (mm_teardown_pmd(d, pmd, cur_offset))
+            return -EAGAIN;
+    }
+    return 0;
+}
+
+static int
 mm_teardown_pgd(struct domain* d, volatile pgd_t *pgd, unsigned long offset)
 {
     unsigned long i;
     volatile pud_t *pud = pud_offset(pgd, offset);
 
     for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
-        if (!pud_present(*pud)) // acquire semantics
+        unsigned long cur_offset = offset + (i << PUD_SHIFT);
+#ifndef __PAGETABLE_PUD_FOLDED
+        if (mm_teardown_can_skip(d, cur_offset + PUD_SIZE))
             continue;
-        mm_teardown_pud(d, pud, offset + (i << PUD_SHIFT));
-    }
-}
-
-void
+#endif
+        if (!pud_present(*pud)) { // acquire semantics
+#ifndef __PAGETABLE_PUD_FOLDED
+            mm_teardown_update_offset(d, cur_offset);
+#endif
+            continue;
+        }
+        if (mm_teardown_pud(d, pud, cur_offset))
+            return -EAGAIN;
+    }
+    return 0;
+}
+
+int
 mm_teardown(struct domain* d)
 {
     struct mm_struct* mm = &d->arch.mm;
@@ -299,14 +339,21 @@ mm_teardown(struct domain* d)
     volatile pgd_t* pgd;
 
     if (mm->pgd == NULL)
-        return;
+        return 0;
 
     pgd = pgd_offset(mm, 0);
     for (i = 0; i < PTRS_PER_PGD; i++, pgd++) {
-        if (!pgd_present(*pgd)) // acquire semantics
+        unsigned long cur_offset = i << PGDIR_SHIFT;
+        if (mm_teardown_can_skip(d, cur_offset + PGDIR_SIZE))
             continue;
-        mm_teardown_pgd(d, pgd, i << PGDIR_SHIFT);
-    }
+        if (!pgd_present(*pgd)) { // acquire semantics
+            mm_teardown_update_offset(d, cur_offset);
+            continue;
+        }
+        if (mm_teardown_pgd(d, pgd, cur_offset))
+            return -EAGAIN;
+    }
+    return 0;
 }
 
 static void
diff -r 68e56e0339b6 -r f18667f3d03d xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Thu Aug 09 16:55:22 2007 +0900
+++ b/xen/include/asm-ia64/domain.h     Thu Aug 09 17:25:50 2007 +0900
@@ -171,6 +171,9 @@ struct arch_domain {
 #ifdef CONFIG_XEN_IA64_TLB_TRACK
     struct tlb_track*   tlb_track;
 #endif
+
+    /* for domctl_destroy_domain continuation */
+    unsigned long mm_teardown_offset;
 };
 #define INT_ENABLE_OFFSET(v)             \
     (sizeof(vcpu_info_t) * (v)->vcpu_id + \
diff -r 68e56e0339b6 -r f18667f3d03d xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Thu Aug 09 16:55:22 2007 +0900
+++ b/xen/include/asm-ia64/mm.h Thu Aug 09 17:25:50 2007 +0900
@@ -417,7 +417,7 @@ extern int nr_swap_pages;
 extern int nr_swap_pages;
 
 extern void alloc_dom_xen_and_dom_io(void);
-extern void mm_teardown(struct domain* d);
+extern int mm_teardown(struct domain* d);
 extern void mm_final_teardown(struct domain* d);
 extern struct page_info * assign_new_domain_page(struct domain *d, unsigned 
long mpaddr);
 extern void assign_new_domain0_page(struct domain *d, unsigned long mpaddr);

-- 
yamahata

Attachment: 15711_f18667f3d03d_prevent_soft_lockup_xen_part.patch
Description: Text Data

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

 


Rackspace

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