qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Joel Stanley <joel@jms.id.au>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, qemu-stable@nongnu.org
Subject: Re: [PATCH] hw/timer/nrf51_timer: Don't lose time when timer is queried in tight loop
Date: Wed, 7 Jun 2023 11:26:38 +0000	[thread overview]
Message-ID: <CACPK8Xd3_ets6btF9ULqjFn_eT55M8t8C+_iQXg-_eXGDLDWqw@mail.gmail.com> (raw)
In-Reply-To: <20230606134917.3782215-1-peter.maydell@linaro.org>

On Tue, 6 Jun 2023 at 13:49, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> The nrf51_timer has a free-running counter which we implement using
> the pattern of using two fields (update_counter_ns, counter) to track
> the last point at which we calculated the counter value, and the
> counter value at that time.  Then we can find the current counter
> value by converting the difference in wall-clock time between then
> and now to a tick count that we need to add to the counter value.
>
> Unfortunately the nrf51_timer's implementation of this has a bug
> which means it loses time every time update_counter() is called.
> After updating s->counter it always sets s->update_counter_ns to
> 'now', even though the actual point when s->counter hit the new value
> will be some point in the past (half a tick, say).  In the worst case
> (guest code in a tight loop reading the counter, icount mode) the
> counter is continually queried less than a tick after it was last
> read, so s->counter never advances but s->update_counter_ns does, and
> the guest never makes forward progress.
>
> The fix for this is to only advance update_counter_ns to the
> timestamp of the last tick, not all the way to 'now'.  (This is the
> pattern used in hw/misc/mps2-fpgaio.c's counter.)
>
> Cc: qemu-stable@nongnu.org
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> The hang in icount mode was discovered by the Zephyr folks as part
> of their investigation into
> https://github.com/zephyrproject-rtos/zephyr/issues/57512

Did you get an image to test with?

Reviewed-by: Joel Stanley <joel@jms.id.au>

>
>  hw/timer/nrf51_timer.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/hw/timer/nrf51_timer.c b/hw/timer/nrf51_timer.c
> index 42be79c7363..50c6772383e 100644
> --- a/hw/timer/nrf51_timer.c
> +++ b/hw/timer/nrf51_timer.c
> @@ -45,7 +45,12 @@ static uint32_t update_counter(NRF51TimerState *s, int64_t now)
>      uint32_t ticks = ns_to_ticks(s, now - s->update_counter_ns);
>
>      s->counter = (s->counter + ticks) % BIT(bitwidths[s->bitmode]);
> -    s->update_counter_ns = now;
> +    /*
> +     * Only advance the sync time to the timestamp of the last tick,
> +     * not all the way to 'now', so we don't lose time if we do
> +     * multiple resyncs in a single tick.
> +     */
> +    s->update_counter_ns += ticks_to_ns(s, ticks);
>      return ticks;

We're still returning the number of ticks up to 'now'. Should we
instead return the elapsed ticks? If not, we will expire the timer
early.

Cheers,

Joel


  reply	other threads:[~2023-06-07 11:27 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-06 13:49 [PATCH] hw/timer/nrf51_timer: Don't lose time when timer is queried in tight loop Peter Maydell
2023-06-07 11:26 ` Joel Stanley [this message]
2023-06-07 13:03   ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CACPK8Xd3_ets6btF9ULqjFn_eT55M8t8C+_iQXg-_eXGDLDWqw@mail.gmail.com \
    --to=joel@jms.id.au \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-stable@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).