On Thu, May 2, 2024 at 5:39 AM Andrew Jones <ajo...@ventanamicro.com> wrote:
>
> On Tue, Apr 30, 2024 at 03:00:45PM GMT, Daniel Henrique Barboza wrote:
> >
> >
> > On 4/29/24 16:28, Atish Patra wrote:
> > > Currently, if a counter monitoring cycle/instret is stopped via
> > > mcountinhibit we just update the state while the value is saved
> > > during the next read. This is not accurate as the read may happen
> > > many cycles after the counter is stopped. Ideally, the read should
> > > return the value saved when the counter is stopped.
> > >
> > > Thus, save the value of the counter during the inhibit update
> > > operation and return that value during the read if corresponding bit
> > > in mcountihibit is set.
> > >
> > > Signed-off-by: Atish Patra <ati...@rivosinc.com>
> > > ---
> > >   target/riscv/cpu.h     |  1 -
> > >   target/riscv/csr.c     | 32 ++++++++++++++++++++------------
> > >   target/riscv/machine.c |  1 -
> > >   3 files changed, 20 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > > index 3b1a02b9449a..09bbf7ce9880 100644
> > > --- a/target/riscv/cpu.h
> > > +++ b/target/riscv/cpu.h
> > > @@ -153,7 +153,6 @@ typedef struct PMUCTRState {
> > >       target_ulong mhpmcounter_prev;
> > >       /* Snapshort value of a counter in RV32 */
> > >       target_ulong mhpmcounterh_prev;
> > > -    bool started;
> > >       /* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt 
> > > trigger */
> > >       target_ulong irq_overflow_left;
> > >   } PMUCTRState;
> > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > > index 726096444fae..68ca31aff47d 100644
> > > --- a/target/riscv/csr.c
> > > +++ b/target/riscv/csr.c
> > > @@ -929,17 +929,11 @@ static RISCVException 
> > > riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
> > >       if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
> > >           /*
> > > -         * Counter should not increment if inhibit bit is set. We can't 
> > > really
> > > -         * stop the icount counting. Just return the counter value 
> > > written by
> > > -         * the supervisor to indicate that counter was not incremented.
> > > +         * Counter should not increment if inhibit bit is set. Just 
> > > return the
> > > +         * current counter value.
> > >            */
> > > -        if (!counter->started) {
> > > -            *val = ctr_val;
> > > -            return RISCV_EXCP_NONE;
> > > -        } else {
> > > -            /* Mark that the counter has been stopped */
> > > -            counter->started = false;
> > > -        }
> > > +         *val = ctr_val;
> > > +         return RISCV_EXCP_NONE;
> > >       }
> > >       /*
> > > @@ -1973,9 +1967,23 @@ static RISCVException 
> > > write_mcountinhibit(CPURISCVState *env, int csrno,
> > >       /* Check if any other counter is also monitoring 
> > > cycles/instructions */
> > >       for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
> > > -        if (!get_field(env->mcountinhibit, BIT(cidx))) {
> > >               counter = &env->pmu_ctrs[cidx];
> > > -            counter->started = true;
> > > +        if (get_field(env->mcountinhibit, BIT(cidx)) && (val & 
> > > BIT(cidx))) {
> > > +       /*
> > > +             * Update the counter value for cycle/instret as we can't 
> > > stop the
> > > +             * host ticks. But we should show the current value at this 
> > > moment.
> > > +             */
> > > +            if (riscv_pmu_ctr_monitor_cycles(env, cidx) ||
> > > +                riscv_pmu_ctr_monitor_instructions(env, cidx)) {
> > > +                counter->mhpmcounter_val = get_ticks(false) -
> > > +                                           counter->mhpmcounter_prev +
> > > +                                           counter->mhpmcounter_val;
> > > +                if (riscv_cpu_mxl(env) == MXL_RV32) {
> > > +                    counter->mhpmcounterh_val = get_ticks(false) -
> > > +                                                
> > > counter->mhpmcounterh_prev +
> > > +                                                
> > > counter->mhpmcounterh_val;
> > > +           }
> > > +            }
> > >           }
> > >       }
> > > diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> > > index 76f2150f78b5..3e0f2dd2ce2a 100644
> > > --- a/target/riscv/machine.c
> > > +++ b/target/riscv/machine.c
> > > @@ -328,7 +328,6 @@ static const VMStateDescription vmstate_pmu_ctr_state 
> > > = {
> > >           VMSTATE_UINTTL(mhpmcounterh_val, PMUCTRState),
> > >           VMSTATE_UINTTL(mhpmcounter_prev, PMUCTRState),
> > >           VMSTATE_UINTTL(mhpmcounterh_prev, PMUCTRState),
> > > -        VMSTATE_BOOL(started, PMUCTRState),
> >
> > Unfortunately we can't remove fields from the VMStateDescription without 
> > breaking
> > migration backward compatibility. Older QEMUs will attempt to read a field 
> > that
> > doesn't exist and migration will fail.
> >
> > I'm assuming that we care about backward compat. If we're not up to this 
> > point yet
> > then we can just bump the version_id of vmstate_pmu_ctr_state and be done 
> > with it.
> > This is fine to do unless someone jumps in and complains that we broke a 
> > migration
> > case for the 'virt' board. Granted, we don't have versioned boards yet so 
> > I'm unsure
> > if someone would actually have a base to complain. Alistair, Drew, care to 
> > comment?
>
> Without versioning boards, then we shouldn't expect migrations to work for
> anything other than between QEMUs of the same version. We're delaying the
> versioning until it's reasonable to expect users to prefer to migrate
> their guests, rather than reboot them, when updating the QEMU the guests
> are running on. I'm not sure how we'll know when that is, but I think we
> can wait until somebody shouts or at least until we see that the tooling
> which makes migration easy (libvirt, etc.) is present.
>
> Regarding this patch, I'm curious what the current status is of migration.
> If we can currently migrate from a QEMU with the latest released version
> to a QEMU built from the current upstream, and then back again, then I

I haven't heard of anyone who actually uses migration in Qemu.
There is only one way to know about it when somebody complains.

I think we should just keep it simple and bump up the version  of
vmstate_pmu_ctr_state.
If somebody complains about backward compatibility, we can implement
compat code.
Otherwise, I don't see the point.

> think this patch should be written in a way to preserve that. If we
> already fail that ping-pong migration, then, as this patch doesn't make
> things worse, we might as well save ourselves from the burden of the
> compat code.
>
> Thanks,
> drew

Reply via email to