mirror of https://github.com/xqemu/xqemu.git
cpus: make pause_all_cpus() play with SMP on single threaded TCG
pause_all_cpus() is sometimes called from a VCPU thread (e.g. s390x during special reset). It cannot deal with multiple VCPUs per Thread (single threaded TCG) yet. Booting an s390x guest with -smp 2 and single threaded TCG from disk currently fails. The DIAG 308 will issue a pause_all_cpus() and wait forever for the CPUs to actually stop. But it is waiting for itself. So let's stop all VCPUs belonging to the current thread. Factor out stopping of a VCPU. Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20171129191215.11323-1-david@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
09df29b665
commit
ebd05fea9b
32
cpus.c
32
cpus.c
|
@ -1057,13 +1057,22 @@ static void qemu_tcg_destroy_vcpu(CPUState *cpu)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qemu_cpu_stop(CPUState *cpu, bool exit)
|
||||||
|
{
|
||||||
|
g_assert(qemu_cpu_is_self(cpu));
|
||||||
|
cpu->stop = false;
|
||||||
|
cpu->stopped = true;
|
||||||
|
if (exit) {
|
||||||
|
cpu_exit(cpu);
|
||||||
|
}
|
||||||
|
qemu_cond_broadcast(&qemu_pause_cond);
|
||||||
|
}
|
||||||
|
|
||||||
static void qemu_wait_io_event_common(CPUState *cpu)
|
static void qemu_wait_io_event_common(CPUState *cpu)
|
||||||
{
|
{
|
||||||
atomic_mb_set(&cpu->thread_kicked, false);
|
atomic_mb_set(&cpu->thread_kicked, false);
|
||||||
if (cpu->stop) {
|
if (cpu->stop) {
|
||||||
cpu->stop = false;
|
qemu_cpu_stop(cpu, false);
|
||||||
cpu->stopped = true;
|
|
||||||
qemu_cond_broadcast(&qemu_pause_cond);
|
|
||||||
}
|
}
|
||||||
process_queued_cpu_work(cpu);
|
process_queued_cpu_work(cpu);
|
||||||
}
|
}
|
||||||
|
@ -1610,12 +1619,12 @@ void pause_all_vcpus(void)
|
||||||
|
|
||||||
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
|
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
|
||||||
CPU_FOREACH(cpu) {
|
CPU_FOREACH(cpu) {
|
||||||
cpu->stop = true;
|
if (qemu_cpu_is_self(cpu)) {
|
||||||
qemu_cpu_kick(cpu);
|
qemu_cpu_stop(cpu, true);
|
||||||
}
|
} else {
|
||||||
|
cpu->stop = true;
|
||||||
if (qemu_in_vcpu_thread()) {
|
qemu_cpu_kick(cpu);
|
||||||
cpu_stop_current();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!all_vcpus_paused()) {
|
while (!all_vcpus_paused()) {
|
||||||
|
@ -1799,10 +1808,7 @@ void qemu_init_vcpu(CPUState *cpu)
|
||||||
void cpu_stop_current(void)
|
void cpu_stop_current(void)
|
||||||
{
|
{
|
||||||
if (current_cpu) {
|
if (current_cpu) {
|
||||||
current_cpu->stop = false;
|
qemu_cpu_stop(current_cpu, true);
|
||||||
current_cpu->stopped = true;
|
|
||||||
cpu_exit(current_cpu);
|
|
||||||
qemu_cond_broadcast(&qemu_pause_cond);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue