Messages in this thread Patch in this message | | | Date | Mon, 15 Jun 2009 21:05:28 +0200 | From | Fabio Checconi <> | Subject | [PATCH 2/8] Fix hrtick handling |
| |
The current hrtick implementation can end up asking to the hrtimer code to wake up ksoftirqd while holding rq->lock, causing a spinlock recursion. This patch uses __hrtimer_start_range_ns() to disable the wakeup in the reprogramming path.
Signed-off-by: Fabio Checconi <fabio@gandalf.sssup.it> --- kernel/sched.c | 20 +++++++++++++++++--- 1 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/kernel/sched.c b/kernel/sched.c index 873b252..b8d432b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1090,6 +1090,19 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer) } #ifdef CONFIG_SMP +static void hrtick_restart(struct hrtimer *timer) +{ + ktime_t hard, soft; + unsigned long delta; + + soft = hrtimer_get_softexpires(timer); + hard = hrtimer_get_expires(timer); + delta = ktime_to_ns(ktime_sub(hard, soft)); + + __hrtimer_start_range_ns(timer, soft, delta, + HRTIMER_MODE_ABS_PINNED, 0); +} + /* * called from hardirq (IPI) context */ @@ -1098,7 +1111,7 @@ static void __hrtick_start(void *arg) struct rq *rq = arg; spin_lock(&rq->lock); - hrtimer_restart(&rq->hrtick_timer); + hrtick_restart(&rq->hrtick_timer); rq->hrtick_csd_pending = 0; spin_unlock(&rq->lock); } @@ -1116,7 +1129,7 @@ static void hrtick_start(struct rq *rq, u64 delay) hrtimer_set_expires(timer, time); if (rq == this_rq()) { - hrtimer_restart(timer); + hrtick_restart(timer); } else if (!rq->hrtick_csd_pending) { __smp_call_function_single(cpu_of(rq), &rq->hrtick_csd, 0); rq->hrtick_csd_pending = 1; @@ -1173,7 +1186,8 @@ static void init_rq_hrtick(struct rq *rq) rq->hrtick_csd.info = rq; #endif - hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL_PINNED); rq->hrtick_timer.function = hrtick; } #else /* CONFIG_SCHED_HRTICK */ -- 1.6.2.2
| |