[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Make XEN_DOMCTL_destroydomain hypercall preemptible, in a way that is
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1188571478 -3600 # Node ID bd59dd48e2084c5b1ec9ae8c8dfde87690a5ef1b # Parent ca093818050990ae9042272dc7ed5a3f205d2862 Make XEN_DOMCTL_destroydomain hypercall preemptible, in a way that is visible to the caller (via -EAGAIN return code). This prevents softlockup in dom0 kernel, due to the hypercall taking too long to execute on very large (multi-multi-gigabyte) domains. Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx> Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/ia64/xen/domain.c | 4 ++- xen/arch/powerpc/domain.c | 4 +-- xen/arch/x86/domain.c | 4 ++- xen/common/domain.c | 53 +++++++++++++++++++++++++----------------- xen/common/domctl.c | 21 +++------------- xen/include/asm-ia64/domain.h | 1 xen/include/xen/domain.h | 2 - xen/include/xen/sched.h | 4 +-- 8 files changed, 48 insertions(+), 45 deletions(-) diff -r ca0938180509 -r bd59dd48e208 xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Fri Aug 31 15:43:28 2007 +0100 +++ b/xen/arch/ia64/xen/domain.c Fri Aug 31 15:44:38 2007 +0100 @@ -936,7 +936,7 @@ static void relinquish_memory(struct dom spin_unlock_recursive(&d->page_alloc_lock); } -void domain_relinquish_resources(struct domain *d) +int domain_relinquish_resources(struct domain *d) { /* Relinquish guest resources for VT-i domain. */ if (d->vcpu[0] && VMX_DOMAIN(d->vcpu[0])) @@ -954,6 +954,8 @@ void domain_relinquish_resources(struct /* Free page used by xen oprofile buffer */ free_xenoprof_pages(d); + + return 0; } unsigned long diff -r ca0938180509 -r bd59dd48e208 xen/arch/powerpc/domain.c --- a/xen/arch/powerpc/domain.c Fri Aug 31 15:43:28 2007 +0100 +++ b/xen/arch/powerpc/domain.c Fri Aug 31 15:44:38 2007 +0100 @@ -313,13 +313,13 @@ static void relinquish_memory(struct dom spin_unlock_recursive(&d->page_alloc_lock); } -void domain_relinquish_resources(struct domain *d) +int domain_relinquish_resources(struct domain *d) { relinquish_memory(d, &d->xenpage_list); relinquish_memory(d, &d->page_list); xfree(d->arch.foreign_mfns); xfree(d->arch.p2m); - return; + return 0; } void arch_dump_domain_info(struct domain *d) diff -r ca0938180509 -r bd59dd48e208 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Fri Aug 31 15:43:28 2007 +0100 +++ b/xen/arch/x86/domain.c Fri Aug 31 15:44:38 2007 +0100 @@ -1717,7 +1717,7 @@ static void vcpu_destroy_pagetables(stru v->arch.cr3 = 0; } -void domain_relinquish_resources(struct domain *d) +int domain_relinquish_resources(struct domain *d) { struct vcpu *v; @@ -1754,6 +1754,8 @@ void domain_relinquish_resources(struct if ( is_hvm_domain(d) ) hvm_domain_relinquish_resources(d); + + return 0; } void arch_dump_domain_info(struct domain *d) diff -r ca0938180509 -r bd59dd48e208 xen/common/domain.c --- a/xen/common/domain.c Fri Aug 31 15:43:28 2007 +0100 +++ b/xen/common/domain.c Fri Aug 31 15:44:38 2007 +0100 @@ -245,7 +245,7 @@ struct domain *domain_create( return d; fail: - d->is_dying = 1; + d->is_dying = DOMDYING_dead; atomic_set(&d->refcnt, DOMAIN_DESTROYED); if ( init_status & INIT_arch ) arch_domain_destroy(d); @@ -303,26 +303,37 @@ struct domain *rcu_lock_domain_by_id(dom } -void domain_kill(struct domain *d) -{ - domain_pause(d); - - /* Already dying? Then bail. */ - if ( test_and_set_bool(d->is_dying) ) - { - domain_unpause(d); - return; - } - - evtchn_destroy(d); - gnttab_release_mappings(d); - domain_relinquish_resources(d); - put_domain(d); - - /* Kick page scrubbing after domain_relinquish_resources(). */ - page_scrub_kick(); - - send_guest_global_virq(dom0, VIRQ_DOM_EXC); +int domain_kill(struct domain *d) +{ + int rc = 0; + + if ( d == current->domain ) + return -EINVAL; + + /* Protected by domctl_lock. */ + switch ( d->is_dying ) + { + case DOMDYING_alive: + domain_pause(d); + d->is_dying = DOMDYING_dying; + evtchn_destroy(d); + gnttab_release_mappings(d); + case DOMDYING_dying: + rc = domain_relinquish_resources(d); + page_scrub_kick(); + if ( rc != 0 ) + { + BUG_ON(rc != -EAGAIN); + break; + } + d->is_dying = DOMDYING_dead; + put_domain(d); + send_guest_global_virq(dom0, VIRQ_DOM_EXC); + case DOMDYING_dead: + break; + } + + return rc; } diff -r ca0938180509 -r bd59dd48e208 xen/common/domctl.c --- a/xen/common/domctl.c Fri Aug 31 15:43:28 2007 +0100 +++ b/xen/common/domctl.c Fri Aug 31 15:44:38 2007 +0100 @@ -114,10 +114,10 @@ void getdomaininfo(struct domain *d, str info->cpu_time = cpu_time; info->flags = flags | - (d->is_dying ? XEN_DOMINF_dying : 0) | - (d->is_shut_down ? XEN_DOMINF_shutdown : 0) | - (d->is_paused_by_controller ? XEN_DOMINF_paused : 0) | - (d->debugger_attached ? XEN_DOMINF_debugged : 0) | + ((d->is_dying == DOMDYING_dead) ? XEN_DOMINF_dying : 0) | + (d->is_shut_down ? XEN_DOMINF_shutdown : 0) | + (d->is_paused_by_controller ? XEN_DOMINF_paused : 0) | + (d->debugger_attached ? XEN_DOMINF_debugged : 0) | d->shutdown_code << XEN_DOMINF_shutdownshift; if ( is_hvm_domain(d) ) @@ -422,18 +422,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc ret = -ESRCH; if ( d != NULL ) { - ret = xsm_destroydomain(d); - if ( ret ) - goto destroydomain_out; - - ret = -EINVAL; - if ( d != current->domain ) - { - domain_kill(d); - ret = 0; - } - - destroydomain_out: + ret = xsm_destroydomain(d) ? : domain_kill(d); rcu_unlock_domain(d); } } diff -r ca0938180509 -r bd59dd48e208 xen/include/asm-ia64/domain.h --- a/xen/include/asm-ia64/domain.h Fri Aug 31 15:43:28 2007 +0100 +++ b/xen/include/asm-ia64/domain.h Fri Aug 31 15:44:38 2007 +0100 @@ -18,7 +18,6 @@ struct tlb_track; struct tlb_track; #endif -extern void domain_relinquish_resources(struct domain *); struct vcpu; extern void relinquish_vcpu_resources(struct vcpu *v); extern void vcpu_share_privregs_with_guest(struct vcpu *v); diff -r ca0938180509 -r bd59dd48e208 xen/include/xen/domain.h --- a/xen/include/xen/domain.h Fri Aug 31 15:43:28 2007 +0100 +++ b/xen/include/xen/domain.h Fri Aug 31 15:44:38 2007 +0100 @@ -45,7 +45,7 @@ int arch_set_info_guest(struct vcpu *, v int arch_set_info_guest(struct vcpu *, vcpu_guest_context_u); void arch_get_info_guest(struct vcpu *, vcpu_guest_context_u); -void domain_relinquish_resources(struct domain *d); +int domain_relinquish_resources(struct domain *d); void dump_pageframe_info(struct domain *d); diff -r ca0938180509 -r bd59dd48e208 xen/include/xen/sched.h --- a/xen/include/xen/sched.h Fri Aug 31 15:43:28 2007 +0100 +++ b/xen/include/xen/sched.h Fri Aug 31 15:44:38 2007 +0100 @@ -194,7 +194,7 @@ struct domain /* Are any VCPUs polling event channels (SCHEDOP_poll)? */ bool_t is_polling; /* Is this guest dying (i.e., a zombie)? */ - bool_t is_dying; + enum { DOMDYING_alive, DOMDYING_dying, DOMDYING_dead } is_dying; /* Domain is paused by controller software? */ bool_t is_paused_by_controller; @@ -338,7 +338,7 @@ static inline struct domain *rcu_lock_cu struct domain *get_domain_by_id(domid_t dom); void domain_destroy(struct domain *d); -void domain_kill(struct domain *d); +int domain_kill(struct domain *d); void domain_shutdown(struct domain *d, u8 reason); void domain_resume(struct domain *d); void domain_pause_for_debugger(void); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |