From nobody Tue Apr 8 22:27:32 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; 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 1539714380834299.14016381558315; Tue, 16 Oct 2018 11:26:20 -0700 (PDT) Received: from localhost ([::1]:59600 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gCU2t-0004Yi-AT for importer@patchew.org; Tue, 16 Oct 2018 14:26:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59958) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gCTTZ-0004EV-4T for qemu-devel@nongnu.org; Tue, 16 Oct 2018 13:49:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gCTTX-0001Ip-Ak for qemu-devel@nongnu.org; Tue, 16 Oct 2018 13:49:49 -0400 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]:39644) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gCTTW-0001Hf-Vg for qemu-devel@nongnu.org; Tue, 16 Oct 2018 13:49:47 -0400 Received: by mail-pl1-x631.google.com with SMTP id e67-v6so2385881plb.6 for ; Tue, 16 Oct 2018 10:49:46 -0700 (PDT) Received: from cloudburst.twiddle.net (174-21-9-133.tukw.qwest.net. [174.21.9.133]) by smtp.gmail.com with ESMTPSA id 6-v6sm17441210pgl.6.2018.10.16.10.49.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 16 Oct 2018 10:49:44 -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=UaQoW0X3h57lcIqJE5IM63G9fD5eqtJkNjrcpKzJ3Eo=; b=da6er6zZUBzMXAJjJ6VlSmoCVZvsF6Jf7fu3/bnMHc8oQGwOCmlYoHk6CuAgFdRagd 2i39PGiCC/LKPKha/OupH42MKBg2i8N+G8JaRBuRt8aF2tgcoOEkmVzR3zNNya/jWHab d/uBpZvfDBf0RWJXtoQlMjetljym+j3reTGNE= 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=UaQoW0X3h57lcIqJE5IM63G9fD5eqtJkNjrcpKzJ3Eo=; b=j999uTVeZEVlkmHbPzoO0oYKcEFPZYcCZO1QH7MCyzt3KnPtUdbskNZ1BntA5DksZY u75U7ZzB+5p4yeY6W7OLw8XVBFHTAcywHJTN02bn0NpNawL080OO/qbNcSx+Qb9b4sEE NPscAnQrF3J7SP87owuYJ3zoXqUYXmAE5BfuKtLj+kd7MIc0B2bhw8QAwhhcDuPHFUje ErBzi/xREw/GC0p4eGhih6OPUX+ynvxAJvvceADjGKaclIEGDmypploUTCuuQaktLQ3W +Gtz5HL4YNgjrFPZ9ckD/pkRSwy0PlwZSUBAYB3Nvl/aUGT5TbdadtYlNsPhXnFzJuAJ tNmA== X-Gm-Message-State: ABuFfoiPnW7ZdbCOXfTHIdipSbKcwL/QgxRKaYikczKOylnL+FW+D07g vq9Ko2yPg3UGtSQzIog/SxzslUmYlGE= X-Google-Smtp-Source: ACcGV62fh2db1v0bOIRat/mvHr4zP3nD8kMXFks/4O8GiPCObQg0/9FUJCfslsRJSPxvJ92Lwno1yg== X-Received: by 2002:a17:902:b104:: with SMTP id q4-v6mr22440679plr.238.1539712185513; Tue, 16 Oct 2018 10:49:45 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 16 Oct 2018 10:49:11 -0700 Message-Id: <20181016174911.9052-22-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181016174911.9052-1-richard.henderson@linaro.org> References: <20181016174911.9052-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::631 Subject: [Qemu-devel] [PULL 21/21] cputlb: read CPUTLBEntry.addr_write 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: peter.maydell@linaro.org, "Emilio G. Cota" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Emilio G. Cota" Updates can come from other threads, so readers that do not take tlb_lock must use atomic_read to avoid undefined behaviour (UB). This completes the conversion to tlb_lock. This conversion results on average in no performance loss, as the following experiments (run on an Intel i7-6700K CPU @ 4.00GHz) show. 1. aarch64 bootup+shutdown test: - Before: Performance counter stats for 'taskset -c 0 ../img/aarch64/die.sh' (10 run= s): 7487.087786 task-clock (msec) # 0.998 CPUs utilized = ( +- 0.12% ) 31,574,905,303 cycles # 4.217 GHz = ( +- 0.12% ) 57,097,908,812 instructions # 1.81 insns per cycl= e ( +- 0.08% ) 10,255,415,367 branches # 1369.747 M/sec = ( +- 0.08% ) 173,278,962 branch-misses # 1.69% of all branche= s ( +- 0.18% ) 7.504481349 seconds time elapsed = ( +- 0.14% ) - After: Performance counter stats for 'taskset -c 0 ../img/aarch64/die.sh' (10 run= s): 7462.441328 task-clock (msec) # 0.998 CPUs utilized = ( +- 0.07% ) 31,478,476,520 cycles # 4.218 GHz = ( +- 0.07% ) 57,017,330,084 instructions # 1.81 insns per cycl= e ( +- 0.05% ) 10,251,929,667 branches # 1373.804 M/sec = ( +- 0.05% ) 173,023,787 branch-misses # 1.69% of all branche= s ( +- 0.11% ) 7.474970463 seconds time elapsed = ( +- 0.07% ) 2. SPEC06int: SPEC06int (test set) [Y axis: Speedup over master] 1.15 +-+----+------+------+------+------+------+-------+------+------+---= ---+------+------+------+----+-+ | = | 1.1 +-+.................................+++.............................= + tlb-lock-v2 (m+++x) +-+ | +++ | +++ = tlb-lock-v3 (spinl|ck) | | +++ | | +++ +++ | = | | 1.05 +-+....+++...........####.........|####.+++.|......|.....###....+++.= ..........+++....###.........+-+ | ### ++#| # |# |# ***### +++### +++#+# | = +++ | #|# ### | 1 +-+++***+#++++####+++#++#++++++++++#++#+*+*++#++++#+#+****+#++++###+= +++###++++###++++#+#++++#+#+++-+ | *+* # #++# *** # #### *** # * *++# ****+# *| * # ****|# = |# # #|# #+# # # | 0.95 +-+..*.*.#....#..#.*|*..#...#..#.*|*..#.*.*..#.*|.*.#.*++*.#.*++*+#.= ****.#....#+#....#.#..++#.#..+-+ | * * # # # *|* # # # *|* # * * # *++* # * * # * * # = * |* # ++# # # # *** # | | * * # ++# # *+* # # # *|* # * * # * * # * * # * * # = *++* # **** # ++# # * * # | 0.9 +-+..*.*.#...|#..#.*.*..#.++#..#.*|*..#.*.*..#.*..*.#.*..*.#.*..*.#.= *..*.#.*.|*.#...|#.#..*.*.#..+-+ | * * # *** # * * # |# # *+* # * * # * * # * * # * * # = * * # *++* # |# # * * # | 0.85 +-+..*.*.#..*|*..#.*.*..#.***..#.*.*..#.*.*..#.*..*.#.*..*.#.*..*.#.= *..*.#.*..*.#.****.#..*.*.#..+-+ | * * # *+* # * * # *|* # * * # * * # * * # * * # * * # = * * # * * # * |* # * * # | | * * # * * # * * # *+* # * * # * * # * * # * * # * * # = * * # * * # * |* # * * # | 0.8 +-+..*.*.#..*.*..#.*.*..#.*.*..#.*.*..#.*.*..#.*..*.#.*..*.#.*..*.#.= *..*.#.*..*.#.*++*.#..*.*.#..+-+ | * * # * * # * * # * * # * * # * * # * * # * * # * * # = * * # * * # * * # * * # | 0.75 +-+--***##--***###-***###-***###-***###-***###-****##-****##-****##-= ****##-****##-****##--***##--+-+ 400.perlben401.bzip2403.gcc429.m445.gob456.hmme45462.libqua464.h26471.omne= t473483.xalancbmkgeomean png: https://imgur.com/a/BHzpPTW Notes: - tlb-lock-v2 corresponds to an implementation with a mutex. - tlb-lock-v3 corresponds to the current implementation, i.e. a spinlock and a single lock acquisition in tlb_set_page_with_attrs. Signed-off-by: Emilio G. Cota Message-Id: <20181016153840.25877-1-cota@braap.org> Signed-off-by: Richard Henderson --- accel/tcg/softmmu_template.h | 12 ++++++------ include/exec/cpu_ldst.h | 11 ++++++++++- include/exec/cpu_ldst_template.h | 2 +- accel/tcg/cputlb.c | 19 +++++++++++++------ 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/accel/tcg/softmmu_template.h b/accel/tcg/softmmu_template.h index 09538b5349..b0adea045e 100644 --- a/accel/tcg/softmmu_template.h +++ b/accel/tcg/softmmu_template.h @@ -280,7 +280,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong = addr, DATA_TYPE val, uintptr_t mmu_idx =3D get_mmuidx(oi); uintptr_t index =3D tlb_index(env, mmu_idx, addr); CPUTLBEntry *entry =3D tlb_entry(env, mmu_idx, addr); - target_ulong tlb_addr =3D entry->addr_write; + target_ulong tlb_addr =3D tlb_addr_write(entry); unsigned a_bits =3D get_alignment_bits(get_memop(oi)); uintptr_t haddr; =20 @@ -295,7 +295,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong = addr, DATA_TYPE val, tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE, mmu_idx, retaddr); } - tlb_addr =3D entry->addr_write & ~TLB_INVALID_MASK; + tlb_addr =3D tlb_addr_write(entry) & ~TLB_INVALID_MASK; } =20 /* Handle an IO access. */ @@ -325,7 +325,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong = addr, DATA_TYPE val, cannot evict the first. */ page2 =3D (addr + DATA_SIZE) & TARGET_PAGE_MASK; entry2 =3D tlb_entry(env, mmu_idx, page2); - if (!tlb_hit_page(entry2->addr_write, page2) + if (!tlb_hit_page(tlb_addr_write(entry2), page2) && !VICTIM_TLB_HIT(addr_write, page2)) { tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE, mmu_idx, retaddr); @@ -358,7 +358,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong = addr, DATA_TYPE val, uintptr_t mmu_idx =3D get_mmuidx(oi); uintptr_t index =3D tlb_index(env, mmu_idx, addr); CPUTLBEntry *entry =3D tlb_entry(env, mmu_idx, addr); - target_ulong tlb_addr =3D entry->addr_write; + target_ulong tlb_addr =3D tlb_addr_write(entry); unsigned a_bits =3D get_alignment_bits(get_memop(oi)); uintptr_t haddr; =20 @@ -373,7 +373,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong = addr, DATA_TYPE val, tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE, mmu_idx, retaddr); } - tlb_addr =3D entry->addr_write & ~TLB_INVALID_MASK; + tlb_addr =3D tlb_addr_write(entry) & ~TLB_INVALID_MASK; } =20 /* Handle an IO access. */ @@ -403,7 +403,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong = addr, DATA_TYPE val, cannot evict the first. */ page2 =3D (addr + DATA_SIZE) & TARGET_PAGE_MASK; entry2 =3D tlb_entry(env, mmu_idx, page2); - if (!tlb_hit_page(entry2->addr_write, page2) + if (!tlb_hit_page(tlb_addr_write(entry2), page2) && !VICTIM_TLB_HIT(addr_write, page2)) { tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE, mmu_idx, retaddr); diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h index f54d91ff68..959068495a 100644 --- a/include/exec/cpu_ldst.h +++ b/include/exec/cpu_ldst.h @@ -126,6 +126,15 @@ extern __thread uintptr_t helper_retaddr; /* The memory helpers for tcg-generated code need tcg_target_long etc. */ #include "tcg.h" =20 +static inline target_ulong tlb_addr_write(const CPUTLBEntry *entry) +{ +#if TCG_OVERSIZED_GUEST + return entry->addr_write; +#else + return atomic_read(&entry->addr_write); +#endif +} + /* Find the TLB index corresponding to the mmu_idx + address pair. */ static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx, target_ulong addr) @@ -439,7 +448,7 @@ static inline void *tlb_vaddr_to_host(CPUArchState *env= , abi_ptr addr, tlb_addr =3D tlbentry->addr_read; break; case 1: - tlb_addr =3D tlbentry->addr_write; + tlb_addr =3D tlb_addr_write(tlbentry); break; case 2: tlb_addr =3D tlbentry->addr_code; diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_templ= ate.h index d21a0b59bf..0f061d47ef 100644 --- a/include/exec/cpu_ldst_template.h +++ b/include/exec/cpu_ldst_template.h @@ -177,7 +177,7 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArc= hState *env, addr =3D ptr; mmu_idx =3D CPU_MMU_INDEX; entry =3D tlb_entry(env, mmu_idx, addr); - if (unlikely(entry->addr_write !=3D + if (unlikely(tlb_addr_write(entry) !=3D (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { oi =3D make_memop_idx(SHIFT, mmu_idx); glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi, diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 28b770a404..af57aca5e4 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -258,7 +258,7 @@ static inline bool tlb_hit_page_anyprot(CPUTLBEntry *tl= b_entry, target_ulong page) { return tlb_hit_page(tlb_entry->addr_read, page) || - tlb_hit_page(tlb_entry->addr_write, page) || + tlb_hit_page(tlb_addr_write(tlb_entry), page) || tlb_hit_page(tlb_entry->addr_code, page); } =20 @@ -855,7 +855,7 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry = *iotlbentry, tlb_fill(cpu, addr, size, MMU_DATA_STORE, mmu_idx, retaddr); =20 entry =3D tlb_entry(env, mmu_idx, addr); - tlb_addr =3D entry->addr_write; + tlb_addr =3D tlb_addr_write(entry); if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) { /* RAM access */ uintptr_t haddr =3D addr + entry->addend; @@ -904,7 +904,14 @@ static bool victim_tlb_hit(CPUArchState *env, size_t m= mu_idx, size_t index, assert_cpu_is_self(ENV_GET_CPU(env)); for (vidx =3D 0; vidx < CPU_VTLB_SIZE; ++vidx) { CPUTLBEntry *vtlb =3D &env->tlb_v_table[mmu_idx][vidx]; - target_ulong cmp =3D *(target_ulong *)((uintptr_t)vtlb + elt_ofs); + target_ulong cmp; + + /* elt_ofs might correspond to .addr_write, so use atomic_read */ +#if TCG_OVERSIZED_GUEST + cmp =3D *(target_ulong *)((uintptr_t)vtlb + elt_ofs); +#else + cmp =3D atomic_read((target_ulong *)((uintptr_t)vtlb + elt_ofs)); +#endif =20 if (cmp =3D=3D page) { /* Found entry in victim tlb, swap tlb and iotlb. */ @@ -977,7 +984,7 @@ void probe_write(CPUArchState *env, target_ulong addr, = int size, int mmu_idx, uintptr_t index =3D tlb_index(env, mmu_idx, addr); CPUTLBEntry *entry =3D tlb_entry(env, mmu_idx, addr); =20 - if (!tlb_hit(entry->addr_write, addr)) { + if (!tlb_hit(tlb_addr_write(entry), addr)) { /* TLB entry is for a different page */ if (!VICTIM_TLB_HIT(addr_write, addr)) { tlb_fill(ENV_GET_CPU(env), addr, size, MMU_DATA_STORE, @@ -995,7 +1002,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, targ= et_ulong addr, size_t mmu_idx =3D get_mmuidx(oi); uintptr_t index =3D tlb_index(env, mmu_idx, addr); CPUTLBEntry *tlbe =3D tlb_entry(env, mmu_idx, addr); - target_ulong tlb_addr =3D tlbe->addr_write; + target_ulong tlb_addr =3D tlb_addr_write(tlbe); TCGMemOp mop =3D get_memop(oi); int a_bits =3D get_alignment_bits(mop); int s_bits =3D mop & MO_SIZE; @@ -1026,7 +1033,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, tar= get_ulong addr, tlb_fill(ENV_GET_CPU(env), addr, 1 << s_bits, MMU_DATA_STORE, mmu_idx, retaddr); } - tlb_addr =3D tlbe->addr_write & ~TLB_INVALID_MASK; + tlb_addr =3D tlb_addr_write(tlbe) & ~TLB_INVALID_MASK; } =20 /* Notice an IO access or a needs-MMU-lookup access */ --=20 2.17.2