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

[Xen-changelog] Fix domain shutdown so that the new status, and notification to domain0,



ChangeSet 1.1628, 2005/06/01 15:44:07+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Fix domain shutdown so that the new status, and notification to domain0,
        occur *after* the domain is fully descheduled and its execution state
        synchronised.
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c |    5 
 tools/libxc/xc_domain.c                                      |    7 
 xen/arch/ia64/xenmisc.c                                      |    3 
 xen/arch/x86/mm.c                                            |   18 ++
 xen/common/dom0_ops.c                                        |    1 
 xen/common/domain.c                                          |   86 +++++++----
 xen/common/schedule.c                                        |   12 +
 xen/include/asm-x86/mm.h                                     |   17 --
 xen/include/public/dom0_ops.h                                |    3 
 xen/include/xen/mm.h                                         |    4 
 xen/include/xen/sched.h                                      |   11 -
 xen/include/xen/softirq.h                                    |    3 
 12 files changed, 112 insertions(+), 58 deletions(-)


diff -Nru a/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c 
b/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
--- a/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c      
2005-06-01 11:02:43 -04:00
+++ b/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c      
2005-06-01 11:02:43 -04:00
@@ -42,8 +42,7 @@
 
 
 #define DOMFLAGS_DYING     (1<<0) /* Domain is scheduled to die.             */
-#define DOMFLAGS_CRASHED   (1<<1) /* Crashed domain; frozen for postmortem.  */
-#define DOMFLAGS_SHUTDOWN  (1<<2) /* The guest OS has shut itself down.      */
+#define DOMFLAGS_SHUTDOWN  (1<<2) /* The guest OS has shut down.             */
 #define DOMFLAGS_PAUSED    (1<<3) /* Currently paused by control software.   */
 #define DOMFLAGS_BLOCKED   (1<<4) /* Currently blocked pending an event.     */
 #define DOMFLAGS_RUNNING   (1<<5) /* Domain is currently running.            */
@@ -220,7 +219,7 @@
   if (myxcwait(current_domain, &w, 0))
       return -1;
   
-  if (w & (DOMFLAGS_CRASHED|DOMFLAGS_DYING)) {
+  if (w & (DOMFLAGS_SHUTDOWN|DOMFLAGS_DYING)) {
       *status = 'W';
       return 0;
   }
diff -Nru a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   2005-06-01 11:02:43 -04:00
+++ b/tools/libxc/xc_domain.c   2005-06-01 11:02:43 -04:00
@@ -86,7 +86,6 @@
         info->domid      = (u16)op.u.getdomaininfo.domain;
 
         info->dying    = !!(op.u.getdomaininfo.flags & DOMFLAGS_DYING);
-        info->crashed  = !!(op.u.getdomaininfo.flags & DOMFLAGS_CRASHED);
         info->shutdown = !!(op.u.getdomaininfo.flags & DOMFLAGS_SHUTDOWN);
         info->paused   = !!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED);
         info->blocked  = !!(op.u.getdomaininfo.flags & DOMFLAGS_BLOCKED);
@@ -95,6 +94,12 @@
         info->shutdown_reason = 
             (op.u.getdomaininfo.flags>>DOMFLAGS_SHUTDOWNSHIFT) & 
             DOMFLAGS_SHUTDOWNMASK;
+
+        if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
+        {
+            info->shutdown = 0;
+            info->crashed  = 1;
+        }
 
         info->nr_pages = op.u.getdomaininfo.tot_pages;
         info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT);
diff -Nru a/xen/arch/ia64/xenmisc.c b/xen/arch/ia64/xenmisc.c
--- a/xen/arch/ia64/xenmisc.c   2005-06-01 11:02:42 -04:00
+++ b/xen/arch/ia64/xenmisc.c   2005-06-01 11:02:42 -04:00
@@ -304,7 +304,8 @@
        printf(buf);
        if (regs) show_registers(regs);
        domain_pause_by_systemcontroller(current->domain);
-       set_bit(_DOMF_crashed, ed->domain->domain_flags);
+       ed->domain->shutdown_code = SHUTDOWN_crash;
+       set_bit(_DOMF_shutdown, ed->domain->domain_flags);
        if (ed->domain->domain_id == 0) {
                int i = 1000000000L;
                // if domain0 crashes, just periodically print out panic
diff -Nru a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c 2005-06-01 11:02:43 -04:00
+++ b/xen/arch/x86/mm.c 2005-06-01 11:02:43 -04:00
@@ -2971,6 +2971,24 @@
     free_xenheap_page((unsigned long)d->arch.ptwr[PTWR_PT_INACTIVE].page);
 }
 
