From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:32993) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TVFPf-0000Yt-HL for qemu-devel@nongnu.org; Mon, 05 Nov 2012 00:39:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TVFPe-000610-BR for qemu-devel@nongnu.org; Mon, 05 Nov 2012 00:39:55 -0500 Received: from mail-ia0-f173.google.com ([209.85.210.173]:37281) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TVFPe-00060u-5x for qemu-devel@nongnu.org; Mon, 05 Nov 2012 00:39:54 -0500 Received: by mail-ia0-f173.google.com with SMTP id m10so4161851iam.4 for ; Sun, 04 Nov 2012 21:39:53 -0800 (PST) From: Liu Ping Fan Date: Mon, 5 Nov 2012 13:38:44 +0800 Message-Id: <1352093924-17598-9-git-send-email-qemulist@gmail.com> In-Reply-To: <1352093924-17598-1-git-send-email-qemulist@gmail.com> References: <1352093924-17598-1-git-send-email-qemulist@gmail.com> Subject: [Qemu-devel] [PATCH v6 8/8] vcpu: push mmio dispatcher out of big lock List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , Jan Kiszka , Marcelo Tosatti , Avi Kivity , Anthony Liguori , Stefan Hajnoczi , Paolo Bonzini From: Liu Ping Fan To anti the recursive big lock, introduce separate interfaces to allow address space dispatcher called with/without big lock. Signed-off-by: Liu Ping Fan --- cpu-common.h | 3 +++ exec.c | 22 ++++++++++++++++++---- kvm-all.c | 6 +++++- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/cpu-common.h b/cpu-common.h index c0d27af..69c1d7a 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -51,6 +51,9 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev); void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, int len, int is_write); +void cpu_physical_memory_nolock_rw(target_phys_addr_t addr, uint8_t *buf, + int len, int is_write); + static inline void cpu_physical_memory_read(target_phys_addr_t addr, void *buf, int len) { diff --git a/exec.c b/exec.c index 1eb920d..73d5242 100644 --- a/exec.c +++ b/exec.c @@ -3484,8 +3484,8 @@ static void address_space_dec_req_pending(void) } } -void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, - int len, bool is_write) +static void address_space_rw_internal(AddressSpace *as, target_phys_addr_t addr, + uint8_t *buf, int len, bool is_write, bool biglock) { AddressSpaceDispatch *d = as->dispatch; int l; @@ -3506,7 +3506,7 @@ void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, qemu_mutex_unlock(&as->lock); address_space_check_inc_req_pending(&obj_mrs); - if (!safe_ref) { + if (!safe_ref && !biglock) { qemu_mutex_lock_iothread(); qemu_mutex_lock(&as->lock); /* when 2nd try, mem map can change, need to judge it again */ @@ -3588,12 +3588,18 @@ void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, len -= l; buf += l; addr += l; - if (!safe_ref) { + if (!safe_ref && !biglock) { qemu_mutex_unlock_iothread(); } } } +void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, + int len, bool is_write) +{ + address_space_rw_internal(as, addr, buf, len, is_write, true); +} + void address_space_write(AddressSpace *as, target_phys_addr_t addr, const uint8_t *buf, int len) { @@ -3619,6 +3625,14 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, return address_space_rw(&address_space_memory, addr, buf, len, is_write); } +void cpu_physical_memory_nolock_rw(target_phys_addr_t addr, uint8_t *buf, + int len, int is_write) +{ + return address_space_rw_internal(&address_space_memory, addr, buf, len, + is_write, false); +} + + /* used for ROM loading : can write in RAM and ROM */ void cpu_physical_memory_write_rom(target_phys_addr_t addr, const uint8_t *buf, int len) diff --git a/kvm-all.c b/kvm-all.c index c2c6909..718f257 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1573,10 +1573,14 @@ int kvm_cpu_exec(CPUArchState *env) break; case KVM_EXIT_MMIO: DPRINTF("handle_mmio\n"); - cpu_physical_memory_rw(run->mmio.phys_addr, + qemu_mutex_unlock_iothread(); + qemu_thread_set_dispatch_type(DISPATCH_MMIO); + cpu_physical_memory_nolock_rw(run->mmio.phys_addr, run->mmio.data, run->mmio.len, run->mmio.is_write); + qemu_thread_reset_dispatch_type(); + qemu_mutex_lock_iothread(); ret = 0; break; case KVM_EXIT_IRQ_WINDOW_OPEN: -- 1.7.4.4