All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anna-Maria Gleixner <anna-maria@linutronix.de>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	keescook@chromium.org, Christoph Hellwig <hch@lst.de>,
	John Stultz <john.stultz@linaro.org>
Subject: Re: [PATCH v2 28/37] hrtimer: Implement support for softirq based hrtimers
Date: Mon, 13 Nov 2017 10:13:02 +0100 (CET)	[thread overview]
Message-ID: <alpine.DEB.2.20.1711131010230.2108@hypnos.tec.linutronix.de> (raw)
In-Reply-To: <20171110124224.ykr6n4z7zgypojnb@breakpoint.cc>

On Fri, 10 Nov 2017, Sebastian Andrzej Siewior wrote:

> On 2017-10-22 23:40:06 [+0200], Anna-Maria Gleixner wrote:
> > --- a/include/linux/hrtimer.h
> > +++ b/include/linux/hrtimer.h
> > @@ -528,25 +546,42 @@ static ktime_t __hrtimer_next_event_base
> >   * Recomputes cpu_base::*next_timer and returns the earliest expires_next but
> >   * does not set cpu_base::*expires_next, that is done by hrtimer_reprogram.
> >   *
> > + * When a softirq is pending, we can ignore the HRTIMER_ACTIVE_SOFT bases,
> > + * those timers will get run whenever the softirq gets handled, at the end of
> > + * hrtimer_run_softirq(), hrtimer_update_softirq_timer() will re-add these bases.
> > + *
> > + * Therefore softirq values are those from the HRTIMER_ACTIVE_SOFT clock bases.
> > + * The !softirq values are the minima across HRTIMER_ACTIVE, unless an actual
> > + * softirq is pending, in which case they're the minima of HRTIMER_ACTIVE_HARD.
> > + *
> >   * @active_mask must be one of:
> >   *  - HRTIMER_ACTIVE,
> >   *  - HRTIMER_ACTIVE_SOFT, or
> >   *  - HRTIMER_ACTIVE_HARD.
> >   */
> > -static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base,
> > -					unsigned int active_mask)
> > +static ktime_t
> > +__hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base, unsigned int active_mask)
> >  {
> >  	unsigned int active;
> > +	struct hrtimer *next_timer = NULL;
> >  	ktime_t expires_next = KTIME_MAX;
> >  
> > -	cpu_base->next_timer = NULL;
> > +	if (!cpu_base->softirq_activated && (active_mask & HRTIMER_ACTIVE_SOFT)) {
> > +		active = cpu_base->active_bases & HRTIMER_ACTIVE_SOFT;
> > +		cpu_base->softirq_next_timer = next_timer;
> > +		expires_next = __hrtimer_next_event_base(cpu_base, active, expires_next);
> 
> doing
> 
>                cpu_base->softirq_next_timer = NULL;
>                expires_next = __hrtimer_next_event_base(cpu_base, active, KTIME_MAX);
> 
> instead would make it more obvious I think. I wasn't sure if it is a
> typo and the timer assignment was meant to be after
> __hrtimer_next_event_base() was invoked or if NULL was indeed intended.

will change it

> > +
> > +		next_timer = cpu_base->softirq_next_timer;
> > +	}
> >  
> > -	active = cpu_base->active_bases & active_mask;
> > -	expires_next = __hrtimer_next_event_base(cpu_base, active, expires_next);
> > +	if (active_mask & HRTIMER_ACTIVE_HARD) {
> > +		active = cpu_base->active_bases & HRTIMER_ACTIVE_HARD;
> > +		cpu_base->next_timer = next_timer;
> > +		expires_next = __hrtimer_next_event_base(cpu_base, active, expires_next);
> > +	}
> >  
> >  	return expires_next;
> >  }
> > -#endif
> >  
> >  static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base)
> >  {
> > @@ -968,6 +1034,32 @@ static inline ktime_t hrtimer_update_low
> >  	return tim;
> >  }
> >  
> > +static void
> > +hrtimer_update_softirq_timer(struct hrtimer_cpu_base *cpu_base, bool reprogram)
> > +{
> > +	ktime_t expires;
> > +
> > +	/*
> > +	 * Find the next SOFT expiration.
> > +	 */
> > +	expires = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_SOFT);
> 
> If you replace the following block
> > +
> > +	/*
> > +	 * reprogramming needs to be triggered, even if the next soft
> > +	 * hrtimer expires at the same time than the next hard
> > +	 * hrtimer. cpu_base->softirq_expires_next needs to be updated!
> > +	 */
> > +	if (!reprogram || expires == KTIME_MAX ||
> > +	    ktime_before(expires, cpu_base->expires_next))
> > +		return;
> 
> with 
> 
>        if (expires == KTIME_MAX)
>                return;
>        if (!reprogram || !ktime_before(expires, cpu_base->expires_next)) {
> 
>                /*
>                 * ->softirq_next_timer was updated by __hrtimer_next_event_base()
>                 * and we need to make sure that ->softirq_expires_next matches.
>                 */
>                cpu_base->softirq_expires_next = expires;
>                return;
>        }
> 
> then you have two bug less I *think*.
> 
> If *expires* is before ->expires_next then you don't want to return and
> do nothing but instead you want to reprogram timer for the soft-timer
> event. 
> 
> And then even if *expires* is after ->expires_next then you need to
> ->softirq_expires_next. As the comment says, the next timer field has
> been already updated. At this point, ->softirq_expires_next is set to
> KTIME_MAX (due to the raise softirq part) so if this field is not
> udpated here, then the hr-irq won't see the pending timer and expire it.
> Even worse, if future soft-timer have a "later" expiry time then this
> timer now then this field won't be updated at all and all soft-timer
> processing will stall.
>

