From nobody Tue Oct 28 12:39:19 2025 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 152298158764099.38505228366569; Thu, 5 Apr 2018 19:26:27 -0700 (PDT) Received: from localhost ([::1]:44441 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f4H58-0005ED-QL for importer@patchew.org; Thu, 05 Apr 2018 22:26:26 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58472) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f4GsM-0002GZ-QQ for qemu-devel@nongnu.org; Thu, 05 Apr 2018 22:13:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f4GsK-0003WK-Cy for qemu-devel@nongnu.org; Thu, 05 Apr 2018 22:13:14 -0400 Received: from out5-smtp.messagingengine.com ([66.111.4.29]:47019) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f4GsK-0003Vv-8D for qemu-devel@nongnu.org; Thu, 05 Apr 2018 22:13:12 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 0A8A4207F3; Thu, 5 Apr 2018 22:13:12 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Thu, 05 Apr 2018 22:13:12 -0400 Received: from localhost (flamenco.cs.columbia.edu [128.59.20.216]) by mail.messagingengine.com (Postfix) with ESMTPA id A87C01025D; Thu, 5 Apr 2018 22:13:11 -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; s=mesmtp; bh=9X/cFvYW55vgiV J3zLa/rV2b1YznqZ5wxUgDWnMpHZQ=; b=jO2trkLPJ3BClwXQcFpFywjGADk09R Yj/5EE0qP4EsVDeiz9jxUCryoNBFfzKTu+GXJ7QawVobe2dzf3IfdkVFivSg3WKP krFmrv4+g3PGskpR+4NtaYcjiESYmGhjHMJfgxRpT44hi4N8zd4y0viTb7eQlRSL Xq3epsyg8QUSM= 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= fm2; bh=9X/cFvYW55vgiVJ3zLa/rV2b1YznqZ5wxUgDWnMpHZQ=; b=c5aWoEpG B27iq6PyvSOEyYYXSFlOEGCOWf42hcjUu2nm6sTKx+XVmYw4ThQ9yeNNpcVzjkYm MYnF9w+U2RFbTdGD2eFf8cBfUsE0Y+19ufv6YrbC3NRGPW7qOkIT2hDXgzRGTgu7 LBVBPECJRqhLvAwFXTircVz3qnA3uvjQ9d9+kZCQhnbm0KBSJ5nq5wvo1dHsaHw5 S2JNiSdoCwn+Km0JQPPgEspPBGsZYt7b2FDZvw5oasMaGZsHZ9ZoTTWEimlSw7j5 ubKsdUM7mBFwstwE+C8FeO5rWLavf7gyftyvP+CkSlEJSA2D9hO3Pdyl/+8Cfp5E GfJ4D6AryATBoQ== X-ME-Sender: From: "Emilio G. Cota" To: qemu-devel@nongnu.org Date: Thu, 5 Apr 2018 22:13:04 -0400 Message-Id: <1522980788-1252-14-git-send-email-cota@braap.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1522980788-1252-1-git-send-email-cota@braap.org> References: <1522980788-1252-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.29 Subject: [Qemu-devel] [PATCH v2 13/17] translate-all: discard TB when tb_link_page returns an existing matching TB 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 , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Paolo Bonzini 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" Use the recently-gained QHT feature of returning the matching TB if it already exists. This allows us to get rid of the lookup we perform right after acquiring tb_lock. Suggested-by: Richard Henderson Signed-off-by: Emilio G. Cota Reviewed-by: Richard Henderson --- docs/devel/multi-thread-tcg.txt | 3 +++ accel/tcg/cpu-exec.c | 14 ++---------- accel/tcg/translate-all.c | 50 +++++++++++++++++++++++++++++++++----= ---- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/docs/devel/multi-thread-tcg.txt b/docs/devel/multi-thread-tcg.= txt index faf8918..faf09c6 100644 --- a/docs/devel/multi-thread-tcg.txt +++ b/docs/devel/multi-thread-tcg.txt @@ -140,6 +140,9 @@ to atomically insert new elements. The lookup caches are updated atomically and the lookup hash uses QHT which is designed for concurrent safe lookup. =20 +Parallel code generation is supported. QHT is used at insertion time +as the synchronization point across threads, thereby ensuring that we only +keep track of a single TranslationBlock for each guest code block. =20 Memory maps and TLBs -------------------- diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 6a3a21d..c79c43b 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -243,10 +243,7 @@ void cpu_exec_step_atomic(CPUState *cpu) if (tb =3D=3D NULL) { mmap_lock(); tb_lock(); - tb =3D tb_htable_lookup(cpu, pc, cs_base, flags, cf_mask); - if (likely(tb =3D=3D NULL)) { - tb =3D tb_gen_code(cpu, pc, cs_base, flags, cflags); - } + tb =3D tb_gen_code(cpu, pc, cs_base, flags, cflags); tb_unlock(); mmap_unlock(); } @@ -396,14 +393,7 @@ static inline TranslationBlock *tb_find(CPUState *cpu, tb_lock(); acquired_tb_lock =3D true; =20 - /* 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, 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, cf_mask); - } + tb =3D tb_gen_code(cpu, pc, cs_base, flags, cf_mask); =20 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 f8862f6..aabde7e 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1581,12 +1581,19 @@ static inline void tb_page_add(PageDesc *p, Transla= tionBlock *tb, * (-1) to indicate that only one page contains the TB. * * Called with mmap_lock held for user-mode emulation. + * + * Returns a pointer @tb, or a pointer to an existing TB that matches @tb. + * Note that in !user-mode, another thread might have already added a TB + * for the same block of guest code that @tb corresponds to. In that case, + * the caller should discard the original @tb, and use instead the returne= d TB. */ -static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, - tb_page_addr_t phys_page2) +static TranslationBlock * +tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, + tb_page_addr_t phys_page2) { PageDesc *p; PageDesc *p2 =3D NULL; + void *existing_tb =3D NULL; uint32_t h; =20 assert_memory_lock(); @@ -1594,6 +1601,11 @@ static void tb_link_page(TranslationBlock *tb, tb_pa= ge_addr_t phys_pc, /* * Add the TB to the page list. * To avoid deadlock, acquire first the lock of the lower-addressed pa= ge. + * We keep the locks held until after inserting the TB in the hash tab= le, + * so that if the insertion fails we know for sure that the TBs are st= ill + * in the page descriptors. + * Note that inserting into the hash table first isn't an option, since + * we can only insert TBs that are fully initialized. */ p =3D page_find_alloc(phys_pc >> TARGET_PAGE_BITS, 1); if (likely(phys_page2 =3D=3D -1)) { @@ -1613,21 +1625,33 @@ static void tb_link_page(TranslationBlock *tb, tb_p= age_addr_t phys_pc, tb_page_add(p2, tb, 1, phys_page2); } =20 + /* add in the hash table */ + h =3D tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MA= SK, + tb->trace_vcpu_dstate); + qht_insert(&tb_ctx.htable, tb, h, &existing_tb); + + /* remove TB from the page(s) if we couldn't insert it */ + if (unlikely(existing_tb)) { + tb_page_remove(p, tb); + invalidate_page_bitmap(p); + if (p2) { + tb_page_remove(p2, tb); + invalidate_page_bitmap(p2); + } + tb =3D existing_tb; + } + if (p2) { page_unlock(p2); } page_unlock(p); =20 - /* add in the hash table */ - h =3D tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MA= SK, - tb->trace_vcpu_dstate); - qht_insert(&tb_ctx.htable, tb, h, NULL); - #ifdef CONFIG_USER_ONLY if (DEBUG_TB_CHECK_GATE) { tb_page_check(); } #endif + return tb; } =20 /* Called with mmap_lock held for user mode emulation. */ @@ -1636,7 +1660,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, uint32_t flags, int cflags) { CPUArchState *env =3D cpu->env_ptr; - TranslationBlock *tb; + TranslationBlock *tb, *existing_tb; tb_page_addr_t phys_pc, phys_page2; target_ulong virt_page2; tcg_insn_unit *gen_code_buf; @@ -1784,7 +1808,15 @@ TranslationBlock *tb_gen_code(CPUState *cpu, * memory barrier is required before tb_link_page() makes the TB visib= le * through the physical hash table and physical page list. */ - tb_link_page(tb, phys_pc, phys_page2); + existing_tb =3D tb_link_page(tb, phys_pc, phys_page2); + /* if the TB already exists, discard what we just translated */ + if (unlikely(existing_tb !=3D tb)) { + uintptr_t orig_aligned =3D (uintptr_t)gen_code_buf; + + orig_aligned -=3D ROUND_UP(sizeof(*tb), qemu_icache_linesize); + atomic_set(&tcg_ctx->code_gen_ptr, orig_aligned); + return existing_tb; + } tcg_tb_insert(tb); return tb; } --=20 2.7.4