From nobody Sun May 19 00:42:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1529602699728638.893400901892; Thu, 21 Jun 2018 10:38:19 -0700 (PDT) Received: from localhost ([::1]:56913 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fW3XE-0001bQ-VO for importer@patchew.org; Thu, 21 Jun 2018 13:38:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54957) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fW3Vm-0000rF-Qu for qemu-devel@nongnu.org; Thu, 21 Jun 2018 13:36:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fW3Vk-0004Mx-H9 for qemu-devel@nongnu.org; Thu, 21 Jun 2018 13:36:46 -0400 Received: from mail-pf0-x241.google.com ([2607:f8b0:400e:c00::241]:38833) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fW3Vk-0004MK-9X for qemu-devel@nongnu.org; Thu, 21 Jun 2018 13:36:44 -0400 Received: by mail-pf0-x241.google.com with SMTP id b74-v6so1876655pfl.5 for ; Thu, 21 Jun 2018 10:36:44 -0700 (PDT) Received: from cloudburst.twiddle.net (mta-98-147-121-51.hawaii.rr.com. [98.147.121.51]) by smtp.gmail.com with ESMTPSA id e192-v6sm9642897pfg.187.2018.06.21.10.36.40 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 21 Jun 2018 10:36:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dymgG+Lj6AEEhFfH5KrDyexbVF7WGuf7sAlMRIoBv8U=; b=W2fDl7LxG844Of4dfpnPOaZPkrQzilaQxgdf4ZNnOCsZGtL0MpTTOt/RbckoFP7Xf5 FC2yPrACcpUcIUdiqAAvVb/RhY8tXrc2Zyf/OidHqZr3M6wmxS7wKxOk7+qS/Ghmqqw0 eA+zztoMoh9BJ5iJtCqGyL/xxrMikzTLvtzpo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dymgG+Lj6AEEhFfH5KrDyexbVF7WGuf7sAlMRIoBv8U=; b=VDqS5uH1qQLxizji2DZIPWy+Y4eOT3IEFMo7Jo0IP9nmPSZ0+t3hHBweg8br6Mdrfz jd+KH6I9pyYJtNQNDeppOH0jI9iBzGKjagO6LqzVUpOhAxsS5Wm7CMOGSpfZsVI++Blw 9Mogq8XfFUD8ZXqcOs+Ap+pmJmIRpMRr4B/sBladVuBJ+r0IOIg+5ds3p1I+TjR9iSP+ JZewt8ol7rFRYfaJYDIsFFpZMPvQpXs3Wvw/mLA/I7tJ0IMWChEAH+lBow8DhBufUiXC emgTto4PCl8htWzCOMbNPIEUIADm3obm79wIDWRiY61sxa9qsG/MPi7aovhoeS8NVH/3 WJQw== X-Gm-Message-State: APt69E3qY59V4Yn/SCpuOAy7qq0uRtzXYtOAx5kM5GiaoslEtQUWa3U1 iIczADedq4v6SjmiXuIQBnrYlYA0SS0= X-Google-Smtp-Source: ADUXVKKchfbFoRHGXHlytmTgJhucI2wxJ0+47RINVjPazGlYXij1EFG3++WkjKLYQLzgIpRC2yjNEA== X-Received: by 2002:a65:4b46:: with SMTP id k6-v6mr23619171pgt.113.1529602602891; Thu, 21 Jun 2018 10:36:42 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 21 Jun 2018 07:36:34 -1000 Message-Id: <20180621173635.21537-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180621173635.21537-1-richard.henderson@linaro.org> References: <20180621173635.21537-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::241 Subject: [Qemu-devel] [PATCH 1/2] exec: Split mmap_lock to mmap_rdlock/mmap_wrlock X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: cota@braap.org, laurent@vivier.eu, qemu-arm@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Do not yet change the backing implementation, but split intent of users for reading or modification of the memory map. Uses within accel/tcg/ and exec.c are expecting exclusivity while manipulating TranslationBlock data structures, so consider those writers. Signed-off-by: Richard Henderson --- include/exec/exec-all.h | 6 ++++-- accel/tcg/cpu-exec.c | 8 ++++---- accel/tcg/translate-all.c | 4 ++-- bsd-user/mmap.c | 18 ++++++++++++++---- exec.c | 6 +++--- linux-user/elfload.c | 2 +- linux-user/mips/cpu_loop.c | 2 +- linux-user/mmap.c | 22 ++++++++++++++++------ linux-user/ppc/cpu_loop.c | 2 +- linux-user/syscall.c | 4 ++-- target/arm/sve_helper.c | 10 +++------- target/xtensa/op_helper.c | 2 +- 12 files changed, 52 insertions(+), 34 deletions(-) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 25a6f28ab8..a57764b693 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -468,7 +468,8 @@ void tlb_fill(CPUState *cpu, target_ulong addr, int siz= e, #endif =20 #if defined(CONFIG_USER_ONLY) -void mmap_lock(void); +void mmap_rdlock(void); +void mmap_wrlock(void); void mmap_unlock(void); bool have_mmap_lock(void); =20 @@ -477,7 +478,8 @@ static inline tb_page_addr_t get_page_addr_code(CPUArch= State *env1, target_ulong return addr; } #else -static inline void mmap_lock(void) {} +static inline void mmap_rdlock(void) {} +static inline void mmap_wrlock(void) {} static inline void mmap_unlock(void) {} =20 /* cputlb.c */ diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index c738b7f7d6..59bdedb6c7 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -212,7 +212,7 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cyc= les, We only end up here when an existing TB is too long. */ cflags |=3D MIN(max_cycles, CF_COUNT_MASK); =20 - mmap_lock(); + mmap_wrlock(); tb =3D tb_gen_code(cpu, orig_tb->pc, orig_tb->cs_base, orig_tb->flags, cflags); tb->orig_tb =3D orig_tb; @@ -222,7 +222,7 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cyc= les, trace_exec_tb_nocache(tb, tb->pc); cpu_tb_exec(cpu, tb); =20 - mmap_lock(); + mmap_wrlock(); tb_phys_invalidate(tb, -1); mmap_unlock(); tcg_tb_remove(tb); @@ -243,7 +243,7 @@ void cpu_exec_step_atomic(CPUState *cpu) if (sigsetjmp(cpu->jmp_env, 0) =3D=3D 0) { tb =3D tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask); if (tb =3D=3D NULL) { - mmap_lock(); + mmap_wrlock(); tb =3D tb_gen_code(cpu, pc, cs_base, flags, cflags); mmap_unlock(); } @@ -397,7 +397,7 @@ static inline TranslationBlock *tb_find(CPUState *cpu, =20 tb =3D tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask); if (tb =3D=3D NULL) { - mmap_lock(); + mmap_wrlock(); tb =3D tb_gen_code(cpu, pc, cs_base, flags, cf_mask); mmap_unlock(); /* We add the TB in the virtual pc hash table for the fast lookup = */ diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index f0c3fd4d03..48a71af392 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1214,7 +1214,7 @@ static gboolean tb_host_size_iter(gpointer key, gpoin= ter value, gpointer data) /* flush all the translation blocks */ static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count) { - mmap_lock(); + mmap_wrlock(); /* If it is already been done on request of another CPU, * just retry. */ @@ -2563,7 +2563,7 @@ int page_unprotect(target_ulong address, uintptr_t pc) /* Technically this isn't safe inside a signal handler. However we know this only ever happens in a synchronous SEGV handler, so in practice it seems to be ok. */ - mmap_lock(); + mmap_wrlock(); =20 p =3D page_find(address >> TARGET_PAGE_BITS); if (!p) { diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 17f4cd80aa..4f6fe3cf4e 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -28,13 +28,23 @@ static pthread_mutex_t mmap_mutex =3D PTHREAD_MUTEX_INITIALIZER; static __thread int mmap_lock_count; =20 -void mmap_lock(void) +static void mmap_lock_internal(void) { if (mmap_lock_count++ =3D=3D 0) { pthread_mutex_lock(&mmap_mutex); } } =20 +void mmap_rdlock(void) +{ + mmap_lock_internal(); +} + +void mmap_wrlock(void) +{ + mmap_lock_internal(); +} + void mmap_unlock(void) { if (--mmap_lock_count =3D=3D 0) { @@ -87,7 +97,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int p= rot) if (len =3D=3D 0) return 0; =20 - mmap_lock(); + mmap_wrlock(); host_start =3D start & qemu_host_page_mask; host_end =3D HOST_PAGE_ALIGN(end); if (start > host_start) { @@ -248,7 +258,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, in= t prot, abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_l= en; unsigned long host_start; =20 - mmap_lock(); + mmap_wrlock(); #ifdef DEBUG_MMAP { printf("mmap: start=3D0x" TARGET_FMT_lx @@ -424,7 +434,7 @@ int target_munmap(abi_ulong start, abi_ulong len) len =3D TARGET_PAGE_ALIGN(len); if (len =3D=3D 0) return -EINVAL; - mmap_lock(); + mmap_wrlock(); end =3D start + len; real_start =3D start & qemu_host_page_mask; real_end =3D HOST_PAGE_ALIGN(end); diff --git a/exec.c b/exec.c index 28f9bdcbf9..27d9c2ab0c 100644 --- a/exec.c +++ b/exec.c @@ -1030,7 +1030,7 @@ const char *parse_cpu_model(const char *cpu_model) #if defined(CONFIG_USER_ONLY) static void breakpoint_invalidate(CPUState *cpu, target_ulong pc) { - mmap_lock(); + mmap_wrlock(); tb_invalidate_phys_page_range(pc, pc + 1, 0); mmap_unlock(); } @@ -2743,7 +2743,7 @@ static void check_watchpoint(int offset, int len, Mem= TxAttrs attrs, int flags) } cpu->watchpoint_hit =3D wp; =20 - mmap_lock(); + mmap_wrlock(); tb_check_watchpoint(cpu); if (wp->flags & BP_STOP_BEFORE_ACCESS) { cpu->exception_index =3D EXCP_DEBUG; @@ -3143,7 +3143,7 @@ static void invalidate_and_set_dirty(MemoryRegion *mr= , hwaddr addr, } if (dirty_log_mask & (1 << DIRTY_MEMORY_CODE)) { assert(tcg_enabled()); - mmap_lock(); + mmap_wrlock(); tb_invalidate_phys_range(addr, addr + length); mmap_unlock(); dirty_log_mask &=3D ~(1 << DIRTY_MEMORY_CODE); diff --git a/linux-user/elfload.c b/linux-user/elfload.c index bdb023b477..9ef8ab972a 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2196,7 +2196,7 @@ static void load_elf_image(const char *image_name, in= t image_fd, info->nsegs =3D 0; info->pt_dynamic_addr =3D 0; =20 - mmap_lock(); + mmap_wrlock(); =20 /* Find the maximum size of the image and allocate an appropriate amount of memory to handle that. */ diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index 084ad6a041..9d7399c6d1 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -405,7 +405,7 @@ static int do_store_exclusive(CPUMIPSState *env) addr =3D env->lladdr; page_addr =3D addr & TARGET_PAGE_MASK; start_exclusive(); - mmap_lock(); + mmap_rdlock(); flags =3D page_get_flags(page_addr); if ((flags & PAGE_READ) =3D=3D 0) { segv =3D 1; diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 9168a2051c..71b6bed5e2 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -27,13 +27,23 @@ static pthread_mutex_t mmap_mutex =3D PTHREAD_MUTEX_INITIALIZER; static __thread int mmap_lock_count; =20 -void mmap_lock(void) +static void mmap_lock_internal(void) { if (mmap_lock_count++ =3D=3D 0) { pthread_mutex_lock(&mmap_mutex); } } =20 +void mmap_rdlock(void) +{ + mmap_lock_internal(); +} + +void mmap_wrlock(void) +{ + mmap_lock_internal(); +} + void mmap_unlock(void) { if (--mmap_lock_count =3D=3D 0) { @@ -87,7 +97,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int p= rot) if (len =3D=3D 0) return 0; =20 - mmap_lock(); + mmap_wrlock(); host_start =3D start & qemu_host_page_mask; host_end =3D HOST_PAGE_ALIGN(end); if (start > host_start) { @@ -251,7 +261,7 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start= , abi_ulong size) /* * Find and reserve a free memory area of size 'size'. The search * starts at 'start'. - * It must be called with mmap_lock() held. + * It must be called with mmap_wrlock() held. * Return -1 if error. */ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) @@ -364,7 +374,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, in= t prot, { abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_l= en; =20 - mmap_lock(); + mmap_wrlock(); #ifdef DEBUG_MMAP { printf("mmap: start=3D0x" TARGET_ABI_FMT_lx @@ -627,7 +637,7 @@ int target_munmap(abi_ulong start, abi_ulong len) return -TARGET_EINVAL; } =20 - mmap_lock(); + mmap_wrlock(); end =3D start + len; real_start =3D start & qemu_host_page_mask; real_end =3D HOST_PAGE_ALIGN(end); @@ -688,7 +698,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong ol= d_size, return -1; } =20 - mmap_lock(); + mmap_wrlock(); =20 if (flags & MREMAP_FIXED) { host_addr =3D mremap(g2h(old_addr), old_size, new_size, diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c index 2fb516cb00..d7cd5f4a50 100644 --- a/linux-user/ppc/cpu_loop.c +++ b/linux-user/ppc/cpu_loop.c @@ -76,7 +76,7 @@ static int do_store_exclusive(CPUPPCState *env) addr =3D env->reserve_ea; page_addr =3D addr & TARGET_PAGE_MASK; start_exclusive(); - mmap_lock(); + mmap_rdlock(); flags =3D page_get_flags(page_addr); if ((flags & PAGE_READ) =3D=3D 0) { segv =3D 1; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 2117fb13b4..4104444764 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4989,7 +4989,7 @@ static inline abi_ulong do_shmat(CPUArchState *cpu_en= v, return -TARGET_EINVAL; } =20 - mmap_lock(); + mmap_wrlock(); =20 if (shmaddr) host_raddr =3D shmat(shmid, (void *)g2h(shmaddr), shmflg); @@ -5034,7 +5034,7 @@ static inline abi_long do_shmdt(abi_ulong shmaddr) int i; abi_long rv; =20 - mmap_lock(); + mmap_wrlock(); =20 for (i =3D 0; i < N_SHM_REGIONS; ++i) { if (shm_regions[i].in_use && shm_regions[i].start =3D=3D shmaddr) { diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c index cd3dfc8b26..086547c7e5 100644 --- a/target/arm/sve_helper.c +++ b/target/arm/sve_helper.c @@ -4071,10 +4071,6 @@ record_fault(CPUARMState *env, intptr_t i, intptr_t = oprsz) * between page_check_range and the load operation. We expect the * usual case to have no faults at all, so we check the whole range * first and if successful defer to the normal load operation. - * - * TODO: Change mmap_lock to a rwlock so that multiple readers - * can run simultaneously. This will probably help other uses - * within QEMU as well. */ #define DO_LDFF1(PART, FN, TYPEE, TYPEM, H) \ static void do_sve_ldff1##PART(CPUARMState *env, void *vd, void *vg, \ @@ -4107,7 +4103,7 @@ void HELPER(sve_ldff1##PART)(CPUARMState *env, void *= vg, \ intptr_t oprsz =3D simd_oprsz(desc); \ unsigned rd =3D simd_data(desc); \ void *vd =3D &env->vfp.zregs[rd]; \ - mmap_lock(); \ + mmap_rdlock(); \ if (likely(page_check_range(addr, oprsz, PAGE_READ) =3D=3D 0)) { = \ do_sve_ld1##PART(env, vd, vg, addr, oprsz, GETPC()); \ } else { \ @@ -4126,7 +4122,7 @@ void HELPER(sve_ldnf1##PART)(CPUARMState *env, void *= vg, \ intptr_t oprsz =3D simd_oprsz(desc); \ unsigned rd =3D simd_data(desc); \ void *vd =3D &env->vfp.zregs[rd]; \ - mmap_lock(); \ + mmap_rdlock(); \ if (likely(page_check_range(addr, oprsz, PAGE_READ) =3D=3D 0)) { = \ do_sve_ld1##PART(env, vd, vg, addr, oprsz, GETPC()); \ } else { \ @@ -4500,7 +4496,7 @@ void HELPER(NAME)(CPUARMState *env, void *vd, void *v= g, void *vm, \ unsigned scale =3D simd_data(desc); \ uintptr_t ra =3D GETPC(); \ bool first =3D true; \ - mmap_lock(); \ + mmap_rdlock(); \ for (i =3D 0; i < oprsz; i++) { \ uint16_t pg =3D *(uint16_t *)(vg + H1_2(i >> 3)); \ do { \ diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c index 8a8c763c63..251fa27d43 100644 --- a/target/xtensa/op_helper.c +++ b/target/xtensa/op_helper.c @@ -114,7 +114,7 @@ static void tb_invalidate_virtual_addr(CPUXtensaState *= env, uint32_t vaddr) =20 static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr) { - mmap_lock(); + mmap_wrlock(); tb_invalidate_phys_range(vaddr, vaddr + 1); mmap_unlock(); } --=20 2.17.1 From nobody Sun May 19 00:42:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1529602828609469.49740623533114; Thu, 21 Jun 2018 10:40:28 -0700 (PDT) Received: from localhost ([::1]:56922 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fW3ZB-0002xx-P0 for importer@patchew.org; Thu, 21 Jun 2018 13:40:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54976) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fW3Vn-0000rN-KS for qemu-devel@nongnu.org; Thu, 21 Jun 2018 13:36:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fW3Vm-0004O1-Oc for qemu-devel@nongnu.org; Thu, 21 Jun 2018 13:36:47 -0400 Received: from mail-pf0-x22f.google.com ([2607:f8b0:400e:c00::22f]:34434) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fW3Vm-0004NE-8g for qemu-devel@nongnu.org; Thu, 21 Jun 2018 13:36:46 -0400 Received: by mail-pf0-x22f.google.com with SMTP id a63-v6so1881541pfl.1 for ; Thu, 21 Jun 2018 10:36:45 -0700 (PDT) Received: from cloudburst.twiddle.net (mta-98-147-121-51.hawaii.rr.com. [98.147.121.51]) by smtp.gmail.com with ESMTPSA id e192-v6sm9642897pfg.187.2018.06.21.10.36.43 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 21 Jun 2018 10:36:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dAGvimUHj8i54umH7c4ck5t1ysicwOLXz6VvcrwBBVo=; b=a3dng0iwajn81tYrivszbJwfLRCggA4jVOIOOmZ+uQ8sgblEQzwWV8X3N9v9e3UWnX so36Y8C++rWMYjpPTonROLhcq9g727K1sPaz+0Zr7RzY9sKecjqPp9WKlxsw/f2TiSdd cn8DXkvqP6fdOrmvieuSyyFRreKASXWi0ZGyg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dAGvimUHj8i54umH7c4ck5t1ysicwOLXz6VvcrwBBVo=; b=Y8p+0d/ZI68j2Y9p6fcK43Tp2E8n6I4w5XqKnuVLGtanGqcGgvXQ9hN9ho0be7cOhV s9HDzmkRWbqGel1PAP9750/k3kl2lbrIuRYnnHoKRs07jZhOGt95sY/gx0bitghZeuZ7 d47QAMbm69lhZoIXYonz1P+2Y1UCOyvONNvbDSfQozwm1ijfjEDOrpE6WyM9UfHwtabk 4oEQI//E6FE/S66w4eMtAfMy1EPjWgnUjF6ZDgDHojL06fV68DtYOVdBoh4RnDd9X3LT dfK6oAyKN5GLUic47E9XwP0flnOE361+/FfUiP4OV5tG9RojvkGobjjzcIzymUjFYlyo gFNQ== X-Gm-Message-State: APt69E2OtJwpJBv/DBRL0IERFVB1u1dHMc1W9P8NboSj2szUpb47/p/+ vIiXlNQ0AUUANfUMqroPBDO+4YwMfBw= X-Google-Smtp-Source: ADUXVKI5otMOUz5xMnDyT3RswyTwPE/6KMjHhmwOjbryOxHKotw5/Npz7kY9e9K2/RHJCWHlR2o+Iw== X-Received: by 2002:a63:8b44:: with SMTP id j65-v6mr23985916pge.203.1529602604780; Thu, 21 Jun 2018 10:36:44 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 21 Jun 2018 07:36:35 -1000 Message-Id: <20180621173635.21537-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180621173635.21537-1-richard.henderson@linaro.org> References: <20180621173635.21537-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::22f Subject: [Qemu-devel] [PATCH 2/2] linux-user: Use pthread_rwlock_t for mmap_rd/wrlock X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: cota@braap.org, laurent@vivier.eu, qemu-arm@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Change the implementation of these functions to use an actual reader/writer lock, allowing multiple simultaneous readers. Signed-off-by: Richard Henderson --- linux-user/mmap.c | 52 ++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 71b6bed5e2..2dc133515a 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -24,52 +24,62 @@ =20 //#define DEBUG_MMAP =20 -static pthread_mutex_t mmap_mutex =3D PTHREAD_MUTEX_INITIALIZER; -static __thread int mmap_lock_count; - -static void mmap_lock_internal(void) -{ - if (mmap_lock_count++ =3D=3D 0) { - pthread_mutex_lock(&mmap_mutex); - } -} +static pthread_rwlock_t mmap_rwlock =3D PTHREAD_RWLOCK_INITIALIZER; +/* Bit 0 indicates reading; bit 1 indicates writing; bits 2+ are count-1. = */ +static __thread int mmap_lock_held; =20 void mmap_rdlock(void) { - mmap_lock_internal(); + if (likely(mmap_lock_held =3D=3D 0)) { + pthread_rwlock_rdlock(&mmap_rwlock); + mmap_lock_held =3D 1; + } else { + /* can read-lock when write-lock held */ + mmap_lock_held +=3D 4; + } } =20 void mmap_wrlock(void) { - mmap_lock_internal(); + if (likely(mmap_lock_held =3D=3D 0)) { + pthread_rwlock_rdlock(&mmap_rwlock); + mmap_lock_held =3D 2; + } else { + /* cannot upgrade a read-lock to a write-lock */ + assert((mmap_lock_held & 1) =3D=3D 0); + mmap_lock_held +=3D 4; + } } =20 void mmap_unlock(void) { - if (--mmap_lock_count =3D=3D 0) { - pthread_mutex_unlock(&mmap_mutex); + assert(mmap_lock_held > 0); + mmap_lock_held -=3D 4; + if (mmap_lock_held < 0) { + mmap_lock_held =3D 0; + pthread_rwlock_unlock(&mmap_rwlock); } } =20 bool have_mmap_lock(void) { - return mmap_lock_count > 0 ? true : false; + return mmap_lock_held !=3D 0; } =20 /* Grab lock to make sure things are in a consistent state after fork(). = */ void mmap_fork_start(void) { - if (mmap_lock_count) - abort(); - pthread_mutex_lock(&mmap_mutex); + assert(mmap_lock_held =3D=3D 0); + pthread_rwlock_wrlock(&mmap_rwlock); } =20 void mmap_fork_end(int child) { - if (child) - pthread_mutex_init(&mmap_mutex, NULL); - else - pthread_mutex_unlock(&mmap_mutex); + if (child) { + pthread_rwlock_init(&mmap_rwlock, NULL); + } else { + pthread_rwlock_unlock(&mmap_rwlock); + } } =20 /* NOTE: all the constants are the HOST ones, but addresses are target. */ --=20 2.17.1