WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Fix domain shutdown so that the new status, and notifica

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix domain shutdown so that the new status, and notification to domain0,
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Wed, 01 Jun 2005 14:44:07 +0000
Delivery-date: Wed, 01 Jun 2005 15:01:52 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: Xen Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Fix domain shutdown so that the new status, and notification to domain0,, BitKeeper Bot <=