aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHirokazu Takata <takata@linux-m32r.org>2005-08-02 00:11:35 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-08-02 00:37:59 -0400
commit2757a71c3122c7653e3dd8077ad6ca71efb1d450 (patch)
treeae0389f0ee758ed603571d43d764d08e267b4112
parentd2013485a52fb7ece48e5688b443cc098f4dbbdf (diff)
[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>
-rw-r--r--arch/m32r/kernel/time.c13
1 files changed, 4 insertions, 9 deletions
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index 3c4707280a52..8a2b77bc5749 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -205,8 +205,7 @@ static long last_rtc_update = 0;
205 * timer_interrupt() needs to keep up the real-time clock, 205 * timer_interrupt() needs to keep up the real-time clock,
206 * as well as call the "do_timer()" routine every clocktick 206 * as well as call the "do_timer()" routine every clocktick
207 */ 207 */
208static inline void 208irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
209do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
210{ 209{
211#ifndef CONFIG_SMP 210#ifndef CONFIG_SMP
212 profile_tick(CPU_PROFILING, regs); 211 profile_tick(CPU_PROFILING, regs);
@@ -221,6 +220,7 @@ do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
221 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be 220 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
222 * called as close as possible to 500 ms before the new second starts. 221 * called as close as possible to 500 ms before the new second starts.
223 */ 222 */
223 write_seqlock(&xtime_lock);
224 if ((time_status & STA_UNSYNC) == 0 224 if ((time_status & STA_UNSYNC) == 0
225 && xtime.tv_sec > last_rtc_update + 660 225 && xtime.tv_sec > last_rtc_update + 660
226 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2 226 && (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)
231 else /* do it again in 60 s */ 231 else /* do it again in 60 s */
232 last_rtc_update = xtime.tv_sec - 600; 232 last_rtc_update = xtime.tv_sec - 600;
233 } 233 }
234 write_sequnlock(&xtime_lock);
234 /* As we return to user mode fire off the other CPU schedulers.. 235 /* As we return to user mode fire off the other CPU schedulers..
235 this is basically because we don't yet share IRQ's around. 236 this is basically because we don't yet share IRQ's around.
236 This message is rigged to be safe on the 386 - basically it's 237 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)
238 239
239#ifdef CONFIG_SMP 240#ifdef CONFIG_SMP
240 smp_local_timer_interrupt(regs); 241 smp_local_timer_interrupt(regs);
242 smp_send_timer();
241#endif 243#endif
242}
243
244irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
245{
246 write_seqlock(&xtime_lock);
247 do_timer_interrupt(irq, NULL, regs);
248 write_sequnlock(&xtime_lock);
249 244
250 return IRQ_HANDLED; 245 return IRQ_HANDLED;
251} 246}