+void cleanup_writable_pagetable(struct domain *d)
+{
+    if ( unlikely(!VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) )
+        return;
+
+    if ( unlikely(shadow_mode_enabled(d)) )
+    {
+        shadow_sync_all(d);
+    }
+    else
+    {
+        if ( d->arch.ptwr[PTWR_PT_ACTIVE].l1va )
+            ptwr_flush(d, PTWR_PT_ACTIVE);
+        if ( d->arch.ptwr[PTWR_PT_INACTIVE].l1va )
+            ptwr_flush(d, PTWR_PT_INACTIVE);
+    }
+}
+
 int map_pages_to_xen(
     unsigned long virt,
     unsigned long pfn,
diff -Nru a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c     2005-06-01 11:02:43 -04:00
+++ b/xen/common/dom0_ops.c     2005-06-01 11:02:43 -04:00
@@ -353,7 +353,6 @@
 
         op->u.getdomaininfo.flags = flags |
             ((d->domain_flags & DOMF_dying)    ? DOMFLAGS_DYING    : 0) |
-            ((d->domain_flags & DOMF_crashed)  ? DOMFLAGS_CRASHED  : 0) |
             ((d->domain_flags & DOMF_shutdown) ? DOMFLAGS_SHUTDOWN : 0) |
             d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT;
 
diff -Nru a/xen/common/domain.c b/xen/common/domain.c
--- a/xen/common/domain.c       2005-06-01 11:02:42 -04:00
+++ b/xen/common/domain.c       2005-06-01 11:02:43 -04:00
@@ -134,11 +134,7 @@
     show_registers(guest_cpu_user_regs());
 #endif
 
-    set_bit(_DOMF_crashed, &d->domain_flags);
-
-    send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC);
-
-    raise_softirq(SCHEDULE_SOFTIRQ);
+    domain_shutdown(SHUTDOWN_crash);
 }
 
 
@@ -150,9 +146,49 @@
 }
 
 
+static struct domain *domain_shuttingdown[NR_CPUS];
+
+static void domain_shutdown_finalise(void)
+{
+    struct domain *d;
+    struct exec_domain *ed;
+
+    d = domain_shuttingdown[smp_processor_id()];
+    domain_shuttingdown[smp_processor_id()] = NULL;
+
+    BUG_ON(d == NULL);
+    BUG_ON(d == current->domain);
+    BUG_ON(!test_bit(_DOMF_shuttingdown, &d->domain_flags));
+    BUG_ON(test_bit(_DOMF_shutdown, &d->domain_flags));
+
+    /* Make sure that every vcpu is descheduled before we finalise. */
+    for_each_exec_domain ( d, ed )
+        while ( test_bit(_VCPUF_running, &ed->vcpu_flags) )
+            cpu_relax();
+
+    sync_lazy_execstate_cpuset(d->cpuset);
+    BUG_ON(d->cpuset != 0);
+
+    sync_pagetable_state(d);
+
+    set_bit(_DOMF_shutdown, &d->domain_flags);
+    clear_bit(_DOMF_shuttingdown, &d->domain_flags);
+
+    send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC);
+}
+
+static __init int domain_shutdown_finaliser_init(void)
+{
+    open_softirq(DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ, domain_shutdown_finalise);
+    return 0;
+}
+__initcall(domain_shutdown_finaliser_init);
+
+
 void domain_shutdown(u8 reason)
 {
     struct domain *d = current->domain;
+    struct exec_domain *ed;
 
     if ( d->domain_id == 0 )
     {
@@ -173,14 +209,18 @@
         }
     }
 
-    if ( (d->shutdown_code = reason) == SHUTDOWN_crash )
-        set_bit(_DOMF_crashed, &d->domain_flags);
-    else
-        set_bit(_DOMF_shutdown, &d->domain_flags);
-
-    send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC);
+    /* Mark the domain as shutting down. */
+    d->shutdown_code = reason;
+    if ( !test_and_set_bit(_DOMF_shuttingdown, &d->domain_flags) )
+    {
+        /* This vcpu won the race to finalise the shutdown. */
+        domain_shuttingdown[smp_processor_id()] = d;
+        raise_softirq(DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ);
+    }
 
-    raise_softirq(SCHEDULE_SOFTIRQ);
+    /* Put every vcpu to sleep, but don't wait (avoids inter-vcpu deadlock). */
+    for_each_exec_domain ( d, ed )
+        domain_sleep_nosync(ed);
 }
 
 
@@ -190,8 +230,7 @@
     struct domain **pd;
     atomic_t      old, new;
 
-    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
-        BUG();
+    BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
 
     /* May be already destructed, or get_domain() can race us. */
     _atomic_set(old, 0);
@@ -225,10 +264,9 @@
 
 void exec_domain_pause(struct exec_domain *ed)
 {
-    ASSERT(ed != current);
+    BUG_ON(ed == current);
     atomic_inc(&ed->pausecnt);
-    domain_sleep(ed);
-    sync_lazy_execstate_cpuset(ed->domain->cpuset & (1UL << ed->processor));
+    domain_sleep_sync(ed);
 }
 
 void domain_pause(struct domain *d)
@@ -237,17 +275,15 @@
 
     for_each_exec_domain( d, ed )
     {
-        ASSERT(ed != current);
+        BUG_ON(ed == current);
         atomic_inc(&ed->pausecnt);
-        domain_sleep(ed);
+        domain_sleep_sync(ed);
     }
-
-    sync_lazy_execstate_cpuset(d->cpuset);
 }
 
 void exec_domain_unpause(struct exec_domain *ed)
 {
-    ASSERT(ed != current);
+    BUG_ON(ed == current);
     if ( atomic_dec_and_test(&ed->pausecnt) )
         domain_wake(ed);
 }
@@ -266,12 +302,10 @@
 
     for_each_exec_domain ( d, ed )
     {
-        ASSERT(ed != current);
+        BUG_ON(ed == current);
         if ( !test_and_set_bit(_VCPUF_ctrl_pause, &ed->vcpu_flags) )
-            domain_sleep(ed);
+            domain_sleep_sync(ed);
     }
-
-    sync_lazy_execstate_cpuset(d->cpuset);
 }
 
 void domain_unpause_by_systemcontroller(struct domain *d)
diff -Nru a/xen/common/schedule.c b/xen/common/schedule.c

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