All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: Mikael Beckius <mikael.beckius@windriver.com>,
	linux-kernel@vger.kernel.org
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Subject: Re: [PATCH] hrtimer: Interrupt storm on clock_settime
Date: Fri, 05 Feb 2021 16:45:42 +0100	[thread overview]
Message-ID: <87r1lu8qmx.fsf@nanos.tec.linutronix.de> (raw)
In-Reply-To: <20210128140208.30264-1-mikael.beckius@windriver.com>

On Thu, Jan 28 2021 at 15:02, Mikael Beckius wrote:

> During clock_settime absolute realtime timers may get updated to expire
> sooner in absolute monotonic time but if hrtimer_force_reprogram is
> called as part of a clock_settime and the next hard hrtimer expires
> before the next soft hrtimer softirq_expires_next will not be updated
> to reflect this change (assuming the realtime timer is a soft timer).
>
> This means that if the next soft hrtimer expires before
> softirq_expires_next but after now no soft hrtimer interrupt will be
> raised in hrtimer_interrupt which will instead retry tick_program_event
> three times before forcing a tick_program_event using a very short delay
> entering hrtimer_interrupt again almost immediately repeating the
> process over and over again until now exceeds softirq_expires_next and a
> soft hrtimer interrupt is finally raised.

Duh.

> This patch aims to solve this by always updating softirq_expires_next if
> a soft hrtimer exists.

  git grep 'This patch' Documentation/process/

> Signed-off-by: Mikael Beckius <mikael.beckius@windriver.com>
> ---
>  kernel/time/hrtimer.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
> index 743c852e10f2..e4c233f404b1 100644
> --- a/kernel/time/hrtimer.c
> +++ b/kernel/time/hrtimer.c
> @@ -633,7 +633,7 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
>  	 */
>  	expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_ALL);
>  
> -	if (cpu_base->next_timer && cpu_base->next_timer->is_soft) {
> +	if (cpu_base->softirq_next_timer) {

>  		/*
>  		 * When the softirq is activated, hrtimer has to be
>  		 * programmed with the first hard hrtimer because soft
> @@ -643,7 +643,8 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
>  			expires_next = __hrtimer_get_next_event(cpu_base,
>  								HRTIMER_ACTIVE_HARD);
>  		else
> -			cpu_base->softirq_expires_next = expires_next;
> +			cpu_base->softirq_expires_next = __hrtimer_get_next_event(cpu_base,
> +								HRTIMER_ACTIVE_SOFT);

That works, but we can spare the double scan completely and make the
code understandable. See below.

Thanks,

        tglx
---

--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -626,26 +626,25 @@ static inline int hrtimer_hres_active(vo
 static void
 hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
 {
-	ktime_t expires_next;
+	ktime_t expires_next, soft = KTIME_MAX;
 
 	/*
-	 * Find the current next expiration time.
+	 * If soft interrupt has already been activated, ignore the soft
+	 * base. It will be handled in the already raised soft interrupt.
 	 */
-	expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_ALL);
-
-	if (cpu_base->next_timer && cpu_base->next_timer->is_soft) {
+	if (!cpu_base->softirq_activated) {
+		soft = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_SOFT);
 		/*
-		 * When the softirq is activated, hrtimer has to be
-		 * programmed with the first hard hrtimer because soft
-		 * timer interrupt could occur too late.
+		 * Update the soft expiry time. clock_settime() might have
+		 * affected it.
 		 */
-		if (cpu_base->softirq_activated)
-			expires_next = __hrtimer_get_next_event(cpu_base,
-								HRTIMER_ACTIVE_HARD);
-		else
-			cpu_base->softirq_expires_next = expires_next;
+		cpu_base->softirq_expires_next = soft;
 	}
 
+	expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_HARD);
+	if (expires_next > soft)
+		expires_next = soft;
+
 	if (skip_equal && expires_next == cpu_base->expires_next)
 		return;
 

  reply	other threads:[~2021-02-05 23:33 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-28 14:02 [PATCH] hrtimer: Interrupt storm on clock_settime Mikael Beckius
2021-02-05 15:45 ` Thomas Gleixner [this message]
2021-02-12 13:38   ` Sv: " Beckius, Mikael
2021-02-23 15:53     ` Anna-Maria Behnsen
2021-02-25 11:18       ` Sv: " Mikael Beckius
2021-03-01  9:13         ` Thomas Gleixner
2021-02-23 16:02     ` [PATCH] hrtimer: Update softirq_expires_next correctly after __hrtimer_get_next_event() Anna-Maria Behnsen
2021-02-25 11:18       ` Sv: " Mikael Beckius
2021-03-01  9:23       ` [tip: timers/urgent] " tip-bot2 for Anna-Maria Behnsen
2021-03-06 12:00       ` tip-bot2 for Anna-Maria Behnsen
2021-03-08  8:41       ` tip-bot2 for Anna-Maria Behnsen
2021-02-09 15:22 ` [tip: timers/urgent] hrtimer: Update softirq_expires_next correctly in hrtimer_force_reprogram() tip-bot2 for Mikael Beckius

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=87r1lu8qmx.fsf@nanos.tec.linutronix.de \
    --to=tglx@linutronix.de \
    --cc=anna-maria@linutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikael.beckius@windriver.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.