Message ID | f01281f814ceba088595917eb06d4cb21db820f1.1606884132.git.pcc@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v3,1/3] Revert "hvf: Actually set SIG_IPI mask" | expand |
On 02.12.20 05:44, Peter Collingbourne wrote: > Sleep on WFI until the VTIMER is due but allow ourselves to be woken > up on IPI. > > Signed-off-by: Peter Collingbourne <pcc@google.com> > --- > v3: > - move the simplified locking to a separate patch > - spin on sleep <2ms > > v2: > - simplify locking further > - wait indefinitely on disabled or masked timers > > accel/hvf/hvf-cpus.c | 4 +-- > include/sysemu/hvf_int.h | 1 + > target/arm/hvf/hvf.c | 56 ++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 59 insertions(+), 2 deletions(-) > > diff --git a/accel/hvf/hvf-cpus.c b/accel/hvf/hvf-cpus.c > index e613c22ad0..b2c8fb57f6 100644 > --- a/accel/hvf/hvf-cpus.c > +++ b/accel/hvf/hvf-cpus.c > @@ -344,8 +344,8 @@ static int hvf_init_vcpu(CPUState *cpu) > sigact.sa_handler = dummy_signal; > sigaction(SIG_IPI, &sigact, NULL); > > - pthread_sigmask(SIG_BLOCK, NULL, &set); > - sigdelset(&set, SIG_IPI); > + pthread_sigmask(SIG_BLOCK, NULL, &cpu->hvf->unblock_ipi_mask); > + sigdelset(&cpu->hvf->unblock_ipi_mask, SIG_IPI); That turns set into an unused variable, no? I'll fix it up while applying though. The rest looks great, I'll push it as part of my next patch set. Alex
On Wed, Dec 2, 2020 at 10:49 AM Alexander Graf <agraf@csgraf.de> wrote: > > > On 02.12.20 05:44, Peter Collingbourne wrote: > > Sleep on WFI until the VTIMER is due but allow ourselves to be woken > > up on IPI. > > > > Signed-off-by: Peter Collingbourne <pcc@google.com> > > --- > > v3: > > - move the simplified locking to a separate patch > > - spin on sleep <2ms > > > > v2: > > - simplify locking further > > - wait indefinitely on disabled or masked timers > > > > accel/hvf/hvf-cpus.c | 4 +-- > > include/sysemu/hvf_int.h | 1 + > > target/arm/hvf/hvf.c | 56 ++++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 59 insertions(+), 2 deletions(-) > > > > diff --git a/accel/hvf/hvf-cpus.c b/accel/hvf/hvf-cpus.c > > index e613c22ad0..b2c8fb57f6 100644 > > --- a/accel/hvf/hvf-cpus.c > > +++ b/accel/hvf/hvf-cpus.c > > @@ -344,8 +344,8 @@ static int hvf_init_vcpu(CPUState *cpu) > > sigact.sa_handler = dummy_signal; > > sigaction(SIG_IPI, &sigact, NULL); > > > > - pthread_sigmask(SIG_BLOCK, NULL, &set); > > - sigdelset(&set, SIG_IPI); > > + pthread_sigmask(SIG_BLOCK, NULL, &cpu->hvf->unblock_ipi_mask); > > + sigdelset(&cpu->hvf->unblock_ipi_mask, SIG_IPI); > > > That turns set into an unused variable, no? I'll fix it up while > applying though. The rest looks great, I'll push it as part of my next > patch set. Yes, thanks for spotting that, your fixup looks good. Peter
diff --git a/accel/hvf/hvf-cpus.c b/accel/hvf/hvf-cpus.c index e613c22ad0..b2c8fb57f6 100644 --- a/accel/hvf/hvf-cpus.c +++ b/accel/hvf/hvf-cpus.c @@ -344,8 +344,8 @@ static int hvf_init_vcpu(CPUState *cpu) sigact.sa_handler = dummy_signal; sigaction(SIG_IPI, &sigact, NULL); - pthread_sigmask(SIG_BLOCK, NULL, &set); - sigdelset(&set, SIG_IPI); + pthread_sigmask(SIG_BLOCK, NULL, &cpu->hvf->unblock_ipi_mask); + sigdelset(&cpu->hvf->unblock_ipi_mask, SIG_IPI); #ifdef __aarch64__ r = hv_vcpu_create(&cpu->hvf->fd, (hv_vcpu_exit_t **)&cpu->hvf->exit, NULL); diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h index 5f15119184..13adf6ea77 100644 --- a/include/sysemu/hvf_int.h +++ b/include/sysemu/hvf_int.h @@ -62,6 +62,7 @@ extern HVFState *hvf_state; struct hvf_vcpu_state { uint64_t fd; void *exit; + sigset_t unblock_ipi_mask; }; void assert_hvf_ok(hv_return_t ret); diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 31db6fca68..f230193cf5 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -2,6 +2,7 @@ * QEMU Hypervisor.framework support for Apple Silicon * Copyright 2020 Alexander Graf <agraf@csgraf.de> + * Copyright 2020 Google LLC * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. @@ -18,6 +19,7 @@ #include "sysemu/hw_accel.h" #include <Hypervisor/Hypervisor.h> +#include <mach/mach_time.h> #include "exec/address-spaces.h" #include "hw/irq.h" @@ -320,6 +322,7 @@ int hvf_arch_init_vcpu(CPUState *cpu) void hvf_kick_vcpu_thread(CPUState *cpu) { + cpus_kick_thread(cpu); hv_vcpus_exit(&cpu->hvf->fd, 1); } @@ -338,6 +341,18 @@ static int hvf_inject_interrupts(CPUState *cpu) return 0; } +static void hvf_wait_for_ipi(CPUState *cpu, struct timespec *ts) +{ + /* + * Use pselect to sleep so that other threads can IPI us while we're + * sleeping. + */ + qatomic_mb_set(&cpu->thread_kicked, false); + qemu_mutex_unlock_iothread(); + pselect(0, 0, 0, 0, ts, &cpu->hvf->unblock_ipi_mask); + qemu_mutex_lock_iothread(); +} + int hvf_vcpu_exec(CPUState *cpu) { ARMCPU *arm_cpu = ARM_CPU(cpu); @@ -466,6 +481,47 @@ int hvf_vcpu_exec(CPUState *cpu) break; } case EC_WFX_TRAP: + if (!(syndrome & WFX_IS_WFE) && !(cpu->interrupt_request & + (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIQ))) { + advance_pc = true; + + uint64_t ctl; + r = hv_vcpu_get_sys_reg(cpu->hvf->fd, HV_SYS_REG_CNTV_CTL_EL0, + &ctl); + assert_hvf_ok(r); + + if (!(ctl & 1) || (ctl & 2)) { + /* Timer disabled or masked, just wait for an IPI. */ + hvf_wait_for_ipi(cpu, NULL); + break; + } + + uint64_t cval; + r = hv_vcpu_get_sys_reg(cpu->hvf->fd, HV_SYS_REG_CNTV_CVAL_EL0, + &cval); + assert_hvf_ok(r); + + int64_t ticks_to_sleep = cval - mach_absolute_time(); + if (ticks_to_sleep < 0) { + break; + } + + uint64_t seconds = ticks_to_sleep / arm_cpu->gt_cntfrq_hz; + uint64_t nanos = + (ticks_to_sleep - arm_cpu->gt_cntfrq_hz * seconds) * + 1000000000 / arm_cpu->gt_cntfrq_hz; + + /* + * Don't sleep for less than 2ms. This is believed to improve + * latency of message passing workloads. + */ + if (!seconds && nanos < 2000000) { + break; + } + + struct timespec ts = { seconds, nanos }; + hvf_wait_for_ipi(cpu, &ts); + } break; case EC_AA64_HVC: cpu_synchronize_state(cpu);
Sleep on WFI until the VTIMER is due but allow ourselves to be woken up on IPI. Signed-off-by: Peter Collingbourne <pcc@google.com> --- v3: - move the simplified locking to a separate patch - spin on sleep <2ms v2: - simplify locking further - wait indefinitely on disabled or masked timers accel/hvf/hvf-cpus.c | 4 +-- include/sysemu/hvf_int.h | 1 + target/arm/hvf/hvf.c | 56 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-)