Re: panic in hrtimer_run_queues

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Aug 28, 2012 at 4:13 PM, Ralf Baechle <ralf@xxxxxxxxxxxxxx> wrote:
> On Tue, Aug 28, 2012 at 09:42:51AM +0800, Lin Ming wrote:
>
>> Hi list,
>>
>> I'm working on a board running 2.6.30 kernel.
>> The panic log is attached in the end.
>>
>> 8002c098:       0c00aeaa        jal     8002baa8 <__remove_hrtimer>
>> 8002c09c:       00003821        move    a3,zero
>> 8002c0a0:       8e220020        lw      v0,32(s1)
>> 8002c0a4:       0040f809        jalr    v0
>> 8002c0a8:       02202021        move    a0,s1
>> 8002c0ac:       02002821        move    a1,s0
>> ------> panic happens here.
>> But this instruction just move data between registers.
>> How could it cause memory access panic?
>
> in case of a jal or jalr instruction the return address will point to the
> instruction of the jal(r) instruction plus 2 instruction as here.  This
> is where in case of a successful return from the subroutine execution
> would continue.
>
> But in your case v0 (that's register $2) contains 0 and it's been loaded
> from address 32(s1) before, so it would appear that memory at that
> address has either been overwritten or not initialized.

You are right. It should be panic at 8002c0a4.

$ addr2line -i -e vmlinux 8002c0a4
linux-2.6.30/kernel/hrtimer.c:1164

Line 1164:
fn = timer->function;
restart = fn(timer);   <---- line 1164

Seems "fn" is corrupted....

Thanks for the info!

static void __run_hrtimer(struct hrtimer *timer)
{
        struct hrtimer_clock_base *base = timer->base;
        struct hrtimer_cpu_base *cpu_base = base->cpu_base;
        enum hrtimer_restart (*fn)(struct hrtimer *);
        int restart;

        WARN_ON(!irqs_disabled());

        debug_hrtimer_deactivate(timer);
        __remove_hrtimer(timer, base, HRTIMER_STATE_CALLBACK, 0);
        timer_stats_account_hrtimer(timer);
        fn = timer->function;

        /*
         * Because we run timers from hardirq context, there is no chance
         * they get migrated to another cpu, therefore its safe to unlock
         * the timer base.
         */
        spin_unlock(&cpu_base->lock);
        restart = fn(timer);     <----------- line 1164
        spin_lock(&cpu_base->lock);

        /*
         * Note: We clear the CALLBACK bit after enqueue_hrtimer and
         * we do not reprogramm the event hardware. Happens either in
         * hrtimer_start_range_ns() or in hrtimer_interrupt()
         */
        if (restart != HRTIMER_NORESTART) {
                BUG_ON(timer->state != HRTIMER_STATE_CALLBACK);
                enqueue_hrtimer(timer, base);
        }
        timer->state &= ~HRTIMER_STATE_CALLBACK;
}


>
>   Ralf



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux