Re: [PATCH v5 16/18] timer: Implement the hierarchical pull model

Frederic Weisbecker
2023-04-04T14:32:28Z

On Tue, Apr 04, 2023 at 04:05:27PM +0200, Anna-Maria Behnsen wrote:
> On Tue, 21 Mar 2023, Frederic Weisbecker wrote:
>
> > On Wed, Mar 01, 2023 at 03:17:42PM +0100, Anna-Maria Behnsen wrote:
> > > +static u64 tmigr_handle_remote_cpu(unsigned int cpu, u64 now,
> > > + unsigned long jif)
> > > +{
> > > + struct timer_events tevt;
> > > + struct tmigr_walk data;
> > > + struct tmigr_cpu *tmc;
> > > + u64 next = KTIME_MAX;
> > > + unsigned long flags;
> > > +
> > > + tmc = per_cpu_ptr(&tmigr_cpu, cpu);
> > > +
> > > + raw_spin_lock_irqsave(&tmc->lock, flags);
> > > + /*
> > > + * Remote CPU is offline or no longer idle or other cpu handles cpu
> > > + * timers already or next event was already expired - return!
> > > + */
> > > + if (!tmc->online || tmc->remote || tmc->cpuevt.ignore ||
> > > + now < tmc->cpuevt.nextevt.expires) {
> > > + raw_spin_unlock_irqrestore(&tmc->lock, flags);
> > > + return next;
> > > + }
> > > +
> > > + tmc->remote = 1;
> > > +
> > > + /* Drop the lock to allow the remote CPU to exit idle */
> > > + raw_spin_unlock_irqrestore(&tmc->lock, flags);
> > > +
> > > + if (cpu != smp_processor_id())
> > > + timer_expire_remote(cpu);
> > > +
> > > + /* next event of cpu */
> > > + fetch_next_timer_interrupt_remote(jif, now, &tevt, cpu);
> >
> > If the target CPU gets an idle interrupt right after the above call and enqueues
> > a new timer (which becomes the new earliest), tmigr_cpu_deactivate() ->
> > tmigr_new_timer() is going to ignore it due to tmc->remote = 1, right?
>
> It's worse. The newly enqueued timer is updated in the timer migration
> hierarchy when CPU goes back idle and afterwards it will be overwritten by
> the group walk propagating the old first timer in
> tmigr_handle_remote_cpu()...

Hmm then that would require the remote CPU to exit dynticks and then
re-enter dynticks, right? Yes, sounds possible too.

>
> I will change the code after remote timer expiry:
>
> 1. take the remote timer bases locks
> 2. take the tmc->lock
> 3. get the next timer interrupt remote
> 4. drop the remote timer bases locks
> 5. propagate new timer changes
> 6. drop the tmc->lock

Right that sounds good!

Thanks.

>
> Thanks,
>
> Anna-Maria