aboutsummaryrefslogtreecommitdiff
path: root/cpus-common.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2016-09-02 23:33:38 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2016-09-27 11:57:30 +0200
commit758e1b2b622d7c177dc2d95e887a11aa069b7e68 (patch)
tree4b8fc6e2fa1fac81eeb8d038ee1f213dbab71a3a /cpus-common.c
parentcf07da65f335b9a74e62f5413078f67280572f36 (diff)
cpus-common: simplify locking for start_exclusive/end_exclusive
It is not necessary to hold qemu_cpu_list_mutex throughout the exclusive section, because no other exclusive section can run while pending_cpus != 0. exclusive_idle() is called in cpu_exec_start(), and that prevents any CPUs created after start_exclusive() from entering cpu_exec() during an exclusive section. Reviewed-by: Richard Henderson <rth@twiddle.net> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'cpus-common.c')
-rw-r--r--cpus-common.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/cpus-common.c b/cpus-common.c
index 80aaf9b42d..429652c7fd 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -171,8 +171,7 @@ static inline void exclusive_idle(void)
}
/* Start an exclusive operation.
- Must only be called from outside cpu_exec, takes
- qemu_cpu_list_lock. */
+ Must only be called from outside cpu_exec. */
void start_exclusive(void)
{
CPUState *other_cpu;
@@ -191,11 +190,17 @@ void start_exclusive(void)
while (pending_cpus > 1) {
qemu_cond_wait(&exclusive_cond, &qemu_cpu_list_lock);
}
+
+ /* Can release mutex, no one will enter another exclusive
+ * section until end_exclusive resets pending_cpus to 0.
+ */
+ qemu_mutex_unlock(&qemu_cpu_list_lock);
}
-/* Finish an exclusive operation. Releases qemu_cpu_list_lock. */
+/* Finish an exclusive operation. */
void end_exclusive(void)
{
+ qemu_mutex_lock(&qemu_cpu_list_lock);
pending_cpus = 0;
qemu_cond_broadcast(&exclusive_resume);
qemu_mutex_unlock(&qemu_cpu_list_lock);