[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |