From patchwork Fri Sep 30 21:31:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 77191 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp519741qgf; Fri, 30 Sep 2016 14:52:24 -0700 (PDT) X-Received: by 10.55.91.196 with SMTP id p187mr8536550qkb.263.1475272344957; Fri, 30 Sep 2016 14:52:24 -0700 (PDT) Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id k192si13458046qke.306.2016.09.30.14.52.24 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Sep 2016 14:52:24 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:47154 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bq5jE-0007zk-Ja for patch@linaro.org; Fri, 30 Sep 2016 17:52:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49787) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bq5P3-0006Zz-Fe for qemu-devel@nongnu.org; Fri, 30 Sep 2016 17:31:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bq5P0-0006as-1T for qemu-devel@nongnu.org; Fri, 30 Sep 2016 17:31:32 -0400 Received: from mail-wm0-x22c.google.com ([2a00:1450:400c:c09::22c]:37327) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bq5Oz-0006ah-NN for qemu-devel@nongnu.org; Fri, 30 Sep 2016 17:31:29 -0400 Received: by mail-wm0-x22c.google.com with SMTP id b80so66259713wme.0 for ; Fri, 30 Sep 2016 14:31:29 -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 :mime-version:content-transfer-encoding; bh=dxiGIB2EZGZbjvnPzqY5js9FSVUhKopPQtL8ZnBdfjI=; b=BguRi09aErPiRjkljPjEnDJu+mYm9eBNVPFv4UzGw0POkdRgI6dc9PW1pgNik557PG L46z6MYJW1pCNhqElM3mml0nLteb9H42Jer98G9GjZeRDuSqPKCaeh7V88vaYiFiGggz 83fpoJtcyJI8UmM80m6zqywD2C4CxbzOAZhzM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dxiGIB2EZGZbjvnPzqY5js9FSVUhKopPQtL8ZnBdfjI=; b=fHv+RDwmjYAdbZBCmEyuhnyHRJSgNci2Io+/GFCfLAOXMf7aDzhWwcqWTve05MF/H9 KAiopD2UZa/Pq5c/uAmqbnI+irQeKiAJueUL06ylmbQBVOhFvtktgXblaup9hj+muado 3tTjc1UwiVhxS+82EYX9yzlWInMDtO4HkJ3MwhWK4ME/berjJTs8aaBEbxw4fJ1qq2pS t+HBkgTyzeRxU813zTQ0cf9Z9xz8dzTfW6ks1g/jXuorkAZqOy6Fj2q31bMzlfmo6bGQ JJTQYScYpbfbH9iwQluZBcC8/zA5AFLmDJps9RTZ+lRzZ4AS5cPznGsTCNzajTzlxDjA DzAw== X-Gm-Message-State: AA6/9RmDucD2qzoxnHjuYq3WmF+x8gkNpfU7uAD/tfdOkR2jN+5+5tV788lQ3zmJ5++Fo47s X-Received: by 10.194.220.233 with SMTP id pz9mr7995170wjc.130.1475271089055; Fri, 30 Sep 2016 14:31:29 -0700 (PDT) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id bj8sm21467877wjc.49.2016.09.30.14.31.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Sep 2016 14:31:23 -0700 (PDT) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 76FFA3E05EE; Fri, 30 Sep 2016 22:31:18 +0100 (BST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org, pbonzini@redhat.com Date: Fri, 30 Sep 2016 22:31:05 +0100 Message-Id: <20160930213106.20186-15-alex.bennee@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20160930213106.20186-1-alex.bennee@linaro.org> References: <20160930213106.20186-1-alex.bennee@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::22c Subject: [Qemu-devel] [PATCH v3 14/15] tcg: update remaining TranslationBuffer fields atomically 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: mttcg@listserver.greensocs.com, peter.maydell@linaro.org, claudio.fontana@huawei.com, nikunj@linux.vnet.ibm.com, Peter Crosthwaite , jan.kiszka@siemens.com, mark.burton@greensocs.com, a.rigo@virtualopensystems.com, cota@braap.org, serge.fdrv@gmail.com, bobby.prani@gmail.com, rth@twiddle.net, =?UTF-8?q?Alex=20Benn=C3=A9e?= , fred.konrad@greensocs.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The TranslationBuffer is one of those heavily accessed across threads. To meet defined C11 behaviour across threads we update the accesses to use the relaxed atomic helpers. Care is still taken with locking and barriers for when flags are updated and when newly generated buffers are made visible to the rest of the system. Signed-off-by: Alex Bennée --- cpu-exec.c | 16 ++++++++-------- include/exec/exec-all.h | 11 +++++++++++ translate-all.c | 11 ++++++----- 3 files changed, 25 insertions(+), 13 deletions(-) -- 2.9.3 diff --git a/cpu-exec.c b/cpu-exec.c index 99c906b..0e6b3d3 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -185,7 +185,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) cc->synchronize_from_tb(cpu, last_tb); } else { assert(cc->set_pc); - cc->set_pc(cpu, last_tb->pc); + cc->set_pc(cpu, atomic_read(&last_tb->pc)); } } if (tb_exit == TB_EXIT_REQUESTED) { @@ -235,13 +235,13 @@ static bool tb_cmp(const void *p, const void *d) const TranslationBlock *tb = p; const struct tb_desc *desc = d; - if (tb->pc == desc->pc && - tb->page_addr[0] == desc->phys_page1 && - tb->cs_base == desc->cs_base && - tb->flags == desc->flags && + if (atomic_read(&tb->pc) == desc->pc && + atomic_read(&tb->page_addr[0]) == desc->phys_page1 && + atomic_read(&tb->cs_base) == desc->cs_base && + atomic_read(&tb->flags) == desc->flags && !atomic_read(&tb->invalid)) { /* check next page if needed */ - if (tb->page_addr[1] == -1) { + if (atomic_read(&tb->page_addr[1]) == -1) { return true; } else { tb_page_addr_t phys_page2; @@ -249,7 +249,7 @@ static bool tb_cmp(const void *p, const void *d) virt_page2 = (desc->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; phys_page2 = get_page_addr_code(desc->env, virt_page2); - if (tb->page_addr[1] == phys_page2) { + if (atomic_read(&tb->page_addr[1]) == phys_page2) { return true; } } @@ -507,7 +507,7 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb, return; } - trace_exec_tb(tb, tb->pc); + trace_exec_tb(tb, atomic_read(&tb->pc)); ret = cpu_tb_exec(cpu, tb); *last_tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK); *tb_exit = ret & TB_EXIT_MASK; diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index c3596a6..ff34a0d 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -200,6 +200,17 @@ static inline void tlb_flush_by_mmuidx(CPUState *cpu, ...) #define USE_DIRECT_JUMP #endif +/* + * TranslationBlock + * + * This structure represents a single translated block of code. The + * actual code is referenced via tc_ptr. This structure is accessed + * across multiple QEMU threads so for C11 compliance all fields + * should be access with at least relaxed atomic primitives. Fields + * that are updated after initial generation, mainly those involved + * with patching jumps and chaining TBs, need stronger guarantees to + * prevent corruption. + */ struct TranslationBlock { target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */ target_ulong cs_base; /* CS base for this block */ diff --git a/translate-all.c b/translate-all.c index 0f13d4d..a6262ae 100644 --- a/translate-all.c +++ b/translate-all.c @@ -773,9 +773,10 @@ static TranslationBlock *tb_alloc(target_ulong pc) return NULL; } tb = &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++]; - tb->pc = pc; - tb->cflags = 0; - tb->invalid = false; + + atomic_set(&tb->pc, pc); + atomic_set(&tb->cflags, 0); + atomic_set(&tb->invalid, false); return tb; } @@ -1095,7 +1096,7 @@ static inline void tb_alloc_page(TranslationBlock *tb, bool page_already_protected; #endif - tb->page_addr[n] = page_addr; + atomic_set(&tb->page_addr[n], page_addr); p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1); tb->page_next[n] = p->first_tb; #ifndef CONFIG_USER_ONLY @@ -1156,7 +1157,7 @@ static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, if (phys_page2 != -1) { tb_alloc_page(tb, 1, phys_page2); } else { - tb->page_addr[1] = -1; + atomic_set(&tb->page_addr[1], -1); } /* add in the hash table */