[PATCH] m32r: Fix local-timer event handling
There was a scheduling problem of the m32r SMP kernel; A process rarely stopped and gave no responding but the other process have been handled by the other CPU still lives, then if we did something in the other terminal or something like that, the stopped process came back to life and continued its operation... (ex. LMbench: lat_sig) In the m32r SMP kernel, a local-timer event is delivered by using an IPI(inter processor interrupts); LOCAL_TIMER_IPI. And a function smp_send_timer() is prepared to send the LOCAL_TIMER_IPI from the current CPU to the other CPUs. The funtion smp_send_timer() was placed and used in do_IRQ() in former times (before 2.6.10-rc3-mm1 kernel), however, it was unintentionally removed when arch/m32r/kernel/irq.c was modified to employ the generic hardirq framework (CONFIG_GENERIC_HARDIRQ) in my previous patch. [PATCH 2.6.10-rc3-mm1] m32r: Use generic hardirq framework http://www.ussg.iu.edu/hypermail/linux/kernel/0412.2/0358.html The following patch fixes the above problem. Signed-off-by: Hitoshi Yamamoto <hitoshiy@isl.melco.co.jp> Signed-off-by: Hirokazu Takata <takata@linux-m32r.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
d2013485a5
commit
2757a71c31
1 changed files with 4 additions and 9 deletions
|
@ -205,8 +205,7 @@ static long last_rtc_update = 0;
|
|||
* timer_interrupt() needs to keep up the real-time clock,
|
||||
* as well as call the "do_timer()" routine every clocktick
|
||||
*/
|
||||
static inline void
|
||||
do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
|
||||
irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
#ifndef CONFIG_SMP
|
||||
profile_tick(CPU_PROFILING, regs);
|
||||
|
@ -221,6 +220,7 @@ do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
|
|||
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
|
||||
* called as close as possible to 500 ms before the new second starts.
|
||||
*/
|
||||
write_seqlock(&xtime_lock);
|
||||
if ((time_status & STA_UNSYNC) == 0
|
||||
&& xtime.tv_sec > last_rtc_update + 660
|
||||
&& (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2
|
||||
|
@ -231,6 +231,7 @@ do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
|
|||
else /* do it again in 60 s */
|
||||
last_rtc_update = xtime.tv_sec - 600;
|
||||
}
|
||||
write_sequnlock(&xtime_lock);
|
||||
/* As we return to user mode fire off the other CPU schedulers..
|
||||
this is basically because we don't yet share IRQ's around.
|
||||
This message is rigged to be safe on the 386 - basically it's
|
||||
|
@ -238,14 +239,8 @@ do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
|
|||
|
||||
#ifdef CONFIG_SMP
|
||||
smp_local_timer_interrupt(regs);
|
||||
smp_send_timer();
|
||||
#endif
|
||||
}
|
||||
|
||||
irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
write_seqlock(&xtime_lock);
|
||||
do_timer_interrupt(irq, NULL, regs);
|
||||
write_sequnlock(&xtime_lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue