hexagon_cpu_mmu_index() runs very often - each TB. Taking the BQL to read syscfg is overkill.
Signed-off-by: Brian Cain <[email protected]> --- include/hw/hexagon/hexagon_globalreg.h | 6 ++++++ hw/hexagon/hexagon_globalreg.c | 9 +++++++-- target/hexagon/cpu.c | 9 ++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/hw/hexagon/hexagon_globalreg.h b/include/hw/hexagon/hexagon_globalreg.h index 2d5c3c166b1..dfd21e78663 100644 --- a/include/hw/hexagon/hexagon_globalreg.h +++ b/include/hw/hexagon/hexagon_globalreg.h @@ -59,6 +59,12 @@ uint32_t hexagon_globalreg_masked_value(HexagonGlobalRegState *s, uint32_t reg, void hexagon_globalreg_write_masked(HexagonGlobalRegState *s, uint32_t reg, uint32_t value); +/* + * SYSCFG, without the BQL: for the translator, which asks for it on every + * translation block lookup and can't afford to contend for the lock. + */ +uint32_t hexagon_globalreg_read_syscfg_unlocked(HexagonGlobalRegState *s); + /* Global performance cycle counter access */ uint64_t hexagon_globalreg_read_pcycle(HexagonGlobalRegState *s); uint64_t hexagon_globalreg_get_pcycle_base(HexagonGlobalRegState *s); diff --git a/hw/hexagon/hexagon_globalreg.c b/hw/hexagon/hexagon_globalreg.c index 22ec4020665..8b50fec770a 100644 --- a/hw/hexagon/hexagon_globalreg.c +++ b/hw/hexagon/hexagon_globalreg.c @@ -252,7 +252,7 @@ static uint32_t get_reg_value(HexagonGlobalRegState *s, uint32_t reg) return reg == HEX_SREG_PCYCLELO ? (uint32_t)value : (uint32_t)(value >> 32); } - return s->regs[reg]; + return qatomic_read(&s->regs[reg]); } static void set_reg_value(HexagonGlobalRegState *s, uint32_t reg, @@ -266,7 +266,7 @@ static void set_reg_value(HexagonGlobalRegState *s, uint32_t reg, return; } - s->regs[reg] = value; + qatomic_set(&s->regs[reg], value); if (pcycle_enable) { s->g_pcycle_base = 0; if (s->pcycle_running) { @@ -281,6 +281,11 @@ static void set_reg_value(HexagonGlobalRegState *s, uint32_t reg, } } +uint32_t hexagon_globalreg_read_syscfg_unlocked(HexagonGlobalRegState *s) +{ + return s ? qatomic_read(&s->regs[HEX_SREG_SYSCFG]) : 0; +} + uint32_t hexagon_globalreg_read(HexagonGlobalRegState *s, uint32_t reg, uint32_t htid) { diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index 281d201250b..607dddf7e7c 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -572,11 +572,14 @@ static int hexagon_cpu_mmu_index(CPUState *cs, bool ifetch) HexagonCPU *cpu = HEXAGON_CPU(cs); int cpu_mode; - BQL_LOCK_GUARD(); + /* + * No BQL: this runs for every translation block lookup, and the vCPU + * threads would otherwise queue up on it. SYSCFG is read atomically and + * the rest is this vCPU's own state. + */ if (cpu->globalregs) { uint32_t syscfg = - hexagon_globalreg_read(cpu->globalregs, HEX_SREG_SYSCFG, - env->threadId); + hexagon_globalreg_read_syscfg_unlocked(cpu->globalregs); uint8_t mmuen = GET_SYSCFG_FIELD(SYSCFG_MMUEN, syscfg); if (!mmuen) { return MMU_KERNEL_IDX; -- 2.34.1
