All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH Resend] hrtimer: call switch_hrtimer_base() after setting new expiry time
@ 2014-05-12  8:12 Viresh Kumar
  2014-05-12  8:51 ` [tip:timers/urgent] hrtimer: Set expiry time before switch_hrtimer_base() tip-bot for Viresh Kumar
  0 siblings, 1 reply; 2+ messages in thread
From: Viresh Kumar @ 2014-05-12  8:12 UTC (permalink / raw)
  To: tglx
  Cc: linaro-kernel, linaro-networking, linux-kernel, fweisbec,
	arvind.chauhan, Viresh Kumar

In switch_hrtimer_base() we are calling hrtimer_check_target() which guarantees
this:

/*
 * With HIGHRES=y we do not migrate the timer when it is expiring
 * before the next event on the target cpu because we cannot reprogram
 * the target cpu hardware and we would cause it to fire late.
 *
 * Called with cpu_base->lock of target cpu held.
 */

But switch_hrtimer_base() is only called from one place, i.e.
__hrtimer_start_range_ns() and at that point (where we call
switch_hrtimer_base()) expiration time is not yet known as we call this routine
later: hrtimer_set_expires_range_ns().

To fix this, we need to find the updated expiry time before calling
switch_hrtimer_base().

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
Rebased over: v3.15-rc5

 kernel/hrtimer.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 6b715c0..e0501fe 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -990,11 +990,8 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
 	/* Remove an active timer from the queue: */
 	ret = remove_hrtimer(timer, base);
 
-	/* Switch the timer base, if necessary: */
-	new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
-
 	if (mode & HRTIMER_MODE_REL) {
-		tim = ktime_add_safe(tim, new_base->get_time());
+		tim = ktime_add_safe(tim, base->get_time());
 		/*
 		 * CONFIG_TIME_LOW_RES is a temporary way for architectures
 		 * to signal that they simply return xtime in
@@ -1009,6 +1006,9 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
 
 	hrtimer_set_expires_range_ns(timer, tim, delta_ns);
 
+	/* Switch the timer base, if necessary: */
+	new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
+
 	timer_stats_hrtimer_set_start_info(timer);
 
 	leftmost = enqueue_hrtimer(timer, new_base);
-- 
2.0.0.rc2


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

* [tip:timers/urgent] hrtimer: Set expiry time before switch_hrtimer_base()
  2014-05-12  8:12 [PATCH Resend] hrtimer: call switch_hrtimer_base() after setting new expiry time Viresh Kumar
@ 2014-05-12  8:51 ` tip-bot for Viresh Kumar
  0 siblings, 0 replies; 2+ messages in thread
From: tip-bot for Viresh Kumar @ 2014-05-12  8:51 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, viresh.kumar, tglx

Commit-ID:  84ea7fe37908254c3bd90910921f6e1045c1747a
Gitweb:     http://git.kernel.org/tip/84ea7fe37908254c3bd90910921f6e1045c1747a
Author:     Viresh Kumar <viresh.kumar@linaro.org>
AuthorDate: Mon, 12 May 2014 13:42:29 +0530
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Mon, 12 May 2014 10:47:39 +0200

hrtimer: Set expiry time before switch_hrtimer_base()

switch_hrtimer_base() calls hrtimer_check_target() which ensures that
we do not migrate a timer to a remote cpu if the timer expires before
the current programmed expiry time on that remote cpu.

But __hrtimer_start_range_ns() calls switch_hrtimer_base() before the
new expiry time is set. So the sanity check in hrtimer_check_target()
is operating on stale or even uninitialized data.

Update expiry time before calling switch_hrtimer_base().

[ tglx: Rewrote changelog once again ]

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: linaro-kernel@lists.linaro.org
Cc: linaro-networking@linaro.org
Cc: fweisbec@gmail.com
Cc: arvind.chauhan@arm.com
Link: http://lkml.kernel.org/r/81999e148745fc51bbcd0615823fbab9b2e87e23.1399882253.git.viresh.kumar@linaro.org
Cc: stable@vger.kernel.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/hrtimer.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 6b715c0..e0501fe 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -990,11 +990,8 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
 	/* Remove an active timer from the queue: */
 	ret = remove_hrtimer(timer, base);
 
-	/* Switch the timer base, if necessary: */
-	new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
-
 	if (mode & HRTIMER_MODE_REL) {
-		tim = ktime_add_safe(tim, new_base->get_time());
+		tim = ktime_add_safe(tim, base->get_time());
 		/*
 		 * CONFIG_TIME_LOW_RES is a temporary way for architectures
 		 * to signal that they simply return xtime in
@@ -1009,6 +1006,9 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
 
 	hrtimer_set_expires_range_ns(timer, tim, delta_ns);
 
+	/* Switch the timer base, if necessary: */
+	new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
+
 	timer_stats_hrtimer_set_start_info(timer);
 
 	leftmost = enqueue_hrtimer(timer, new_base);

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

end of thread, other threads:[~2014-05-12  8:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-12  8:12 [PATCH Resend] hrtimer: call switch_hrtimer_base() after setting new expiry time Viresh Kumar
2014-05-12  8:51 ` [tip:timers/urgent] hrtimer: Set expiry time before switch_hrtimer_base() tip-bot for Viresh Kumar

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.