From nobody Mon Feb 9 09:34:54 2026 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; 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500617018079480.86559782289316; Thu, 20 Jul 2017 23:03:38 -0700 (PDT) Received: from localhost ([::1]:41213 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dYR2G-0005R1-O7 for importer@patchew.org; Fri, 21 Jul 2017 02:03:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55924) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dYQyM-0002RK-9W for qemu-devel@nongnu.org; Fri, 21 Jul 2017 01:59:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dYQyJ-0001ps-4b for qemu-devel@nongnu.org; Fri, 21 Jul 2017 01:59:34 -0400 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:37291) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dYQyI-0001pE-SL for qemu-devel@nongnu.org; Fri, 21 Jul 2017 01:59:31 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 4A4F120B05; Fri, 21 Jul 2017 01:59:30 -0400 (EDT) Received: from frontend2 ([10.202.2.161]) by compute4.internal (MEProxy); Fri, 21 Jul 2017 01:59:30 -0400 Received: from localhost (flamenco.cs.columbia.edu [128.59.20.216]) by mail.messagingengine.com (Postfix) with ESMTPA id 0BC66241E0; Fri, 21 Jul 2017 01:59:30 -0400 (EDT) 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:x-sasl-enc; s=mesmtp; bh=fs+ 46nwnyv1lMfhhHhSBzyU6n1boXPdMR+N5fVI9EdY=; b=VEJt+xzC+QdZBxmwC6I QPGhEaAJ5jWk4i4T/uX0dmR131VHyeJpvil+wwLQ00wyPL+8T12X3bN0Q5oOs+35 KxsJWvs/jBIbYSO42GvxAc+bP2UP913lX9ctTdxlFaOcudjYOQeVIhLvRK4meoh9 hbiIhTjsTaVXpJs5jSXMYqYs= 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 :x-sasl-enc; s=fm1; bh=fs+46nwnyv1lMfhhHhSBzyU6n1boXPdMR+N5fVI9E dY=; b=Yrsy4rzEtj/WC01U1TouwMoOiKbXKhM5Ez55SG8bX390wHh7YtuSOHHBy 5CFPz1b8syOyOs1VSZXFkYdA7MH1Mfm2c6o7qD597TysnKm9eRULGuoSWUXZGl0D EadCmmXTL4DIoSqiF4pvDROT54bmJ1pRQj5zlh5+EUwMDsXtFbVT/m/VO08LpP+f wKi3pU7UppT5WzxI2IpAITFjeNqk7AkQaFwFfQc0a/KE2WzKbOWxoOIGP347LxyS BEefd4vaWgp8Hkuv8CdQWATJhyEkpNXJlYio9JL2VcBsmRw6c6j+dUuTz9U6gjs2 IuK1Dr8BC1sHgNSo2EgDdgZT0yRZg== X-ME-Sender: X-Sasl-enc: h6S3C+p4bkOgR6SOzPMicKRaDF5F0KBaf553mmV1DMxA 1500616770 From: "Emilio G. Cota" To: qemu-devel@nongnu.org Date: Fri, 21 Jul 2017 01:59:19 -0400 Message-Id: <1500616763-26560-2-git-send-email-cota@braap.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1500616763-26560-1-git-send-email-cota@braap.org> References: <1500616763-26560-1-git-send-email-cota@braap.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.111.4.25 Subject: [Qemu-devel] [PATCH v4 11/43] tcg: define CF_PARALLEL and use it for TB hashing along with CF_COUNT_MASK 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: Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This will enable us to decouple code translation from the value of parallel_cpus at any given time. It will also help us minimize TB flushes when generating code via EXCP_ATOMIC. Note that the declaration of parallel_cpus is brought to exec-all.h to be able to define there the "curr_cflags" inline. Signed-off-by: Emilio G. Cota Reviewed-by: Richard Henderson --- include/exec/exec-all.h | 20 +++++++++++++++++++- include/exec/tb-hash-xx.h | 9 ++++++--- include/exec/tb-hash.h | 4 ++-- include/exec/tb-lookup.h | 6 +++--- tcg/tcg.h | 1 - accel/tcg/cpu-exec.c | 45 +++++++++++++++++++++++--------------------= -- accel/tcg/translate-all.c | 13 +++++++++---- exec.c | 2 +- tcg/tcg-runtime.c | 2 +- tests/qht-bench.c | 2 +- 10 files changed, 65 insertions(+), 39 deletions(-) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 8cbd90b..f6a928d 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -353,6 +353,9 @@ struct TranslationBlock { #define CF_USE_ICOUNT 0x20000 #define CF_IGNORE_ICOUNT 0x40000 /* Do not generate icount code */ #define CF_INVALID 0x80000 /* TB is stale. Setters must acquire tb_loc= k */ +#define CF_PARALLEL 0x100000 /* Generate code for a parallel context */ +/* cflags' mask for hashing/comparison */ +#define CF_HASH_MASK (CF_COUNT_MASK | CF_PARALLEL) =20 /* Per-vCPU dynamic tracing state used to generate this TB */ uint32_t trace_vcpu_dstate; @@ -396,11 +399,26 @@ struct TranslationBlock { uintptr_t jmp_list_first; }; =20 +extern bool parallel_cpus; + +/* Hide the atomic_read to make code a little easier on the eyes */ +static inline uint32_t tb_cflags(const TranslationBlock *tb) +{ + return atomic_read(&tb->cflags); +} + +/* current cflags for hashing/comparison */ +static inline uint32_t curr_cflags(void) +{ + return parallel_cpus ? CF_PARALLEL : 0; +} + void tb_free(TranslationBlock *tb); void tb_flush(CPUState *cpu); void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc, - target_ulong cs_base, uint32_t flags); + target_ulong cs_base, uint32_t flags, + uint32_t cf_mask); =20 #if defined(USE_DIRECT_JUMP) =20 diff --git a/include/exec/tb-hash-xx.h b/include/exec/tb-hash-xx.h index 6cd3022..747a9a6 100644 --- a/include/exec/tb-hash-xx.h +++ b/include/exec/tb-hash-xx.h @@ -48,8 +48,8 @@ * xxhash32, customized for input variables that are not guaranteed to be * contiguous in memory. */ -static inline -uint32_t tb_hash_func6(uint64_t a0, uint64_t b0, uint32_t e, uint32_t f) +static inline uint32_t +tb_hash_func7(uint64_t a0, uint64_t b0, uint32_t e, uint32_t f, uint32_t g) { uint32_t v1 =3D TB_HASH_XX_SEED + PRIME32_1 + PRIME32_2; uint32_t v2 =3D TB_HASH_XX_SEED + PRIME32_2; @@ -78,7 +78,7 @@ uint32_t tb_hash_func6(uint64_t a0, uint64_t b0, uint32_t= e, uint32_t f) v4 *=3D PRIME32_1; =20 h32 =3D rol32(v1, 1) + rol32(v2, 7) + rol32(v3, 12) + rol32(v4, 18); - h32 +=3D 24; + h32 +=3D 28; =20 h32 +=3D e * PRIME32_3; h32 =3D rol32(h32, 17) * PRIME32_4; @@ -86,6 +86,9 @@ uint32_t tb_hash_func6(uint64_t a0, uint64_t b0, uint32_t= e, uint32_t f) h32 +=3D f * PRIME32_3; h32 =3D rol32(h32, 17) * PRIME32_4; =20 + h32 +=3D g * PRIME32_3; + h32 =3D rol32(h32, 17) * PRIME32_4; + h32 ^=3D h32 >> 15; h32 *=3D PRIME32_2; h32 ^=3D h32 >> 13; diff --git a/include/exec/tb-hash.h b/include/exec/tb-hash.h index 17b5ee0..0526c4f 100644 --- a/include/exec/tb-hash.h +++ b/include/exec/tb-hash.h @@ -59,9 +59,9 @@ static inline unsigned int tb_jmp_cache_hash_func(target_= ulong pc) =20 static inline uint32_t tb_hash_func(tb_page_addr_t phys_pc, target_ulong pc, uint32_t fl= ags, - uint32_t trace_vcpu_dstate) + uint32_t cf_mask, uint32_t trace_vcpu_dstate) { - return tb_hash_func6(phys_pc, pc, flags, trace_vcpu_dstate); + return tb_hash_func7(phys_pc, pc, flags, cf_mask, trace_vcpu_dstate); } =20 #endif diff --git a/include/exec/tb-lookup.h b/include/exec/tb-lookup.h index 436b6d5..2961385 100644 --- a/include/exec/tb-lookup.h +++ b/include/exec/tb-lookup.h @@ -21,7 +21,7 @@ /* Might cause an exception, so have a longjmp destination ready */ static inline TranslationBlock * tb_lookup__cpu_state(CPUState *cpu, target_ulong *pc, target_ulong *cs_bas= e, - uint32_t *flags) + uint32_t *flags, uint32_t cf_mask) { CPUArchState *env =3D (CPUArchState *)cpu->env_ptr; TranslationBlock *tb; @@ -35,10 +35,10 @@ tb_lookup__cpu_state(CPUState *cpu, target_ulong *pc, t= arget_ulong *cs_base, tb->cs_base =3D=3D *cs_base && tb->flags =3D=3D *flags && tb->trace_vcpu_dstate =3D=3D *cpu->trace_dstate && - !(atomic_read(&tb->cflags) & CF_INVALID))) { + (tb_cflags(tb) & (CF_HASH_MASK | CF_INVALID)) =3D=3D cf_mas= k)) { return tb; } - tb =3D tb_htable_lookup(cpu, *pc, *cs_base, *flags); + tb =3D tb_htable_lookup(cpu, *pc, *cs_base, *flags, cf_mask); if (tb =3D=3D NULL) { return NULL; } diff --git a/tcg/tcg.h b/tcg/tcg.h index da78721..96872f8 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -730,7 +730,6 @@ struct TCGContext { }; =20 extern TCGContext tcg_ctx; -extern bool parallel_cpus; =20 static inline void tcg_set_insn_param(int op_idx, int arg, TCGArg v) { diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index fae8c40..b71e015 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -207,7 +207,8 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cyc= les, tb_lock(); tb =3D tb_gen_code(cpu, orig_tb->pc, orig_tb->cs_base, orig_tb->flags, max_cycles | CF_NOCACHE - | (ignore_icount ? CF_IGNORE_ICOUNT : 0)); + | (ignore_icount ? CF_IGNORE_ICOUNT : 0) + | curr_cflags()); tb->orig_tb =3D orig_tb; tb_unlock(); =20 @@ -225,31 +226,27 @@ static void cpu_exec_nocache(CPUState *cpu, int max_c= ycles, static void cpu_exec_step(CPUState *cpu) { CPUClass *cc =3D CPU_GET_CLASS(cpu); - CPUArchState *env =3D (CPUArchState *)cpu->env_ptr; TranslationBlock *tb; target_ulong cs_base, pc; uint32_t flags; + uint32_t cflags =3D 1 | CF_IGNORE_ICOUNT; =20 - cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); if (sigsetjmp(cpu->jmp_env, 0) =3D=3D 0) { - mmap_lock(); - tb_lock(); - tb =3D tb_gen_code(cpu, pc, cs_base, flags, - 1 | CF_NOCACHE | CF_IGNORE_ICOUNT); - tb->orig_tb =3D NULL; - tb_unlock(); - mmap_unlock(); + tb =3D tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, + cflags & CF_HASH_MASK); + if (tb =3D=3D NULL) { + mmap_lock(); + tb_lock(); + tb =3D tb_gen_code(cpu, pc, cs_base, flags, cflags); + tb_unlock(); + mmap_unlock(); + } =20 cc->cpu_exec_enter(cpu); /* execute the generated code */ - trace_exec_tb_nocache(tb, pc); + trace_exec_tb(tb, pc); cpu_tb_exec(cpu, tb); cc->cpu_exec_exit(cpu); - - tb_lock(); - tb_phys_invalidate(tb, -1); - tb_free(tb); - tb_unlock(); } else { /* We may have exited due to another problem here, so we need * to reset any tb_locks we may have taken but didn't release. @@ -281,6 +278,7 @@ struct tb_desc { CPUArchState *env; tb_page_addr_t phys_page1; uint32_t flags; + uint32_t cf_mask; uint32_t trace_vcpu_dstate; }; =20 @@ -294,7 +292,7 @@ static bool tb_cmp(const void *p, const void *d) tb->cs_base =3D=3D desc->cs_base && tb->flags =3D=3D desc->flags && tb->trace_vcpu_dstate =3D=3D desc->trace_vcpu_dstate && - !(atomic_read(&tb->cflags) & CF_INVALID)) { + (tb_cflags(tb) & (CF_HASH_MASK | CF_INVALID)) =3D=3D desc->cf_mask= ) { /* check next page if needed */ if (tb->page_addr[1] =3D=3D -1) { return true; @@ -313,7 +311,8 @@ static bool tb_cmp(const void *p, const void *d) } =20 TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc, - target_ulong cs_base, uint32_t flags) + target_ulong cs_base, uint32_t flags, + uint32_t cf_mask) { tb_page_addr_t phys_pc; struct tb_desc desc; @@ -322,11 +321,12 @@ TranslationBlock *tb_htable_lookup(CPUState *cpu, tar= get_ulong pc, desc.env =3D (CPUArchState *)cpu->env_ptr; desc.cs_base =3D cs_base; desc.flags =3D flags; + desc.cf_mask =3D cf_mask; desc.trace_vcpu_dstate =3D *cpu->trace_dstate; desc.pc =3D pc; phys_pc =3D get_page_addr_code(desc.env, pc); desc.phys_page1 =3D phys_pc & TARGET_PAGE_MASK; - h =3D tb_hash_func(phys_pc, pc, flags, *cpu->trace_dstate); + h =3D tb_hash_func(phys_pc, pc, flags, cf_mask, *cpu->trace_dstate); return qht_lookup(&tcg_ctx.tb_ctx.htable, tb_cmp, &desc, h); } =20 @@ -338,8 +338,9 @@ static inline TranslationBlock *tb_find(CPUState *cpu, target_ulong cs_base, pc; uint32_t flags; bool acquired_tb_lock =3D false; + uint32_t cf_mask =3D curr_cflags(); =20 - tb =3D tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags); + tb =3D tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask); if (tb =3D=3D NULL) { /* mmap_lock is needed by tb_gen_code, and mmap_lock must be * taken outside tb_lock. As system emulation is currently @@ -352,10 +353,10 @@ static inline TranslationBlock *tb_find(CPUState *cpu, /* There's a chance that our desired tb has been translated while * taking the locks so we check again inside the lock. */ - tb =3D tb_htable_lookup(cpu, pc, cs_base, flags); + tb =3D tb_htable_lookup(cpu, pc, cs_base, flags, cf_mask); if (likely(tb =3D=3D NULL)) { /* if no translated code available, then translate it now */ - tb =3D tb_gen_code(cpu, pc, cs_base, flags, 0); + tb =3D tb_gen_code(cpu, pc, cs_base, flags, cf_mask); } =20 mmap_unlock(); diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index c8abef0..c1ce38f 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1077,7 +1077,8 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page= _addr_t page_addr) =20 /* remove the TB from the hash list */ phys_pc =3D tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK); - h =3D tb_hash_func(phys_pc, tb->pc, tb->flags, tb->trace_vcpu_dstate); + h =3D tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MA= SK, + tb->trace_vcpu_dstate); qht_remove(&tcg_ctx.tb_ctx.htable, tb, h); =20 /* remove the TB from the page list */ @@ -1222,7 +1223,8 @@ static void tb_link_page(TranslationBlock *tb, tb_pag= e_addr_t phys_pc, } =20 /* add in the hash table */ - h =3D tb_hash_func(phys_pc, tb->pc, tb->flags, tb->trace_vcpu_dstate); + h =3D tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MA= SK, + tb->trace_vcpu_dstate); qht_insert(&tcg_ctx.tb_ctx.htable, tb, h); =20 #ifdef DEBUG_TB_CHECK @@ -1503,7 +1505,8 @@ void tb_invalidate_phys_page_range(tb_page_addr_t sta= rt, tb_page_addr_t end, /* we generate a block containing just the instruction modifying the memory. It will ensure that it cannot modify itself */ - tb_gen_code(cpu, current_pc, current_cs_base, current_flags, 1); + tb_gen_code(cpu, current_pc, current_cs_base, current_flags, + 1 | curr_cflags()); cpu_loop_exit_noexc(cpu); } #endif @@ -1621,7 +1624,8 @@ static bool tb_invalidate_phys_page(tb_page_addr_t ad= dr, uintptr_t pc) /* we generate a block containing just the instruction modifying the memory. It will ensure that it cannot modify itself */ - tb_gen_code(cpu, current_pc, current_cs_base, current_flags, 1); + tb_gen_code(cpu, current_pc, current_cs_base, current_flags, + 1 | curr_cflags()); /* tb_lock will be reset after cpu_loop_exit_noexc longjmps * back into the cpu_exec loop. */ return true; @@ -1765,6 +1769,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retadd= r) } =20 cflags =3D n | CF_LAST_IO; + cflags |=3D curr_cflags(); pc =3D tb->pc; cs_base =3D tb->cs_base; flags =3D tb->flags; diff --git a/exec.c b/exec.c index 01ac21e..94b0f3e 100644 --- a/exec.c +++ b/exec.c @@ -2433,7 +2433,7 @@ static void check_watchpoint(int offset, int len, Mem= TxAttrs attrs, int flags) cpu_loop_exit(cpu); } else { cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags); - tb_gen_code(cpu, pc, cs_base, cpu_flags, 1); + tb_gen_code(cpu, pc, cs_base, cpu_flags, 1 | curr_cfla= gs()); cpu_loop_exit_noexc(cpu); } } diff --git a/tcg/tcg-runtime.c b/tcg/tcg-runtime.c index 7100339..4f873a9 100644 --- a/tcg/tcg-runtime.c +++ b/tcg/tcg-runtime.c @@ -151,7 +151,7 @@ void *HELPER(lookup_tb_ptr)(CPUArchState *env) target_ulong cs_base, pc; uint32_t flags; =20 - tb =3D tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags); + tb =3D tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, curr_cflags()); if (tb =3D=3D NULL) { return tcg_ctx.code_gen_epilogue; } diff --git a/tests/qht-bench.c b/tests/qht-bench.c index 11c1cec..4cabdfd 100644 --- a/tests/qht-bench.c +++ b/tests/qht-bench.c @@ -103,7 +103,7 @@ static bool is_equal(const void *obj, const void *userp) =20 static inline uint32_t h(unsigned long v) { - return tb_hash_func6(v, 0, 0, 0); + return tb_hash_func7(v, 0, 0, 0, 0); } =20 /* --=20 2.7.4