OpenSBI Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: Anup Patel <anup@brainfault.org>
Cc: Anup Patel <anup.patel@oss.qualcomm.com>,
	 Atish Patra <atish.patra@linux.dev>,
	Andrew Jones <andrew.jones@oss.qualcomm.com>,
	 Samuel Holland <samuel.holland@sifive.com>,
	opensbi@lists.infradead.org
Subject: Re: [PATCH 3/3] lib: sbi_timer: Add support for timer events
Date: Fri, 24 Apr 2026 11:09:16 +1000	[thread overview]
Message-ID: <aerAIAyFzMGCKy8H@lima-default> (raw)
In-Reply-To: <CAAhSdy1j83c6a6gaWXcBm81a1QrnQLfkUZF5ds05u0_AUn-hOA@mail.gmail.com>

On Thu, Apr 23, 2026 at 01:55:59PM +0530, Anup Patel wrote:
> On Thu, Apr 23, 2026 at 12:24 PM Nicholas Piggin <npiggin@gmail.com> wrote:
> >
> > On Wed, Apr 15, 2026 at 04:30:02PM +0530, Anup Patel wrote:

> > > +void sbi_timer_event_start(struct sbi_timer_event *ev, u64 next_event)
> > > +{
> > > +     struct sbi_timer_event *tev, *next_ev = NULL;
> > > +     struct timer_state *tstate;
> > > +
> > > +     if (!ev)
> > > +             return;
> > > +
> > > +     /* Ensure that event is not on the per-HART event list */
> > > +     if (ev->hart_index > -1) {
> >
> > It is a bit worrying to permit sbi_timer_event_start() if the timer is
> > already on a list. Is that necessary, or could you return an error in
> > this case?
> >
> > I'm thinking problems like this -
> >
> > HART0                         HART1
> > sbi_timer_event_start()       sbi_timer_process()
> >
> >   if (hart_index > -1) {
> >                                 __sbi_timer_event_stop(ev)
> >                                 if (ev->callback) {
> >                                   spin_unlock();
> >     spin_lock();
> >     __sbi_timer_event_stop(ev)
> >     spin_unlock();
> >                                   callback_fn()
> >                                     sbi_timer_event_start(); /* re-add periodic timer */
> 
> It is generally good to have ability to stop a running timer
> event from any CPU but I agree the problem you are highlighting.
> I think the real problem in this patch is the spin_unlock()/spin_lock()
> dance around the callback function called by sbi_timer_process().
> 
> To avoid the spin_unlock()/spin_lock() dance in sbi_timer_process(),
> I think it is better to call the callback function with lock held and callback
> function can optionally return next_time_stamp if it wants to re-add
> periodic timer. Suggestions ?

Yes, if the timer callbacks are fine with it, then the simpler the better.

Returning next_time_stamp if a reschedule is needed seems reasonable to
me. sbi_timer_event_start_from_callback() would be okay too.

> > > +             tstate = sbi_scratch_offset_ptr(sbi_hartindex_to_scratch(ev->hart_index),
> > > +                                             timer_state_off);
> > > +             spin_lock(&tstate->event_list_lock);
> > > +             __sbi_timer_event_stop(ev);
> > > +             spin_unlock(&tstate->event_list_lock);
> > > +     }
> > > +
> > > +     tstate = sbi_scratch_thishart_offset_ptr(timer_state_off);
> > > +     spin_lock(&tstate->event_list_lock);
> > > +
> > > +     /* Find where to insert the event in per-HART event list */
> > > +     sbi_list_for_each_entry(tev, &tstate->event_list, head) {
> > > +             if (next_event < tev->time_stamp) {
> > > +                     next_ev = tev;
> > > +                     break;
> > > +             }
> > > +     }
> > > +
> > > +     /* Insert the event in per-HART event list */
> > > +     ev->hart_index = current_hartindex();
> > > +     ev->time_stamp = next_event;
> > > +     if (next_ev)
> > > +             sbi_list_add(&ev->head, &next_ev->head);
> > > +     else
> > > +             sbi_list_add_tail(&ev->head, &tstate->event_list);
> > > +
> > > +     __sbi_timer_update_device(tstate);
> > > +
> > > +     spin_unlock(&tstate->event_list_lock);
> > > +}
> > > +
> > > +void sbi_timer_event_stop(struct sbi_timer_event *ev)
> > > +{
> > > +     struct timer_state *tstate;
> > > +
> > > +     if (!ev)
> > > +             return;
> > > +
> > > +     /* Ensure that event is not on the per-HART event list */
> > > +     if (ev->hart_index > -1) {
> > > +             tstate = sbi_scratch_offset_ptr(sbi_hartindex_to_scratch(ev->hart_index),
> > > +                                             timer_state_off);
> > > +             spin_lock(&tstate->event_list_lock);
> > > +             __sbi_timer_event_stop(ev);
> > > +             spin_unlock(&tstate->event_list_lock);
> >
> > Similar concern here, timer could be in the middle of running. Maybe it
> > is benign. I think it would be nice to make this a "sync" stop though,
> > so it can wait for potential running timers.
> >
> > timer event could have a 'running' state which is updated inside the
> > lock, then sbi_timer_event_stop() (and sbi_timer_exit()) could wait for
> > it to clear.
> 
> We might have to waste a lot of CPU cycles in the busy-loop.

That's true but I would expect it to not be common. Having the simpler
sync API as the first / default one would be good, add something more
complex if you find the need.

In any case, I think keeping the lock held over the callback should
make this a synchronous delete.

Thanks,
Nick

-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

  reply	other threads:[~2026-04-24  1:09 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-15 10:59 [PATCH 0/3] Timer events for OpenSBI Anup Patel
2026-04-15 11:00 ` [PATCH 1/3] include: sbi: Add sbi_scratch_hartindex() macro Anup Patel
2026-04-23  6:55   ` Nicholas Piggin
2026-04-15 11:00 ` [PATCH 2/3] lib: sbi_timer: Introduce per-HART timer state Anup Patel
2026-04-23  6:55   ` Nicholas Piggin
2026-04-15 11:00 ` [PATCH 3/3] lib: sbi_timer: Add support for timer events Anup Patel
2026-04-23  6:54   ` Nicholas Piggin
2026-04-23  8:25     ` Anup Patel
2026-04-24  1:09       ` Nicholas Piggin [this message]
2026-04-23  6:57 ` [PATCH 0/3] Timer events for OpenSBI Nicholas Piggin
2026-04-23  8:08   ` Anup Patel
2026-04-24  3:56     ` Nicholas Piggin

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=aerAIAyFzMGCKy8H@lima-default \
    --to=npiggin@gmail.com \
    --cc=andrew.jones@oss.qualcomm.com \
    --cc=anup.patel@oss.qualcomm.com \
    --cc=anup@brainfault.org \
    --cc=atish.patra@linux.dev \
    --cc=opensbi@lists.infradead.org \
    --cc=samuel.holland@sifive.com \
    /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