From patchwork Mon Sep 17 16:31:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emilio Cota X-Patchwork-Id: 10603015 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C55CA161F for ; Mon, 17 Sep 2018 16:31:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B3E4B2A1C3 for ; Mon, 17 Sep 2018 16:31:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B1D0D2A1D2; Mon, 17 Sep 2018 16:31:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BD5342A1FD for ; Mon, 17 Sep 2018 16:31:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728688AbeIQV7U (ORCPT ); Mon, 17 Sep 2018 17:59:20 -0400 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:54359 "EHLO out1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728547AbeIQV7U (ORCPT ); Mon, 17 Sep 2018 17:59:20 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 5FB7D21C08; Mon, 17 Sep 2018 12:31:13 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Mon, 17 Sep 2018 12:31:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=braap.org; h=cc :date:from:in-reply-to:message-id:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=mesmtp; bh=hP3BNXg9fUYlH9 mrXcVwqXX3Jxaadm+2okW5WxgMl58=; b=t0k38ogxl8BXY3m2tREnHvB25lJWSx g7zD1EqEH2hkI/NKCUwrakORm783Rps0I45j5wns6R49X48sUQJ3hZbond7xAnLf qL07P//HmjW35o6l33xGtF5FyBMvVCeLHeQRqTwnKb/qr81BtmQDfXTNX0+zt1zC uh9twUe6DNil0= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=hP3BNXg9fUYlH9mrXcVwqXX3Jxaadm+2okW5WxgMl58=; b=SmlTA+CQ rAfSw6VLqvmOKbJubMF5E4CKJC//QJYrNksBWjBGbfw9zjAxmenfbkPFcOOiHxX+ /O5wOFm9kQ0QPvVIatmAW1+M4brmrmYOQ5SzHLr5TMEhhTYa55atqT1ofm22nuvV cTDkf/r4TG++b/N63ZDp9atkxQWtxa3FxNAAMtOcxeVWKhxrrZ6qRIvJq8+tr2Sg RaOK4TkdyyFcb+LH5eiwXtYH3wVkmF1Qxk2gvnQPIofvpzK3NuhkGhkg0UzTiXaL TSoy27LT51X8/8erpZr7jlajZamvoOEP0FPeNeE4KHqvA17kPazQaGtNz7Su9hDx eb/ii1gbjnRQXg== X-ME-Proxy: X-ME-Sender: Received: from localhost (flamenco.cs.columbia.edu [128.59.20.216]) by mail.messagingengine.com (Postfix) with ESMTPA id D5505E49EC; Mon, 17 Sep 2018 12:31:12 -0400 (EDT) From: "Emilio G. Cota" To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Aleksandar Markovic , Alexander Graf , Anthony Green , Artyom Tarasenko , Aurelien Jarno , Christian Borntraeger , Chris Wulff , Cornelia Huck , David Gibson , David Hildenbrand , "Edgar E. Iglesias" , Eduardo Habkost , Guan Xuetao , James Hogan , kvm@vger.kernel.org, Laurent Vivier , Marcelo Tosatti , Marek Vasut , Mark Cave-Ayland , Michael Walle , Peter Crosthwaite , Peter Maydell , qemu-arm@nongnu.org, qemu-ppc@nongnu.org, qemu-s390x@nongnu.org, Richard Henderson , Stafford Horne Subject: [PATCH 35/35] exec: push BQL down to cpu->cpu_exec_interrupt Date: Mon, 17 Sep 2018 12:31:03 -0400 Message-Id: <20180917163103.6113-36-cota@braap.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180917163103.6113-1-cota@braap.org> References: <20180917163103.6113-1-cota@braap.org> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Paolo Bonzini Most interrupt requests do not need to take the BQL, and in fact most architectures do not need it at all. Push the BQL acquisition down to target code. Cc: Aleksandar Markovic Cc: Alexander Graf Cc: Anthony Green Cc: Artyom Tarasenko Cc: Aurelien Jarno Cc: Christian Borntraeger Cc: Chris Wulff Cc: Cornelia Huck Cc: David Gibson Cc: David Hildenbrand Cc: "Edgar E. Iglesias" Cc: Eduardo Habkost Cc: Guan Xuetao Cc: James Hogan Cc: kvm@vger.kernel.org Cc: Laurent Vivier Cc: Marcelo Tosatti Cc: Marek Vasut Cc: Mark Cave-Ayland Cc: Michael Walle Cc: Peter Crosthwaite Cc: Peter Maydell Cc: qemu-arm@nongnu.org Cc: qemu-ppc@nongnu.org Cc: qemu-s390x@nongnu.org Cc: Richard Henderson Cc: Stafford Horne Signed-off-by: Paolo Bonzini Signed-off-by: Emilio G. Cota Acked-by: David Gibson --- docs/devel/multi-thread-tcg.txt | 7 +++++-- accel/tcg/cpu-exec.c | 9 +-------- target/arm/cpu.c | 15 ++++++++++++++- target/i386/seg_helper.c | 3 +++ target/ppc/excp_helper.c | 2 ++ target/s390x/excp_helper.c | 3 +++ 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/docs/devel/multi-thread-tcg.txt b/docs/devel/multi-thread-tcg.txt index 782bebc28b..422de4736b 100644 --- a/docs/devel/multi-thread-tcg.txt +++ b/docs/devel/multi-thread-tcg.txt @@ -231,8 +231,11 @@ BQL. Currently ARM targets serialise all ARM_CP_IO register accesses and also defer the reset/startup of vCPUs to the vCPU context by way of async_run_on_cpu(). -Updates to interrupt state are also protected by the BQL as they can -often be cross vCPU. +The CPUClass callbacks cpu_exec_interrupt and do_interrupt are invoked +without BQL protection. Accesses to the interrupt controller from +the vCPU thread, for example while processing CPU_INTERRUPT_HARD, must +either call qemu_mutex_lock_iothread/qemu_mutex_unlock_iothread or use +a separate mutex. Memory Consistency ================== diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index b649e3d772..f5e08e79d1 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -524,7 +524,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, if (unlikely(atomic_read(&cpu->interrupt_request))) { int interrupt_request; - qemu_mutex_lock_iothread(); + interrupt_request = atomic_read(&cpu->interrupt_request); if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) { /* Mask out external interrupts for this step. */ @@ -533,7 +533,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, if (interrupt_request & CPU_INTERRUPT_DEBUG) { cpu_reset_interrupt(cpu, CPU_INTERRUPT_DEBUG); cpu->exception_index = EXCP_DEBUG; - qemu_mutex_unlock_iothread(); return true; } if (replay_mode == REPLAY_MODE_PLAY && !replay_has_interrupt()) { @@ -543,7 +542,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, cpu_reset_interrupt(cpu, CPU_INTERRUPT_HALT); cpu->halted = 1; cpu->exception_index = EXCP_HLT; - qemu_mutex_unlock_iothread(); return true; } #if defined(TARGET_I386) @@ -554,14 +552,12 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0, 0); do_cpu_init(x86_cpu); cpu->exception_index = EXCP_HALTED; - qemu_mutex_unlock_iothread(); return true; } #else else if (interrupt_request & CPU_INTERRUPT_RESET) { replay_interrupt(); cpu_reset(cpu); - qemu_mutex_unlock_iothread(); return true; } #endif @@ -585,9 +581,6 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, the program flow was changed */ *last_tb = NULL; } - - /* If we exit via cpu_loop_exit/longjmp it is reset in cpu_exec */ - qemu_mutex_unlock_iothread(); } /* Finally, check if we need to exit to the main loop. */ diff --git a/target/arm/cpu.c b/target/arm/cpu.c index e2c492efdf..246ea13d8f 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -347,7 +347,8 @@ static void arm_cpu_reset(CPUState *s) hw_watchpoint_update_all(cpu); } -bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request) +/* call with the BQL held */ +static bool arm_cpu_exec_interrupt_locked(CPUState *cs, int interrupt_request) { CPUClass *cc = CPU_GET_CLASS(cs); CPUARMState *env = cs->env_ptr; @@ -401,6 +402,16 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request) return ret; } +bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request) +{ + bool ret; + + qemu_mutex_lock_iothread(); + ret = arm_cpu_exec_interrupt_locked(cs, interrupt_request); + qemu_mutex_unlock_iothread(); + return ret; +} + #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { @@ -409,6 +420,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) CPUARMState *env = &cpu->env; bool ret = false; + qemu_mutex_lock_iothread(); /* ARMv7-M interrupt masking works differently than -A or -R. * There is no FIQ/IRQ distinction. Instead of I and F bits * masking FIQ and IRQ interrupts, an exception is taken only @@ -422,6 +434,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) cc->do_interrupt(cs); ret = true; } + qemu_mutex_unlock_iothread(); return ret; } #endif diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c index 0dd85329db..2fdfbd3c37 100644 --- a/target/i386/seg_helper.c +++ b/target/i386/seg_helper.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qemu/main-loop.h" #include "cpu.h" #include "qemu/log.h" #include "exec/helper-proto.h" @@ -1324,7 +1325,9 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request) #if !defined(CONFIG_USER_ONLY) if (interrupt_request & CPU_INTERRUPT_POLL) { cpu_reset_interrupt(cs, CPU_INTERRUPT_POLL); + qemu_mutex_lock_iothread(); apic_poll_irq(cpu->apic_state); + qemu_mutex_unlock_iothread(); /* Don't process multiple interrupt requests in a single call. This is required to make icount-driven execution deterministic. */ return true; diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 8b2cc48cad..57acba2a80 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -885,10 +885,12 @@ bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) CPUPPCState *env = &cpu->env; if (interrupt_request & CPU_INTERRUPT_HARD) { + qemu_mutex_lock_iothread(); ppc_hw_interrupt(env); if (env->pending_interrupts == 0) { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } + qemu_mutex_unlock_iothread(); return true; } return false; diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c index 931c0103c8..f2a93abf01 100644 --- a/target/s390x/excp_helper.c +++ b/target/s390x/excp_helper.c @@ -480,10 +480,13 @@ bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request) the parent EXECUTE insn. */ return false; } + qemu_mutex_lock_iothread(); if (s390_cpu_has_int(cpu)) { s390_cpu_do_interrupt(cs); + qemu_mutex_unlock_iothread(); return true; } + qemu_mutex_unlock_iothread(); if (env->psw.mask & PSW_MASK_WAIT) { /* Woken up because of a floating interrupt but it has already * been delivered. Go back to sleep. */