From mboxrd@z Thu Jan 1 00:00:00 1970 From: Juergen Gross Subject: Re: Wrong cpupool handling Date: Tue, 11 Nov 2014 15:21:01 +0100 Message-ID: <54621B4D.7000408@suse.com> References: <19147765.FEreuxd8Ya@amur> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------070605070108000505020609" Return-path: In-Reply-To: <19147765.FEreuxd8Ya@amur> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Dietmar Hahn , xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org This is a multi-part message in MIME format. --------------070605070108000505020609 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Hi again, On 11/11/2014 01:18 PM, Dietmar Hahn wrote: > Hi list, > > When creating a cpupool, starting and destroying a guest within this pool, > then removing this pool doesn't work because of EBUSY. > > It seems the cause of this behavior is the commit > bac6334b51d9bcfe57ecf4a4cb5288348fcf044a. > > In domain_kill() the function sched_move_domain() gets called changing the > d->cpupool pointer to the new cpupool without incrementing/decrementing the > counters "n_dom" of the new/old cpupool. > > This leads to decrementing the wrong cpupool0->n_dom counter when > cpupool_rm_domain() gets called at the end and my own cpupool can't be > destroyed because n_dom = 1! > > I don't have a fast patch because I'am not enough familiar with the code > this time but I think it should be fixed for 4.5. Please discard previous patch, try this one. Juergen --------------070605070108000505020609 Content-Type: text/x-patch; name="0001-Adjust-number-of-domains-in-cpupools-when-destroying.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-Adjust-number-of-domains-in-cpupools-when-destroying.pa"; filename*1="tch" >>From 629a7fe8ed07a13304d9378d357420ec885f59e3 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Tue, 11 Nov 2014 15:03:33 +0100 Subject: [PATCH] Adjust number of domains in cpupools when destroying domain Commit bac6334b51d9bcfe57ecf4a4cb5288348fcf044a (move domain to cpupool0 before destroying it) introduced an error in the accounting of cpupools regarding the number of domains. The number of domains is nor adjusted when a domain is moved to cpupool0 in kill_domain(). Correct this by introducing a cpupool function doing the move instead of open coding it by calling sched_move_domain(). Signed-off-by: Juergen Gross --- xen/common/cpupool.c | 47 +++++++++++++++++++++++++++++++++-------------- xen/common/domain.c | 2 +- xen/include/xen/sched.h | 1 + 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/xen/common/cpupool.c b/xen/common/cpupool.c index 73249d3..c6e3869 100644 --- a/xen/common/cpupool.c +++ b/xen/common/cpupool.c @@ -225,6 +225,35 @@ static int cpupool_destroy(struct cpupool *c) } /* + * Move domain to another cpupool + */ +static int cpupool_move_domain_unlocked(struct domain *d, struct cpupool *c) +{ + int ret; + + d->cpupool->n_dom--; + ret = sched_move_domain(d, c); + if ( ret ) + d->cpupool->n_dom++; + else + c->n_dom++; + + return ret; +} +int cpupool_move_domain(struct domain *d, struct cpupool *c) +{ + int ret; + + spin_lock(&cpupool_lock); + + ret = cpupool_move_domain_unlocked(d, c); + + spin_unlock(&cpupool_lock); + + return ret; +} + +/* * assign a specific cpu to a cpupool * cpupool_lock must be held */ @@ -338,14 +367,9 @@ static int cpupool_unassign_cpu(struct cpupool *c, unsigned int cpu) ret = -EBUSY; break; } - c->n_dom--; - ret = sched_move_domain(d, cpupool0); + ret = cpupool_move_domain_unlocked(d, cpupool0); if ( ret ) - { - c->n_dom++; break; - } - cpupool0->n_dom++; } rcu_read_unlock(&domlist_read_lock); if ( ret ) @@ -613,16 +637,11 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op) d->domain_id, op->cpupool_id); ret = -ENOENT; spin_lock(&cpupool_lock); + c = cpupool_find_by_id(op->cpupool_id); if ( (c != NULL) && cpumask_weight(c->cpu_valid) ) - { - d->cpupool->n_dom--; - ret = sched_move_domain(d, c); - if ( ret ) - d->cpupool->n_dom++; - else - c->n_dom++; - } + ret = cpupool_move_domain_unlocked(d, c); + spin_unlock(&cpupool_lock); cpupool_dprintk("cpupool move_domain(dom=%d)->pool=%d ret %d\n", d->domain_id, op->cpupool_id, ret); diff --git a/xen/common/domain.c b/xen/common/domain.c index a3f51ec..4a62c1d 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -621,7 +621,7 @@ int domain_kill(struct domain *d) rc = -EAGAIN; break; } - if ( sched_move_domain(d, cpupool0) ) + if ( cpupool_move_domain(d, cpupool0) ) return -EAGAIN; for_each_vcpu ( d, v ) unmap_vcpu_info(v); diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index c5157e6..46fc6e3 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -871,6 +871,7 @@ struct cpupool *cpupool_get_by_id(int poolid); void cpupool_put(struct cpupool *pool); int cpupool_add_domain(struct domain *d, int poolid); void cpupool_rm_domain(struct domain *d); +int cpupool_move_domain(struct domain *d, struct cpupool *c); int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op); void schedule_dump(struct cpupool *c); extern void dump_runq(unsigned char key); -- 2.1.2 --------------070605070108000505020609 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --------------070605070108000505020609--