Isaku Yamahata
2007-Aug-28 06:20 UTC
[Xen-devel] [PATCH] Make XEN_DOMCTL_destroydomain hypercall continuable.
# HG changeset patch # User yamahata@valinux.co.jp # Date 1188274001 -32400 # Node ID 2c9db26f1d0e0fdd4757d76a67f4b37ba0e40351 # Parent 58d131f1fb35977ff2d8682f553391c8a866d52c Make XEN_DOMCTL_destroydomain hypercall continuable. XEN_DOMCTL_destroydomain hypercall frees domain resources, especially it frees all pages of the domain. When domain memory is very large, it takes too long resulting in soft lockup warning message. To prevent softlokup, make the hypercall continuable. PATCHNAME: make_xen_domctl_destroydomain_hypercall_continuable Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Keir Fraser <keir@xensource.com> diff -r 58d131f1fb35 -r 2c9db26f1d0e tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Fri Aug 24 16:32:56 2007 +0100 +++ b/tools/libxc/xc_domain.c Tue Aug 28 13:06:41 2007 +0900 @@ -55,10 +55,17 @@ int xc_domain_destroy(int xc_handle, int xc_domain_destroy(int xc_handle, uint32_t domid) { + int ret; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_destroydomain; domctl.domain = (domid_t)domid; - return do_domctl(xc_handle, &domctl); + for (;;) { + ret = do_domctl(xc_handle, &domctl); + if (ret && errno == EAGAIN) + continue; + break; + } + return ret; } int xc_domain_shutdown(int xc_handle, diff -r 58d131f1fb35 -r 2c9db26f1d0e xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Fri Aug 24 16:32:56 2007 +0100 +++ b/xen/arch/ia64/xen/domain.c Tue Aug 28 13:06:41 2007 +0900 @@ -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 58d131f1fb35 -r 2c9db26f1d0e xen/arch/powerpc/domain.c --- a/xen/arch/powerpc/domain.c Fri Aug 24 16:32:56 2007 +0100 +++ b/xen/arch/powerpc/domain.c Tue Aug 28 13:06:41 2007 +0900 @@ -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 58d131f1fb35 -r 2c9db26f1d0e xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Fri Aug 24 16:32:56 2007 +0100 +++ b/xen/arch/x86/domain.c Tue Aug 28 13:06:41 2007 +0900 @@ -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 58d131f1fb35 -r 2c9db26f1d0e xen/common/domain.c --- a/xen/common/domain.c Fri Aug 24 16:32:56 2007 +0100 +++ b/xen/common/domain.c Tue Aug 28 13:06:41 2007 +0900 @@ -298,26 +298,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 58d131f1fb35 -r 2c9db26f1d0e xen/common/domctl.c --- a/xen/common/domctl.c Fri Aug 24 16:32:56 2007 +0100 +++ b/xen/common/domctl.c Tue Aug 28 13:06:41 2007 +0900 @@ -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) ) @@ -395,12 +395,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc ret = -ESRCH; if ( d != NULL ) { - ret = -EINVAL; - if ( d != current->domain ) - { - domain_kill(d); - ret = 0; - } + ret = domain_kill(d); rcu_unlock_domain(d); } } diff -r 58d131f1fb35 -r 2c9db26f1d0e xen/include/asm-ia64/domain.h --- a/xen/include/asm-ia64/domain.h Fri Aug 24 16:32:56 2007 +0100 +++ b/xen/include/asm-ia64/domain.h Tue Aug 28 13:06:41 2007 +0900 @@ -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 58d131f1fb35 -r 2c9db26f1d0e xen/include/xen/domain.h --- a/xen/include/xen/domain.h Fri Aug 24 16:32:56 2007 +0100 +++ b/xen/include/xen/domain.h Tue Aug 28 13:06:41 2007 +0900 @@ -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 58d131f1fb35 -r 2c9db26f1d0e xen/include/xen/sched.h --- a/xen/include/xen/sched.h Fri Aug 24 16:32:56 2007 +0100 +++ b/xen/include/xen/sched.h Tue Aug 28 13:06:41 2007 +0900 @@ -191,7 +191,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; @@ -335,7 +335,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); -- yamahata _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
tgingold@free.fr
2007-Aug-28 08:34 UTC
Re: [Xen-devel] [PATCH] Make XEN_DOMCTL_destroydomain hypercall continuable.
Quoting Isaku Yamahata <yamahata@valinux.co.jp>:> diff -r 58d131f1fb35 -r 2c9db26f1d0e tools/libxc/xc_domain.c > --- a/tools/libxc/xc_domain.c Fri Aug 24 16:32:56 2007 +0100 > +++ b/tools/libxc/xc_domain.c Tue Aug 28 13:06:41 2007 +0900 > @@ -55,10 +55,17 @@ int xc_domain_destroy(int xc_handle, > int xc_domain_destroy(int xc_handle, > uint32_t domid) > { > + int ret; > DECLARE_DOMCTL; > domctl.cmd = XEN_DOMCTL_destroydomain; > domctl.domain = (domid_t)domid; > - return do_domctl(xc_handle, &domctl); > + for (;;) { > + ret = do_domctl(xc_handle, &domctl) > + if (ret && errno == EAGAIN) > + continue; > + break; > + } > + return ret; > }Isn''t this loop a little bit obscure ? Why not: do { ret = do_domctl(xc_handle, &domctl); while (ret == EAGAIN); Tristan. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Isaku Yamahata
2007-Aug-28 08:59 UTC
Re: [Xen-devel] [PATCH] Make XEN_DOMCTL_destroydomain hypercall continuable.
On Tue, Aug 28, 2007 at 10:34:42AM +0200, tgingold@free.fr wrote:> Quoting Isaku Yamahata <yamahata@valinux.co.jp>: > > > diff -r 58d131f1fb35 -r 2c9db26f1d0e tools/libxc/xc_domain.c > > --- a/tools/libxc/xc_domain.c Fri Aug 24 16:32:56 2007 +0100 > > +++ b/tools/libxc/xc_domain.c Tue Aug 28 13:06:41 2007 +0900 > > @@ -55,10 +55,17 @@ int xc_domain_destroy(int xc_handle, > > int xc_domain_destroy(int xc_handle, > > uint32_t domid) > > { > > + int ret; > > DECLARE_DOMCTL; > > domctl.cmd = XEN_DOMCTL_destroydomain; > > domctl.domain = (domid_t)domid; > > - return do_domctl(xc_handle, &domctl); > > + for (;;) { > > + ret = do_domctl(xc_handle, &domctl) > > + if (ret && errno == EAGAIN) > > + continue; > > + break; > > + } > > + return ret; > > } > > Isn''t this loop a little bit obscure ? > Why not: > > do { > ret = do_domctl(xc_handle, &domctl); > while (ret == EAGAIN);Right. attached the updated one. -- yamahata _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2007-Aug-28 09:51 UTC
Re: [Xen-devel] [PATCH] Make XEN_DOMCTL_destroydomain hypercall continuable.
On 28/8/07 09:59, "Isaku Yamahata" <yamahata@valinux.co.jp> wrote:>> do { >> ret = do_domctl(xc_handle, &domctl); >> while (ret == EAGAIN); > > Right. attached the updated one.Hang on! The loop above doesn''t do the same as your original one. And looks less correct to me. Which is the correct one? -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Isaku Yamahata
2007-Aug-28 09:58 UTC
Re: [Xen-devel] [PATCH] Make XEN_DOMCTL_destroydomain hypercall continuable.
On Tue, Aug 28, 2007 at 10:51:17AM +0100, Keir Fraser wrote:> On 28/8/07 09:59, "Isaku Yamahata" <yamahata@valinux.co.jp> wrote: > > >> do { > >> ret = do_domctl(xc_handle, &domctl); > >> while (ret == EAGAIN); > > > > Right. attached the updated one. > > Hang on! The loop above doesn''t do the same as your original one. And looks > less correct to me. Which is the correct one?The patch has the following hank which is correct, I believe. Or am I missing anything else? diff -r 58d131f1fb35 -r 8e146ea8c43c tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Fri Aug 24 16:32:56 2007 +0100 +++ b/tools/libxc/xc_domain.c Tue Aug 28 17:58:20 2007 +0900 @@ -55,10 +55,14 @@ int xc_domain_destroy(int xc_handle, int xc_domain_destroy(int xc_handle, uint32_t domid) { + int ret; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_destroydomain; domctl.domain = (domid_t)domid; - return do_domctl(xc_handle, &domctl); + do { + ret = do_domctl(xc_handle, &domctl); + } while ( ret && errno == EAGAIN ); + return ret; } int xc_domain_shutdown(int xc_handle, -- yamahata _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Tristan Gingold
2007-Aug-28 10:51 UTC
Re: [Xen-devel] [PATCH] Make XEN_DOMCTL_destroydomain hypercall continuable.
On Tue, Aug 28, 2007 at 06:58:55PM +0900, Isaku Yamahata wrote:> On Tue, Aug 28, 2007 at 10:51:17AM +0100, Keir Fraser wrote: > > On 28/8/07 09:59, "Isaku Yamahata" <yamahata@valinux.co.jp> wrote: > > > > >> do { > > >> ret = do_domctl(xc_handle, &domctl); > > >> while (ret == EAGAIN); > > > > > > Right. attached the updated one. > > > > Hang on! The loop above doesn''t do the same as your original one. And looks > > less correct to me. Which is the correct one? > > The patch has the following hank which is correct, I believe. > Or am I missing anything else?You correctly fix my loop (I wrote the test condition too quickly hence wrongly!) Tristan. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Tristan Gingold
2007-Aug-29 02:16 UTC
Re: [Xen-devel] [PATCH] Make XEN_DOMCTL_destroydomain hypercall continuable.
On Tue, Aug 28, 2007 at 06:58:55PM +0900, Isaku Yamahata wrote:> On Tue, Aug 28, 2007 at 10:51:17AM +0100, Keir Fraser wrote: > > On 28/8/07 09:59, "Isaku Yamahata" <yamahata@valinux.co.jp> wrote: > > > > >> do { > > >> ret = do_domctl(xc_handle, &domctl); > > >> while (ret == EAGAIN); > > > > > > Right. attached the updated one. > > > > Hang on! The loop above doesn''t do the same as your original one. And looks > > less correct to me. Which is the correct one? > > The patch has the following hank which is correct, I believe. > Or am I missing anything else?It is correct. I wrote the condition too quickly and you fixed it! Sorry for this confusion. Tristan. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Apparently Analagous Threads
- when timer go back in dom0 save and restore or migrate, PV domain hung
- [PATCH v7 1/2] xen: unify domain locking in domctl code
- [PATCH 0 of 2] v2: memshare/xenpaging/xen-access fixes for xen-unstable
- [PATCH] Support cross-bitness guest when core-dumping
- 101th domU fails to start with "SETVCPUCONTEXT failed"