ia64/xen-unstable
changeset 5256:79fea09c3b44
bitkeeper revision 1.1628 (429dc9b7MTwsBkscbFS1sK8SbwJhdg)
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@xensource.com>
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@xensource.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Wed Jun 01 14:44:07 2005 +0000 (2005-06-01) |
parents | f16ac5cfa153 |
children | f3d83aed87fa 44063d9f39e4 |
files | tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c tools/libxc/xc_domain.c xen/arch/ia64/xenmisc.c xen/arch/x86/mm.c xen/common/dom0_ops.c xen/common/domain.c xen/common/schedule.c xen/include/asm-x86/mm.h xen/include/public/dom0_ops.h xen/include/xen/mm.h xen/include/xen/sched.h xen/include/xen/softirq.h |
line diff
1.1 --- a/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c Wed Jun 01 12:36:40 2005 +0000 1.2 +++ b/tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c Wed Jun 01 14:44:07 2005 +0000 1.3 @@ -42,8 +42,7 @@ int (*myxcwait)(int domain, int *status, 1.4 1.5 1.6 #define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */ 1.7 -#define DOMFLAGS_CRASHED (1<<1) /* Crashed domain; frozen for postmortem. */ 1.8 -#define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut itself down. */ 1.9 +#define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut down. */ 1.10 #define DOMFLAGS_PAUSED (1<<3) /* Currently paused by control software. */ 1.11 #define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */ 1.12 #define DOMFLAGS_RUNNING (1<<5) /* Domain is currently running. */ 1.13 @@ -220,7 +219,7 @@ linux_wait (char *status) 1.14 if (myxcwait(current_domain, &w, 0)) 1.15 return -1; 1.16 1.17 - if (w & (DOMFLAGS_CRASHED|DOMFLAGS_DYING)) { 1.18 + if (w & (DOMFLAGS_SHUTDOWN|DOMFLAGS_DYING)) { 1.19 *status = 'W'; 1.20 return 0; 1.21 }
2.1 --- a/tools/libxc/xc_domain.c Wed Jun 01 12:36:40 2005 +0000 2.2 +++ b/tools/libxc/xc_domain.c Wed Jun 01 14:44:07 2005 +0000 2.3 @@ -86,7 +86,6 @@ int xc_domain_getinfo(int xc_handle, 2.4 info->domid = (u16)op.u.getdomaininfo.domain; 2.5 2.6 info->dying = !!(op.u.getdomaininfo.flags & DOMFLAGS_DYING); 2.7 - info->crashed = !!(op.u.getdomaininfo.flags & DOMFLAGS_CRASHED); 2.8 info->shutdown = !!(op.u.getdomaininfo.flags & DOMFLAGS_SHUTDOWN); 2.9 info->paused = !!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED); 2.10 info->blocked = !!(op.u.getdomaininfo.flags & DOMFLAGS_BLOCKED); 2.11 @@ -96,6 +95,12 @@ int xc_domain_getinfo(int xc_handle, 2.12 (op.u.getdomaininfo.flags>>DOMFLAGS_SHUTDOWNSHIFT) & 2.13 DOMFLAGS_SHUTDOWNMASK; 2.14 2.15 + if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) ) 2.16 + { 2.17 + info->shutdown = 0; 2.18 + info->crashed = 1; 2.19 + } 2.20 + 2.21 info->nr_pages = op.u.getdomaininfo.tot_pages; 2.22 info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT); 2.23 info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
3.1 --- a/xen/arch/ia64/xenmisc.c Wed Jun 01 12:36:40 2005 +0000 3.2 +++ b/xen/arch/ia64/xenmisc.c Wed Jun 01 14:44:07 2005 +0000 3.3 @@ -304,7 +304,8 @@ loop: 3.4 printf(buf); 3.5 if (regs) show_registers(regs); 3.6 domain_pause_by_systemcontroller(current->domain); 3.7 - set_bit(_DOMF_crashed, ed->domain->domain_flags); 3.8 + ed->domain->shutdown_code = SHUTDOWN_crash; 3.9 + set_bit(_DOMF_shutdown, ed->domain->domain_flags); 3.10 if (ed->domain->domain_id == 0) { 3.11 int i = 1000000000L; 3.12 // if domain0 crashes, just periodically print out panic
4.1 --- a/xen/arch/x86/mm.c Wed Jun 01 12:36:40 2005 +0000 4.2 +++ b/xen/arch/x86/mm.c Wed Jun 01 14:44:07 2005 +0000 4.3 @@ -2971,6 +2971,24 @@ void ptwr_destroy(struct domain *d) 4.4 free_xenheap_page((unsigned long)d->arch.ptwr[PTWR_PT_INACTIVE].page); 4.5 } 4.6 4.7 +void cleanup_writable_pagetable(struct domain *d) 4.8 +{ 4.9 + if ( unlikely(!VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) ) 4.10 + return; 4.11 + 4.12 + if ( unlikely(shadow_mode_enabled(d)) ) 4.13 + { 4.14 + shadow_sync_all(d); 4.15 + } 4.16 + else 4.17 + { 4.18 + if ( d->arch.ptwr[PTWR_PT_ACTIVE].l1va ) 4.19 + ptwr_flush(d, PTWR_PT_ACTIVE); 4.20 + if ( d->arch.ptwr[PTWR_PT_INACTIVE].l1va ) 4.21 + ptwr_flush(d, PTWR_PT_INACTIVE); 4.22 + } 4.23 +} 4.24 + 4.25 int map_pages_to_xen( 4.26 unsigned long virt, 4.27 unsigned long pfn,
5.1 --- a/xen/common/dom0_ops.c Wed Jun 01 12:36:40 2005 +0000 5.2 +++ b/xen/common/dom0_ops.c Wed Jun 01 14:44:07 2005 +0000 5.3 @@ -353,7 +353,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 5.4 5.5 op->u.getdomaininfo.flags = flags | 5.6 ((d->domain_flags & DOMF_dying) ? DOMFLAGS_DYING : 0) | 5.7 - ((d->domain_flags & DOMF_crashed) ? DOMFLAGS_CRASHED : 0) | 5.8 ((d->domain_flags & DOMF_shutdown) ? DOMFLAGS_SHUTDOWN : 0) | 5.9 d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT; 5.10
6.1 --- a/xen/common/domain.c Wed Jun 01 12:36:40 2005 +0000 6.2 +++ b/xen/common/domain.c Wed Jun 01 14:44:07 2005 +0000 6.3 @@ -134,11 +134,7 @@ void domain_crash(void) 6.4 show_registers(guest_cpu_user_regs()); 6.5 #endif 6.6 6.7 - set_bit(_DOMF_crashed, &d->domain_flags); 6.8 - 6.9 - send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC); 6.10 - 6.11 - raise_softirq(SCHEDULE_SOFTIRQ); 6.12 + domain_shutdown(SHUTDOWN_crash); 6.13 } 6.14 6.15 6.16 @@ -150,9 +146,49 @@ void domain_crash_synchronous(void) 6.17 } 6.18 6.19 6.20 +static struct domain *domain_shuttingdown[NR_CPUS]; 6.21 + 6.22 +static void domain_shutdown_finalise(void) 6.23 +{ 6.24 + struct domain *d; 6.25 + struct exec_domain *ed; 6.26 + 6.27 + d = domain_shuttingdown[smp_processor_id()]; 6.28 + domain_shuttingdown[smp_processor_id()] = NULL; 6.29 + 6.30 + BUG_ON(d == NULL); 6.31 + BUG_ON(d == current->domain); 6.32 + BUG_ON(!test_bit(_DOMF_shuttingdown, &d->domain_flags)); 6.33 + BUG_ON(test_bit(_DOMF_shutdown, &d->domain_flags)); 6.34 + 6.35 + /* Make sure that every vcpu is descheduled before we finalise. */ 6.36 + for_each_exec_domain ( d, ed ) 6.37 + while ( test_bit(_VCPUF_running, &ed->vcpu_flags) ) 6.38 + cpu_relax(); 6.39 + 6.40 + sync_lazy_execstate_cpuset(d->cpuset); 6.41 + BUG_ON(d->cpuset != 0); 6.42 + 6.43 + sync_pagetable_state(d); 6.44 + 6.45 + set_bit(_DOMF_shutdown, &d->domain_flags); 6.46 + clear_bit(_DOMF_shuttingdown, &d->domain_flags); 6.47 + 6.48 + send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC); 6.49 +} 6.50 + 6.51 +static __init int domain_shutdown_finaliser_init(void) 6.52 +{ 6.53 + open_softirq(DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ, domain_shutdown_finalise); 6.54 + return 0; 6.55 +} 6.56 +__initcall(domain_shutdown_finaliser_init); 6.57 + 6.58 + 6.59 void domain_shutdown(u8 reason) 6.60 { 6.61 struct domain *d = current->domain; 6.62 + struct exec_domain *ed; 6.63 6.64 if ( d->domain_id == 0 ) 6.65 { 6.66 @@ -173,14 +209,18 @@ void domain_shutdown(u8 reason) 6.67 } 6.68 } 6.69 6.70 - if ( (d->shutdown_code = reason) == SHUTDOWN_crash ) 6.71 - set_bit(_DOMF_crashed, &d->domain_flags); 6.72 - else 6.73 - set_bit(_DOMF_shutdown, &d->domain_flags); 6.74 + /* Mark the domain as shutting down. */ 6.75 + d->shutdown_code = reason; 6.76 + if ( !test_and_set_bit(_DOMF_shuttingdown, &d->domain_flags) ) 6.77 + { 6.78 + /* This vcpu won the race to finalise the shutdown. */ 6.79 + domain_shuttingdown[smp_processor_id()] = d; 6.80 + raise_softirq(DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ); 6.81 + } 6.82 6.83 - send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC); 6.84 - 6.85 - raise_softirq(SCHEDULE_SOFTIRQ); 6.86 + /* Put every vcpu to sleep, but don't wait (avoids inter-vcpu deadlock). */ 6.87 + for_each_exec_domain ( d, ed ) 6.88 + domain_sleep_nosync(ed); 6.89 } 6.90 6.91 6.92 @@ -190,8 +230,7 @@ void domain_destruct(struct domain *d) 6.93 struct domain **pd; 6.94 atomic_t old, new; 6.95 6.96 - if ( !test_bit(_DOMF_dying, &d->domain_flags) ) 6.97 - BUG(); 6.98 + BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags)); 6.99 6.100 /* May be already destructed, or get_domain() can race us. */ 6.101 _atomic_set(old, 0); 6.102 @@ -225,10 +264,9 @@ void domain_destruct(struct domain *d) 6.103 6.104 void exec_domain_pause(struct exec_domain *ed) 6.105 { 6.106 - ASSERT(ed != current); 6.107 + BUG_ON(ed == current); 6.108 atomic_inc(&ed->pausecnt); 6.109 - domain_sleep(ed); 6.110 - sync_lazy_execstate_cpuset(ed->domain->cpuset & (1UL << ed->processor)); 6.111 + domain_sleep_sync(ed); 6.112 } 6.113 6.114 void domain_pause(struct domain *d) 6.115 @@ -237,17 +275,15 @@ void domain_pause(struct domain *d) 6.116 6.117 for_each_exec_domain( d, ed ) 6.118 { 6.119 - ASSERT(ed != current); 6.120 + BUG_ON(ed == current); 6.121 atomic_inc(&ed->pausecnt); 6.122 - domain_sleep(ed); 6.123 + domain_sleep_sync(ed); 6.124 } 6.125 - 6.126 - sync_lazy_execstate_cpuset(d->cpuset); 6.127 } 6.128 6.129 void exec_domain_unpause(struct exec_domain *ed) 6.130 { 6.131 - ASSERT(ed != current); 6.132 + BUG_ON(ed == current); 6.133 if ( atomic_dec_and_test(&ed->pausecnt) ) 6.134 domain_wake(ed); 6.135 } 6.136 @@ -266,12 +302,10 @@ void domain_pause_by_systemcontroller(st 6.137 6.138 for_each_exec_domain ( d, ed ) 6.139 { 6.140 - ASSERT(ed != current); 6.141 + BUG_ON(ed == current); 6.142 if ( !test_and_set_bit(_VCPUF_ctrl_pause, &ed->vcpu_flags) ) 6.143 - domain_sleep(ed); 6.144 + domain_sleep_sync(ed); 6.145 } 6.146 - 6.147 - sync_lazy_execstate_cpuset(d->cpuset); 6.148 } 6.149 6.150 void domain_unpause_by_systemcontroller(struct domain *d)
7.1 --- a/xen/common/schedule.c Wed Jun 01 12:36:40 2005 +0000 7.2 +++ b/xen/common/schedule.c Wed Jun 01 14:44:07 2005 +0000 7.3 @@ -190,7 +190,7 @@ void sched_rem_domain(struct exec_domain 7.4 TRACE_2D(TRC_SCHED_DOM_REM, ed->domain->domain_id, ed->vcpu_id); 7.5 } 7.6 7.7 -void domain_sleep(struct exec_domain *ed) 7.8 +void domain_sleep_nosync(struct exec_domain *ed) 7.9 { 7.10 unsigned long flags; 7.11 7.12 @@ -200,10 +200,16 @@ void domain_sleep(struct exec_domain *ed 7.13 spin_unlock_irqrestore(&schedule_data[ed->processor].schedule_lock, flags); 7.14 7.15 TRACE_2D(TRC_SCHED_SLEEP, ed->domain->domain_id, ed->vcpu_id); 7.16 - 7.17 - /* Synchronous. */ 7.18 +} 7.19 + 7.20 +void domain_sleep_sync(struct exec_domain *ed) 7.21 +{ 7.22 + domain_sleep_nosync(ed); 7.23 + 7.24 while ( test_bit(_VCPUF_running, &ed->vcpu_flags) && !domain_runnable(ed) ) 7.25 cpu_relax(); 7.26 + 7.27 + sync_lazy_execstate_cpuset(ed->domain->cpuset & (1UL << ed->processor)); 7.28 } 7.29 7.30 void domain_wake(struct exec_domain *ed)
8.1 --- a/xen/include/asm-x86/mm.h Wed Jun 01 12:36:40 2005 +0000 8.2 +++ b/xen/include/asm-x86/mm.h Wed Jun 01 14:44:07 2005 +0000 8.3 @@ -314,21 +314,8 @@ void ptwr_flush(struct domain *, const i 8.4 int ptwr_do_page_fault(struct domain *, unsigned long); 8.5 int revalidate_l1(struct domain *, l1_pgentry_t *, l1_pgentry_t *); 8.6 8.7 -#define cleanup_writable_pagetable(_d) \ 8.8 - do { \ 8.9 - if ( likely(VM_ASSIST((_d), VMASST_TYPE_writable_pagetables)) ) \ 8.10 - { \ 8.11 - if ( likely(!shadow_mode_enabled(_d)) ) \ 8.12 - { \ 8.13 - if ( (_d)->arch.ptwr[PTWR_PT_ACTIVE].l1va ) \ 8.14 - ptwr_flush((_d), PTWR_PT_ACTIVE); \ 8.15 - if ( (_d)->arch.ptwr[PTWR_PT_INACTIVE].l1va ) \ 8.16 - ptwr_flush((_d), PTWR_PT_INACTIVE); \ 8.17 - } \ 8.18 - else \ 8.19 - shadow_sync_all(_d); \ 8.20 - } \ 8.21 - } while ( 0 ) 8.22 +void cleanup_writable_pagetable(struct domain *d); 8.23 +#define sync_pagetable_state(d) cleanup_writable_pagetable(d) 8.24 8.25 int audit_adjust_pgtables(struct domain *d, int dir, int noisy); 8.26
9.1 --- a/xen/include/public/dom0_ops.h Wed Jun 01 12:36:40 2005 +0000 9.2 +++ b/xen/include/public/dom0_ops.h Wed Jun 01 14:44:07 2005 +0000 9.3 @@ -72,8 +72,7 @@ typedef struct { 9.4 domid_t domain; /* NB. IN/OUT variable. */ 9.5 /* OUT variables. */ 9.6 #define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */ 9.7 -#define DOMFLAGS_CRASHED (1<<1) /* Crashed domain; frozen for postmortem. */ 9.8 -#define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut itself down. */ 9.9 +#define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut down. */ 9.10 #define DOMFLAGS_PAUSED (1<<3) /* Currently paused by control software. */ 9.11 #define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */ 9.12 #define DOMFLAGS_RUNNING (1<<5) /* Domain is currently running. */
10.1 --- a/xen/include/xen/mm.h Wed Jun 01 12:36:40 2005 +0000 10.2 +++ b/xen/include/xen/mm.h Wed Jun 01 14:44:07 2005 +0000 10.3 @@ -48,4 +48,8 @@ extern struct list_head page_scrub_list; 10.4 10.5 #include <asm/mm.h> 10.6 10.7 +#ifndef sync_pagetable_state 10.8 +#define sync_pagetable_state(d) ((void)0) 10.9 +#endif 10.10 + 10.11 #endif /* __XEN_MM_H__ */
11.1 --- a/xen/include/xen/sched.h Wed Jun 01 12:36:40 2005 +0000 11.2 +++ b/xen/include/xen/sched.h Wed Jun 01 14:44:07 2005 +0000 11.3 @@ -255,7 +255,8 @@ long sched_ctl(struct sched_ctl_cmd *); 11.4 long sched_adjdom(struct sched_adjdom_cmd *); 11.5 int sched_id(); 11.6 void domain_wake(struct exec_domain *d); 11.7 -void domain_sleep(struct exec_domain *d); 11.8 +void domain_sleep_nosync(struct exec_domain *d); 11.9 +void domain_sleep_sync(struct exec_domain *d); 11.10 11.11 /* 11.12 * Force loading of currently-executing domain state on the specified set 11.13 @@ -375,9 +376,9 @@ extern struct domain *domain_list; 11.14 /* Guest shut itself down for some reason. */ 11.15 #define _DOMF_shutdown 4 11.16 #define DOMF_shutdown (1UL<<_DOMF_shutdown) 11.17 - /* Domain has crashed and cannot continue to execute. */ 11.18 -#define _DOMF_crashed 5 11.19 -#define DOMF_crashed (1UL<<_DOMF_crashed) 11.20 + /* Guest is in process of shutting itself down (becomes DOMF_shutdown). */ 11.21 +#define _DOMF_shuttingdown 5 11.22 +#define DOMF_shuttingdown (1UL<<_DOMF_shuttingdown) 11.23 /* Death rattle. */ 11.24 #define _DOMF_dying 6 11.25 #define DOMF_dying (1UL<<_DOMF_dying) 11.26 @@ -386,7 +387,7 @@ static inline int domain_runnable(struct 11.27 { 11.28 return ( (atomic_read(&ed->pausecnt) == 0) && 11.29 !(ed->vcpu_flags & (VCPUF_blocked|VCPUF_ctrl_pause)) && 11.30 - !(ed->domain->domain_flags & (DOMF_shutdown|DOMF_crashed)) ); 11.31 + !(ed->domain->domain_flags & (DOMF_shutdown|DOMF_shuttingdown)) ); 11.32 } 11.33 11.34 void exec_domain_pause(struct exec_domain *ed);
12.1 --- a/xen/include/xen/softirq.h Wed Jun 01 12:36:40 2005 +0000 12.2 +++ b/xen/include/xen/softirq.h Wed Jun 01 14:44:07 2005 +0000 12.3 @@ -8,7 +8,8 @@ 12.4 #define KEYPRESS_SOFTIRQ 3 12.5 #define NMI_SOFTIRQ 4 12.6 #define PAGE_SCRUB_SOFTIRQ 5 12.7 -#define NR_SOFTIRQS 6 12.8 +#define DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ 6 12.9 +#define NR_SOFTIRQS 7 12.10 12.11 #ifndef __ASSEMBLY__ 12.12