From: Russell King Date: Mon, 28 Jan 2008 10:16:37 +0000 (+0000) Subject: [ARM] Fix timer damage from d3d74453c34f8fd87674a8cf5b8a327c68f22e99 X-Git-Tag: v2.6.25-rc1~1175^2~5 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=193c3cc12583344be01206078d9ad3fec5dbc397;p=linux-2.6 [ARM] Fix timer damage from d3d74453c34f8fd87674a8cf5b8a327c68f22e99 Move the xtime write mode seqlock into timer_tick(), so it only surrounds the call to do_timer(). This avoids a deadlock in update_process_times() ... hrtimer_get_softirq_time() which tries to get a read mode seqlock on xtime, thereby preventing booting. Signed-off-by: Russell King --- diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index e59b5b8416..b5867eca1d 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -325,7 +325,9 @@ void timer_tick(void) profile_tick(CPU_PROFILING); do_leds(); do_set_rtc(); + write_seqlock(&xtime_lock); do_timer(1); + write_sequnlock(&xtime_lock); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index 0446ef2f5b..b016be2b0e 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -130,13 +130,9 @@ static irqreturn_t aaec2000_timer_interrupt(int irq, void *dev_id) { /* TODO: Check timer accuracy */ - write_seqlock(&xtime_lock); - timer_tick(); TIMER1_CLEAR = 1; - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c index f428af7545..e5dc33f1f9 100644 --- a/arch/arm/mach-clps711x/time.c +++ b/arch/arm/mach-clps711x/time.c @@ -50,9 +50,7 @@ static unsigned long clps711x_gettimeoffset(void) static irqreturn_t p720t_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); timer_tick(); - write_sequnlock(&xtime_lock); return IRQ_HANDLED; } diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index 986205ec92..2ac63671ea 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -298,8 +298,6 @@ extern unsigned long ioc_timer_gettimeoffset(void); static irqreturn_t clps7500_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); - timer_tick(); /* Why not using do_leds interface?? */ @@ -313,8 +311,6 @@ clps7500_timer_interrupt(int irq, void *dev_id) } } - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index 8c1b5690df..7710e14b52 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -178,8 +178,6 @@ ebsa110_timer_interrupt(int irq, void *dev_id) { u32 count; - write_seqlock(&xtime_lock); - /* latch and read timer 1 */ __raw_writeb(0x40, PIT_CTRL); count = __raw_readb(PIT_T1); @@ -192,8 +190,6 @@ ebsa110_timer_interrupt(int irq, void *dev_id) timer_tick(); - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 70b2c78011..f1074ff02f 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -99,8 +99,6 @@ static unsigned int last_jiffy_time; static int ep93xx_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); - __raw_writel(1, EP93XX_TIMER1_CLEAR); while ((signed long) (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) @@ -109,8 +107,6 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id) timer_tick(); } - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index 3a63941d43..b2a21189dd 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -30,14 +30,10 @@ static unsigned long timer1_gettimeoffset (void) static irqreturn_t timer1_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); - *CSR_TIMER1_CLR = 0; timer_tick(); - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c index d08d64139d..a764e01d35 100644 --- a/arch/arm/mach-footbridge/isa-timer.c +++ b/arch/arm/mach-footbridge/isa-timer.c @@ -64,9 +64,7 @@ static unsigned long isa_gettimeoffset(void) static irqreturn_t isa_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); timer_tick(); - write_sequnlock(&xtime_lock); return IRQ_HANDLED; } diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c index 9107b8e2ad..c2a431f482 100644 --- a/arch/arm/mach-h720x/cpu-h7201.c +++ b/arch/arm/mach-h720x/cpu-h7201.c @@ -29,13 +29,9 @@ static irqreturn_t h7201_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); - CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); timer_tick(); - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c index 0a1a25fb8b..c627fa124e 100644 --- a/arch/arm/mach-h720x/cpu-h7202.c +++ b/arch/arm/mach-h720x/cpu-h7202.c @@ -113,9 +113,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irq_desc *desc) mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); if ( mask & TSTAT_T0INT ) { - write_seqlock(&xtime_lock); timer_tick(); - write_sequnlock(&xtime_lock); if( mask == TSTAT_T0INT ) return; } diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index e9c82deb79..7fbbc17f8e 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -250,8 +250,6 @@ unsigned long integrator_gettimeoffset(void) static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); - /* * clear the interrupt */ @@ -259,8 +257,6 @@ integrator_timer_interrupt(int irq, void *dev_id) timer_tick(); - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index cb6ad21188..81cdc82672 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -206,8 +206,6 @@ unsigned long ixp2000_gettimeoffset (void) static int ixp2000_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); - /* clear timer 1 */ ixp2000_reg_wrb(IXP2000_T1_CLR, 1); @@ -217,8 +215,6 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id) next_jiffy_time -= ticks_per_jiffy; } - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-ks8695/time.c b/arch/arm/mach-ks8695/time.c index d2c86e4a72..02f766b312 100644 --- a/arch/arm/mach-ks8695/time.c +++ b/arch/arm/mach-ks8695/time.c @@ -70,10 +70,7 @@ static unsigned long ks8695_gettimeoffset (void) */ static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); timer_tick(); - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c index c25316d025..e50e60b338 100644 --- a/arch/arm/mach-lh7a40x/time.c +++ b/arch/arm/mach-lh7a40x/time.c @@ -41,13 +41,9 @@ static irqreturn_t lh7a40x_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); - TIMER_EOI = 0; timer_tick(); - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-mx3/time.c b/arch/arm/mach-mx3/time.c index e81fb5c5d7..fb565c98db 100644 --- a/arch/arm/mach-mx3/time.c +++ b/arch/arm/mach-mx3/time.c @@ -45,8 +45,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) { unsigned int next_match; - write_seqlock(&xtime_lock); - if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) { do { timer_tick(); @@ -57,8 +55,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) __raw_readl(MXC_GPT_GPTCNT)) <= 0); } - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c index 4762e207b0..ea07b54afa 100644 --- a/arch/arm/mach-netx/time.c +++ b/arch/arm/mach-netx/time.c @@ -33,12 +33,8 @@ static irqreturn_t netx_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); - timer_tick(); - write_sequnlock(&xtime_lock); - /* acknowledge interrupt */ writel(COUNTER_BIT(0), NETX_GPIO_IRQ); diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index 8d322c20cc..3234deedb9 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c @@ -40,13 +40,9 @@ static inline void omap2_gp_timer_start(unsigned long load_val) static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); - omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW); timer_tick(); - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c index 67e05f005a..6d4ca8fc0c 100644 --- a/arch/arm/mach-pnx4008/time.c +++ b/arch/arm/mach-pnx4008/time.c @@ -51,8 +51,6 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id) { if (__raw_readl(HSTIM_INT) & MATCH0_INT) { - write_seqlock(&xtime_lock); - do { timer_tick(); @@ -73,8 +71,6 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id) } while ((signed) (__raw_readl(HSTIM_MATCH0) - __raw_readl(HSTIM_COUNTER)) < 0); - - write_sequnlock(&xtime_lock); } return IRQ_HANDLED; diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index c7f1b44da4..61d70218f1 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -530,8 +530,6 @@ static unsigned long realview_gettimeoffset(void) */ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); - // ...clear the interrupt writel(1, TIMER0_VA_BASE + TIMER_INTCLR); @@ -542,8 +540,6 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) update_process_times(user_mode(get_irq_regs())); #endif - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index fdf7b016e7..47f8640438 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c @@ -62,8 +62,6 @@ sa1100_timer_interrupt(int irq, void *dev_id) { unsigned int next_match; - write_seqlock(&xtime_lock); - #ifdef CONFIG_NO_IDLE_HZ if (match_posponed) { match_posponed = 0; @@ -85,8 +83,6 @@ sa1100_timer_interrupt(int irq, void *dev_id) next_match = (OSMR0 += LATCH); } while ((signed long)(next_match - OSCR) <= 0); - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; } diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index a0545db2a3..09d9f33d40 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -82,9 +82,7 @@ static void __init shark_map_io(void) static irqreturn_t shark_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); timer_tick(); - write_sequnlock(&xtime_lock); return IRQ_HANDLED; }