public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* kernel/timer: avoid spurious ksoftirqd wakeups (v2)
@ 2015-04-06 23:15 Marcelo Tosatti
  2015-04-06 23:20 ` Rik van Riel
  2015-04-07 21:10 ` Thomas Gleixner
  0 siblings, 2 replies; 8+ messages in thread
From: Marcelo Tosatti @ 2015-04-06 23:15 UTC (permalink / raw)
  To: Frederic Weisbecker; +Cc: linux-kernel, Rik van Riel, Thomas Gleixner



It is only necessary to raise timer softirq
in case there are active timers.

Limit the ksoftirqd wakeup to that case.

Fixes a latency spike with isolated CPUs and
nohz full mode.

v2: fix variable initialization
    do not raise timer softirq due to pending irqwork 

Reported-and-tested-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

diff --git a/include/linux/timer.h b/include/linux/timer.h
index 8c5a197..0c065f9 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -192,7 +192,7 @@ extern void set_timer_slack(struct timer_list *time, int slack_hz);
  * locks the timer base and does the comparison against the given
  * jiffie.
  */
-extern unsigned long get_next_timer_interrupt(unsigned long now);
+extern unsigned long get_next_timer_interrupt(unsigned long now, bool *raise_softirq);
 
 /*
  * Timer-statistics info:
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index a4c4eda..1ee688c 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -568,6 +568,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
 	unsigned long rcu_delta_jiffies;
 	struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
 	u64 time_delta;
+	bool raise_softirq = false;
 
 	time_delta = timekeeping_max_deferment();
 
@@ -584,7 +585,8 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
 		delta_jiffies = 1;
 	} else {
 		/* Get the next timer wheel timer */
-		next_jiffies = get_next_timer_interrupt(last_jiffies);
+		next_jiffies = get_next_timer_interrupt(last_jiffies,
+							&raise_softirq);
 		delta_jiffies = next_jiffies - last_jiffies;
 		if (rcu_delta_jiffies < delta_jiffies) {
 			next_jiffies = last_jiffies + rcu_delta_jiffies;
@@ -703,7 +705,8 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
 		 */
 		tick_do_update_jiffies64(ktime_get());
 	}
-	raise_softirq_irqoff(TIMER_SOFTIRQ);
+	if (raise_softirq)
+		raise_softirq_irqoff(TIMER_SOFTIRQ);
 out:
 	ts->next_jiffies = next_jiffies;
 	ts->last_jiffies = last_jiffies;
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 2d3f5c5..771f811 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1343,7 +1343,7 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now,
  * get_next_timer_interrupt - return the jiffy of the next pending timer
  * @now: current time (in jiffies)
  */
-unsigned long get_next_timer_interrupt(unsigned long now)
+unsigned long get_next_timer_interrupt(unsigned long now, bool *raise_softirq)
 {
 	struct tvec_base *base = __this_cpu_read(tvec_bases);
 	unsigned long expires = now + NEXT_TIMER_MAX_DELTA;
@@ -1357,6 +1357,7 @@ unsigned long get_next_timer_interrupt(unsigned long now)
 
 	spin_lock(&base->lock);
 	if (base->active_timers) {
+		*raise_softirq = true;
 		if (time_before_eq(base->next_timer, base->timer_jiffies))
 			base->next_timer = __next_timer_interrupt(base);
 		expires = base->next_timer;


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-04-13 15:06 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-06 23:15 kernel/timer: avoid spurious ksoftirqd wakeups (v2) Marcelo Tosatti
2015-04-06 23:20 ` Rik van Riel
2015-04-07 21:10 ` Thomas Gleixner
2015-04-07 22:12   ` Frederic Weisbecker
2015-04-10 18:09     ` Marcelo Tosatti
2015-04-11  1:30       ` Luiz Capitulino
2015-04-11  9:25         ` Thomas Gleixner
2015-04-13 15:06           ` Luiz Capitulino

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox