From cc752df401301bad47242170221303120ab20d43 Mon Sep 17 00:00:00 2001 From: Gautham R Shenoy Date: Sat, 25 Oct 2008 10:22:38 +0530 Subject: [PATCH] --- yaml --- r: 118775 b: refs/heads/master c: 5d5254f0d3b9bebc47d97e357374c0ad0c291a7d h: refs/heads/master i: 118773: ced7e7cd52b75055824053464f4995436937ef66 118771: 5f37a63a02fa17d91a9e9a5c8fbb6048b7264c8a 118767: 944629794b0b3845929ad98e89e1fff381add883 v: v3 --- [refs] | 2 +- trunk/kernel/hrtimer.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 88df8c4ce142..6e118fe49f7d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ae99286b4f1be7788f2d6947c66a91dbd6351eec +refs/heads/master: 5d5254f0d3b9bebc47d97e357374c0ad0c291a7d diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index 2b465dfde426..95d3949f2ae5 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -1209,6 +1209,7 @@ static void run_hrtimer_pending(struct hrtimer_cpu_base *cpu_base) enum hrtimer_restart (*fn)(struct hrtimer *); struct hrtimer *timer; int restart; + int emulate_hardirq_ctx = 0; timer = list_entry(cpu_base->cb_pending.next, struct hrtimer, cb_entry); @@ -1217,10 +1218,24 @@ static void run_hrtimer_pending(struct hrtimer_cpu_base *cpu_base) timer_stats_account_hrtimer(timer); fn = timer->function; + /* + * A timer might have been added to the cb_pending list + * when it was migrated during a cpu-offline operation. + * Emulate hardirq context for such timers. + */ + if (timer->cb_mode == HRTIMER_CB_IRQSAFE_PERCPU || + timer->cb_mode == HRTIMER_CB_IRQSAFE_UNLOCKED) + emulate_hardirq_ctx = 1; + __remove_hrtimer(timer, timer->base, HRTIMER_STATE_CALLBACK, 0); spin_unlock_irq(&cpu_base->lock); - restart = fn(timer); + if (unlikely(emulate_hardirq_ctx)) { + local_irq_disable(); + restart = fn(timer); + local_irq_enable(); + } else + restart = fn(timer); spin_lock_irq(&cpu_base->lock);