Commit d84be02d authored by David Hildenbrand's avatar David Hildenbrand Committed by Paolo Bonzini
Browse files

cpu-exec: fix missed CPU kick during interrupt injection



The conditional memory barrier not only looks strange but actually is
wrong.

On s390x, I can reproduce interrupts via cpu_interrupt() not leading to
a proper kick out of emulation every now and then. cpu_interrupt() is
especially used for inter CPU communication via SIGP (esp. external
calls and emergency interrupts).

With this patch, I was not able to reproduce. (esp. no stalls or hangs
in the guest).

My setup is s390x MTTCG with 16 VCPUs on 8 CPU host, running make -j16.

Signed-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Message-Id: <20171129191319.11483-1-david@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent ebd05fea
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -525,19 +525,13 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
                                        TranslationBlock **last_tb)
{
    CPUClass *cc = CPU_GET_CLASS(cpu);
    int32_t insns_left;

    /* Clear the interrupt flag now since we're processing
     * cpu->interrupt_request and cpu->exit_request.
     * Ensure zeroing happens before reading cpu->exit_request or
     * cpu->interrupt_request (see also smp_wmb in cpu_exit())
     */
    insns_left = atomic_read(&cpu->icount_decr.u32);
    atomic_set(&cpu->icount_decr.u16.high, 0);
    if (unlikely(insns_left < 0)) {
        /* Ensure the zeroing of icount_decr comes before the next read
         * of cpu->exit_request or cpu->interrupt_request.
         */
        smp_mb();
    }
    atomic_mb_set(&cpu->icount_decr.u16.high, 0);

    if (unlikely(atomic_read(&cpu->interrupt_request))) {
        int interrupt_request;