[XEN] Simplify domain shutdown -- no need to synchronously halt execution.
authorkaf24@localhost.localdomain <kaf24@localhost.localdomain>
Sat, 4 Nov 2006 19:50:59 +0000 (19:50 +0000)
committerkaf24@localhost.localdomain <kaf24@localhost.localdomain>
Sat, 4 Nov 2006 19:50:59 +0000 (19:50 +0000)
This avoids a possible deadlock on the per-domain 'big lock'.

No control tools depend on synchronous halting of execution (e.g.,
save/restore already expect that secondary CPUs were halted
synchronously under the control of the guest itself). This makes the
code rather less complex.

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/common/domain.c
xen/common/domctl.c
xen/include/xen/softirq.h

index 91ee08b743e226cdf339636f44272e24b621b12e..0d63c46395df0d2949ead45e5d03e1cbe9a55762 100644 (file)
@@ -247,42 +247,6 @@ void __domain_crash_synchronous(void)
 }
 
 
-static DEFINE_PER_CPU(struct domain *, domain_shuttingdown);
-
-static void domain_shutdown_finalise(void)
-{
-    struct domain *d;
-    struct vcpu *v;
-
-    d = this_cpu(domain_shuttingdown);
-    this_cpu(domain_shuttingdown) = NULL;
-
-    BUG_ON(d == NULL);
-    BUG_ON(d == current->domain);
-
-    LOCK_BIGLOCK(d);
-
-    /* Make sure that every vcpu is descheduled before we finalise. */
-    for_each_vcpu ( d, v )
-        vcpu_sleep_sync(v);
-    BUG_ON(!cpus_empty(d->domain_dirty_cpumask));
-
-    /* Don't set DOMF_shutdown until execution contexts are sync'ed. */
-    if ( !test_and_set_bit(_DOMF_shutdown, &d->domain_flags) )
-        send_guest_global_virq(dom0, VIRQ_DOM_EXC);
-
-    UNLOCK_BIGLOCK(d);
-
-    put_domain(d);
-}
-
-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(struct domain *d, u8 reason)
 {
     struct vcpu *v;
@@ -290,20 +254,13 @@ void domain_shutdown(struct domain *d, u8 reason)
     if ( d->domain_id == 0 )
         dom0_shutdown(reason);
 
-    /* Mark the domain as shutting down. */
     d->shutdown_code = reason;
+    set_bit(_DOMF_shutdown, &d->domain_flags);
 
-    /* Put every vcpu to sleep, but don't wait (avoids inter-vcpu deadlock). */
-    spin_lock(&d->pause_lock);
-    d->pause_count++;
-    set_bit(_DOMF_paused, &d->domain_flags);
-    spin_unlock(&d->pause_lock);
     for_each_vcpu ( d, v )
         vcpu_sleep_nosync(v);
 
-    get_knownalive_domain(d);
-    this_cpu(domain_shuttingdown) = d;
-    raise_softirq(DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ);
+    send_guest_global_virq(dom0, VIRQ_DOM_EXC);
 }
 
 
@@ -312,12 +269,8 @@ void domain_pause_for_debugger(void)
     struct domain *d = current->domain;
     struct vcpu *v;
 
-    /*
-     * NOTE: This does not synchronously pause the domain. The debugger
-     * must issue a PAUSEDOMAIN command to ensure that all execution
-     * has ceased and guest state is committed to memory.
-     */
     set_bit(_DOMF_ctrl_pause, &d->domain_flags);
+
     for_each_vcpu ( d, v )
         vcpu_sleep_nosync(v);
 
index 5eba88b7c34f5b42baaf00b7e21ef88b859670f5..bf6b8473aa2bfd39ce78ba2df51fdd3f074485e8 100644 (file)
@@ -107,9 +107,9 @@ void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info)
             info->nr_online_vcpus++;
         }
     }
-    
+
     info->cpu_time = cpu_time;
-    
+
     info->flags = flags |
         ((d->domain_flags & DOMF_dying)      ? XEN_DOMINF_dying    : 0) |
         ((d->domain_flags & DOMF_shutdown)   ? XEN_DOMINF_shutdown : 0) |
index 00e561dc86962798cf7cda192c518092a35cea92..d4e8edd7ad3689f0a4ab39552c12461ae5b4007b 100644 (file)
@@ -8,9 +8,8 @@
 #define KEYPRESS_SOFTIRQ                  3
 #define NMI_SOFTIRQ                       4
 #define PAGE_SCRUB_SOFTIRQ                5
-#define DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ  6
-#define TRACE_SOFTIRQ                     7
-#define NR_SOFTIRQS                       8
+#define TRACE_SOFTIRQ                     6
+#define NR_SOFTIRQS                       7
 
 #ifndef __ASSEMBLY__