Skip to content

Commit

Permalink
Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed Nov 11, 2008
2 parents 2f96cb5 + 5d5254f commit f21f237
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 6 deletions.
4 changes: 2 additions & 2 deletions arch/x86/kernel/hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ static int hpet_next_event(unsigned long delta,
* what we wrote hit the chip before we compare it to the
* 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;
}
Expand Down Expand Up @@ -445,7 +445,7 @@ static int hpet_setup_irq(struct hpet_dev *dev)
{

if (request_irq(dev->irq, hpet_interrupt_handler,
IRQF_SHARED|IRQF_NOBALANCING, dev->name, dev))
IRQF_DISABLED|IRQF_NOBALANCING, dev->name, dev))
return -1;

disable_irq(dev->irq);
Expand Down
17 changes: 16 additions & 1 deletion kernel/hrtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);

Expand Down
7 changes: 4 additions & 3 deletions kernel/softirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,11 @@ void irq_enter(void)
{
int cpu = smp_processor_id();

if (idle_cpu(cpu) && !in_interrupt())
if (idle_cpu(cpu) && !in_interrupt()) {
__irq_enter();
tick_check_idle(cpu);

__irq_enter();
} else
__irq_enter();
}

#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
Expand Down
4 changes: 4 additions & 0 deletions kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,9 @@ static void tick_nohz_switch_to_nohz(void)
*/
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);
ktime_t delta, now;

Expand All @@ -584,6 +587,7 @@ static void tick_nohz_kick_tick(int cpu)
return;

tick_nohz_restart(ts, now);
#endif
}

#else
Expand Down

0 comments on commit f21f237

Please sign in to comment.