提交 f21f237c 编写于 作者: L Linus Torvalds

Merge branch 'timers-fixes-for-linus' of...

Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  timers: handle HRTIMER_CB_IRQSAFE_UNLOCKED correctly from softirq context
  nohz: disable tick_nohz_kick_tick() for now
  irq: call __irq_enter() before calling the tick_idle_check
  x86: HPET: enter hpet_interrupt_handler with interrupts disabled
  x86: HPET: read from HPET_Tn_CMP() not HPET_T0_CMP
  x86: HPET: convert WARN_ON to WARN_ON_ONCE
...@@ -322,7 +322,7 @@ static int hpet_next_event(unsigned long delta, ...@@ -322,7 +322,7 @@ static int hpet_next_event(unsigned long delta,
* what we wrote hit the chip before we compare it to the * what we wrote hit the chip before we compare it to the
* counter. * counter.
*/ */
WARN_ON((u32)hpet_readl(HPET_T0_CMP) != cnt); WARN_ON_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt);
return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
} }
...@@ -445,7 +445,7 @@ static int hpet_setup_irq(struct hpet_dev *dev) ...@@ -445,7 +445,7 @@ static int hpet_setup_irq(struct hpet_dev *dev)
{ {
if (request_irq(dev->irq, hpet_interrupt_handler, if (request_irq(dev->irq, hpet_interrupt_handler,
IRQF_SHARED|IRQF_NOBALANCING, dev->name, dev)) IRQF_DISABLED|IRQF_NOBALANCING, dev->name, dev))
return -1; return -1;
disable_irq(dev->irq); disable_irq(dev->irq);
......
...@@ -1209,6 +1209,7 @@ static void run_hrtimer_pending(struct hrtimer_cpu_base *cpu_base) ...@@ -1209,6 +1209,7 @@ static void run_hrtimer_pending(struct hrtimer_cpu_base *cpu_base)
enum hrtimer_restart (*fn)(struct hrtimer *); enum hrtimer_restart (*fn)(struct hrtimer *);
struct hrtimer *timer; struct hrtimer *timer;
int restart; int restart;
int emulate_hardirq_ctx = 0;
timer = list_entry(cpu_base->cb_pending.next, timer = list_entry(cpu_base->cb_pending.next,
struct hrtimer, cb_entry); struct hrtimer, cb_entry);
...@@ -1217,10 +1218,24 @@ static void run_hrtimer_pending(struct hrtimer_cpu_base *cpu_base) ...@@ -1217,10 +1218,24 @@ static void run_hrtimer_pending(struct hrtimer_cpu_base *cpu_base)
timer_stats_account_hrtimer(timer); timer_stats_account_hrtimer(timer);
fn = timer->function; 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); __remove_hrtimer(timer, timer->base, HRTIMER_STATE_CALLBACK, 0);
spin_unlock_irq(&cpu_base->lock); 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); spin_lock_irq(&cpu_base->lock);
......
...@@ -269,10 +269,11 @@ void irq_enter(void) ...@@ -269,10 +269,11 @@ void irq_enter(void)
{ {
int cpu = smp_processor_id(); int cpu = smp_processor_id();
if (idle_cpu(cpu) && !in_interrupt()) if (idle_cpu(cpu) && !in_interrupt()) {
__irq_enter();
tick_check_idle(cpu); tick_check_idle(cpu);
} else
__irq_enter(); __irq_enter();
} }
#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED #ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
......
...@@ -568,6 +568,9 @@ static void tick_nohz_switch_to_nohz(void) ...@@ -568,6 +568,9 @@ static void tick_nohz_switch_to_nohz(void)
*/ */
static void tick_nohz_kick_tick(int cpu) static void tick_nohz_kick_tick(int cpu)
{ {
#if 0
/* Switch back to 2.6.27 behaviour */
struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
ktime_t delta, now; ktime_t delta, now;
...@@ -584,6 +587,7 @@ static void tick_nohz_kick_tick(int cpu) ...@@ -584,6 +587,7 @@ static void tick_nohz_kick_tick(int cpu)
return; return;
tick_nohz_restart(ts, now); tick_nohz_restart(ts, now);
#endif
} }
#else #else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册