I would propse another solution for this:

	if (expires == KTIME_MAX)
		return;

	hrtimer_reprogram(cpu_base->softirq_next_timer, reprogram);

Updating of cpu_base::*expires_next values is done in
hrtimer_reprogram() only. I think this should not change. When expires
equals KTIME_MAX, there is no soft hrtimer queued and updating of
softirq_expires_next is not required. The hrtimer_reprogram() function
gets the reprogram parameter handed in. If this parameter is set, the
hrtimer_reprogram() returns after setting the softirq_expires_next
value. In the migration case the hardware is not reprogrammed. If the
first soft hrtimer expires after the first hard hrtimer, then
hrtimer_reprogram() returns without reprogramming anyway.

> > +
> > +	/*
> > +	 * cpu_base->*next_timer is recomputed by __hrtimer_get_next_event()
> > +	 * cpu_base->*expires_next is only set by hrtimer_reprogram()
> > +	 */
> > +	hrtimer_reprogram(cpu_base->softirq_next_timer);
> > +}
> > +
> 
> Sebastian
> 

Anna-Maria

  reply	other threads:[~2017-11-13  9:13 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-22 21:39 [PATCH v2 00/37] hrtimer: Provide softirq context hrtimers Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 01/37] hrtimer: Correct blantanly wrong comment Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 02/37] hrtimer: Fix kerneldoc for struct hrtimer_cpu_base Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 03/37] hrtimer: Cleanup clock argument in schedule_hrtimeout_range_clock() Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 04/37] hrtimer: Fix hrtimer function description Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 05/37] hrtimer: Ensure POSIX compliance (relative CLOCK_REALTIME hrtimers) Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 06/37] hrtimer: Cleanup hrtimer_mode enum Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 07/37] tracing: hrtimer: Take all clock bases and modes into account Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 08/37] tracing: hrtimer: Print hrtimer mode in hrtimer_start tracepoint Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 09/37] hrtimer: Switch for loop to _ffs() evaluation Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 10/37] hrtimer: Store running timer in hrtimer_clock_base Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 11/37] hrtimer: Change boolean struct members into bitfield Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 12/37] hrtimer: Make room in struct hrtimer_cpu_base Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 13/37] hrtimer: Reduce conditional code (hres_active) Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 14/37] hrtimer: Use accesor functions instead of direct access Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 15/37] hrtimer: Make the remote enqueue check unconditional Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 16/37] hrtimer: Make hrtimer_cpu_base.next_timer handling unconditional Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 17/37] hrtimer: Make hrtimer_reprogramm() unconditional Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 18/37] hrtimer: Reduce conditional code and make hrtimer_force_reprogramm() unconditional Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 19/37] hrtimer: Unify handling of hrtimer remove Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 20/37] hrtimer: Unify handling of remote enqueue Anna-Maria Gleixner
2017-10-22 21:39 ` [PATCH v2 21/37] hrtimer: Make remote enqueue decision less restrictive Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 22/37] hrtimer: Remove base argument from hrtimer_reprogram() Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 23/37] hrtimer: Split hrtimer_start_range_ns() Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 24/37] hrtimer: Split __hrtimer_get_next_event() Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 25/37] hrtimer: Use irqsave/irqrestore around __run_hrtimer() Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 26/37] hrtimer: Add clock bases and hrtimer mode for soft irq context Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 27/37] hrtimer: Prepare handling of hard and softirq based hrtimers Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 28/37] hrtimer: Implement support for " Anna-Maria Gleixner
2017-11-10 12:42   ` Sebastian Andrzej Siewior
2017-11-13  9:13     ` Anna-Maria Gleixner [this message]
2017-10-22 21:40 ` [PATCH v2 29/37] hrtimer: Implement SOFT/HARD clock base selection Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 30/37] can/bcm: Replace hrtimer_tasklet with softirq based hrtimer Anna-Maria Gleixner
2017-10-27 14:42   ` Oliver Hartkopp
2017-10-22 21:40 ` [PATCH v2 31/37] mac80211_hwsim: Replace hrtimer tasklet with softirq hrtimer Anna-Maria Gleixner
2017-10-22 21:40   ` Anna-Maria Gleixner
2017-10-23 10:14   ` Johannes Berg
2017-10-23 10:23     ` Thomas Gleixner
2017-10-23 10:25       ` Johannes Berg
2017-10-23 10:33         ` Thomas Gleixner
2017-10-23 10:42           ` Johannes Berg
2017-10-22 21:40 ` [PATCH v2 32/37] xfrm: " Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 33/37] softirq: Remove tasklet_hrtimer Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 34/37] ALSA/dummy: Replace tasklet with softirq hrtimer Anna-Maria Gleixner
2017-10-22 21:40   ` Anna-Maria Gleixner
2017-10-24  6:25   ` Takashi Iwai
2017-10-24  6:25     ` Takashi Iwai
2017-10-22 21:40 ` [PATCH v2 36/37] usb/gadget/NCM: " Anna-Maria Gleixner
2017-10-22 21:40 ` [PATCH v2 37/37] net/mvpp2: " Anna-Maria Gleixner
2017-10-23 16:08 ` [PATCH v2 00/37] hrtimer: Provide softirq context hrtimers Peter Zijlstra

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=alpine.DEB.2.20.1711131010230.2108@hypnos.tec.linutronix.de \
    --to=anna-maria@linutronix.de \
    --cc=bigeasy@linutronix.de \
    --cc=hch@lst.de \
    --cc=john.stultz@linaro.org \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    /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.