[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 2/2] hw/timer/slavio_timer.c: Switch to transaction-based pti
From: |
Peter Maydell |
Subject: |
Re: [PATCH 2/2] hw/timer/slavio_timer.c: Switch to transaction-based ptimer API |
Date: |
Thu, 17 Oct 2019 16:00:43 +0100 |
On Thu, 17 Oct 2019 at 15:54, Philippe Mathieu-Daudé <address@hidden> wrote:
>
> Hi Peter,
>
> On 10/17/19 3:23 PM, Peter Maydell wrote:
> > Switch the slavio_timer code away from bottom-half based ptimers to
> > the new transaction-based ptimer API. This just requires adding
> > begin/commit calls around the various places that modify the ptimer
> > state, and using the new ptimer_init() function to create the timer.
> >
> > Signed-off-by: Peter Maydell <address@hidden>
> > ---
> > hw/timer/slavio_timer.c | 20 ++++++++++++++++----
> > 1 file changed, 16 insertions(+), 4 deletions(-)
> >
> > diff --git a/hw/timer/slavio_timer.c b/hw/timer/slavio_timer.c
> > index 692d213897d..0e2efe6fe89 100644
> > --- a/hw/timer/slavio_timer.c
> > +++ b/hw/timer/slavio_timer.c
> > @@ -30,7 +30,6 @@
> > #include "hw/sysbus.h"
> > #include "migration/vmstate.h"
> > #include "trace.h"
> > -#include "qemu/main-loop.h"
> > #include "qemu/module.h"
> >
> > /*
> > @@ -213,6 +212,7 @@ static void slavio_timer_mem_writel(void *opaque,
> > hwaddr addr,
> > saddr = addr >> 2;
> > switch (saddr) {
> > case TIMER_LIMIT:
> > + ptimer_transaction_begin(t->timer);
> > if (slavio_timer_is_user(tc)) {
> > uint64_t count;
>
>
> This part is odd since there is a check on t->timer != NULL later, and
> ptimer_transaction_commit() can't take NULL.
Hmm, I hadn't noticed that. I think the bug is the check
for NULL, though, beacuse the slavio_timer_init() function
always initializes all the timer pointers, so there's
no situation where the pointer can be non-NULL as far
as I can see. So I think I'd rather fix this by removing
the NULL pointer check...
> > @@ -255,13 +258,16 @@ static void slavio_timer_mem_writel(void *opaque,
> > hwaddr addr,
> > case TIMER_COUNTER_NORST:
> > // set limit without resetting counter
> > t->limit = val & TIMER_MAX_COUNT32;
> > + ptimer_transaction_begin(t->timer);
> > if (t->limit == 0) { /* free-run */
> > ptimer_set_limit(t->timer,
> > LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 0);
> > } else {
> > ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 0);
> > }
> > + ptimer_transaction_commit(t->timer);
> > break;
> > case TIMER_STATUS:
> > + ptimer_transaction_begin(t->timer);
> > if (slavio_timer_is_user(tc)) {
>
> I'd move the begin() here.
This would be awkward because then it won't neatly nest with
the commit call unless you add an extra if() for the
commit or otherwise rearrange/duplicate code...
> > // start/stop user counter
> > if (val & 1) {
> > @@ -273,6 +279,7 @@ static void slavio_timer_mem_writel(void *opaque,
> > hwaddr addr,
> > }
> > }
> > t->run = val & 1;
> > + ptimer_transaction_commit(t->timer);
...because the commit should come after we have finished
updating the timer state (t->run in this case), because
the trigger callback slavio_timer_irq() otherwise sees
inconsistent half-updated state if commit() calls it.
thanks
-- PMM
[PATCH 1/2] hw/timer/grlib_gptimer.c: Switch to transaction-based ptimer API, Peter Maydell, 2019/10/17
Re: [PATCH 0/2] Convert sparc devices to new ptimer API, Mark Cave-Ayland, 2019/10/20