54 lines
2.0 KiB
Diff
54 lines
2.0 KiB
Diff
|
# Commit bac6334b51d9bcfe57ecf4a4cb5288348fcf044a
|
||
|
# Date 2014-05-20 15:55:42 +0200
|
||
|
# Author Juergen Gross <juergen.gross@ts.fujitsu.com>
|
||
|
# Committer Jan Beulich <jbeulich@suse.com>
|
||
|
move domain to cpupool0 before destroying it
|
||
|
|
||
|
Currently when a domain is destroyed it is removed from the domain_list
|
||
|
before all of it's resources, including the cpupool membership, are freed.
|
||
|
This can lead to a situation where the domain is still member of a cpupool
|
||
|
without for_each_domain_in_cpupool() (or even for_each_domain()) being
|
||
|
able to find it any more. This in turn can result in rejection of removing
|
||
|
the last cpu from a cpupool, because there seems to be still a domain in
|
||
|
the cpupool, even if it can't be found by scanning through all domains.
|
||
|
|
||
|
This situation can be avoided by moving the domain to be destroyed to
|
||
|
cpupool0 first and then remove it from this cpupool BEFORE deleting it from
|
||
|
the domain_list. As cpupool0 is always active and a domain without any cpupool
|
||
|
membership is implicitly regarded as belonging to cpupool0, this poses no
|
||
|
problem.
|
||
|
|
||
|
Signed-off-by: Juergen Gross <juergen.gross@ts.fujitsu.com>
|
||
|
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||
|
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
|
||
|
|
||
|
--- a/xen/common/domain.c
|
||
|
+++ b/xen/common/domain.c
|
||
|
@@ -539,6 +539,8 @@ int domain_kill(struct domain *d)
|
||
|
BUG_ON(rc != -EAGAIN);
|
||
|
break;
|
||
|
}
|
||
|
+ if ( sched_move_domain(d, cpupool0) )
|
||
|
+ return -EAGAIN;
|
||
|
for_each_vcpu ( d, v )
|
||
|
unmap_vcpu_info(v);
|
||
|
d->is_dying = DOMDYING_dead;
|
||
|
@@ -721,8 +723,6 @@ static void complete_domain_destroy(stru
|
||
|
|
||
|
sched_destroy_domain(d);
|
||
|
|
||
|
- cpupool_rm_domain(d);
|
||
|
-
|
||
|
/* Free page used by xen oprofile buffer. */
|
||
|
#ifdef CONFIG_XENOPROF
|
||
|
free_xenoprof_pages(d);
|
||
|
@@ -770,6 +770,8 @@ void domain_destroy(struct domain *d)
|
||
|
if ( _atomic_read(old) != 0 )
|
||
|
return;
|
||
|
|
||
|
+ cpupool_rm_domain(d);
|
||
|
+
|
||
|
/* Delete from task list and task hashtable. */
|
||
|
TRACE_1D(TRC_SCHED_DOM_REM, d->domain_id);
|
||
|
spin_lock(&domlist_update_lock);
|