All of 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.