Linux hrtimer和calltrace

时间:2014-11-06 06:59:22

标签: c linux linux-kernel linux-device-driver

我在Linux下使用hrtimers时遇到了一些问题。我正在使用hrtimer如下:

hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
timer.function = timer_master;
hrtimer_start(&timer, ktime_set(0, 50*1000000), HRTIMER_MODE_REL); //start tx 50ms after  init

并在timer_master处理程序中:

hrtimer_forward_now(handle, ktime_set(0, 2400 * 1000));

当CPU尝试运行hrtimer_forward_now(handle,ktime_set(0,2400 * 1000))时; 我得到了以下calltrace:

[K   55.936212] ------------[ cut here ]------------
[K   55.941110] WARNING: at kernel/irq/handle.c:130 handle_irq_event_percpu+0x70/0x18c()
[K   55.949028] irq 5 handler ixp4xx_timer_interrupt+0x0/0x30 enabled interrupts
[K   55.956230] Modules linked in:  ixp4xx_crypto ftdi_sio sg usbserial cdc_acm     ebt_redirect ebt_mark ebt_vlan ebt_stp ebt_pkttype ebt_mark_m ebt_limit ebt_among ebt_802_3 ebtable_nat ebtable_filter 
[K   56.038593] Backtrace:
[K   56.041185] [<c000bc84>] (dump_backtrace+0x0/0x114) from [<c01e8c68>]  (dump_stack+0x18/0x1c)
[K   56.049847]  r6:00000082 r5:c0248347 r4:c0299e80 r3:60000013
[K   56.055698] [<c01e8c50>] (dump_stack+0x0/0x1c) from [<c001550c>] (warn_slowpath_common+0x54/0x6c)
[K   56.064766] [<c00154b8>] (warn_slowpath_common+0x0/0x6c) from [<c00155c8>] (warn_slowpath_fmt+0x38/0x40)
[K   56.074432]  r8:00000000 r7:00000000 r6:c02a8c40 r5:00000005 r4:c029d920
[K   56.081183] r3:00000009
[K   56.083937] [<c0015590>] (warn_slowpath_fmt+0x0/0x40) from [<c0044dd0>] (handle_irq_event_percpu+0x70/0x18c)
[K   56.093959]  r3:00000005 r2:c024835b
[K   56.097681] [<c0044d60>] (handle_irq_event_percpu+0x0/0x18c) from [<c0044f1c>] (handle_irq_event+0x30/0x40)
[K   56.107623] [<c0044eec>] (handle_irq_event+0x0/0x40) from [<c00472e4>] (handle_level_irq+0xb4/0xc4)
[K   56.116851]  r4:c02a8c40 r3:00020000
[K   56.120607] [<c0047230>] (handle_level_irq+0x0/0xc4) from [<c0044720>] (generic_handle_irq+0x30/0x4c)
[K   56.130011]  r4:00000005 r3:c0047230
[K   56.133730] [<c00446f0>] (generic_handle_irq+0x0/0x4c) from [<c000992c>] (handle_IRQ+0x68/0x8c)
[K   56.142619] [<c00098c4>] (handle_IRQ+0x0/0x8c) from [<c00081d0>] (asm_do_IRQ+0x10/0x14)
[K   56.150791]  r5:60000013 r4:c0009a8c
[K   56.154506] [<c00081c0>] (asm_do_IRQ+0x0/0x14) from [<c0008c70>] (__irq_svc+0x30/0xa0)
[K   56.162624] Exception stack(0xc0299f40 to 0xc0299f88)
[K   56.167830] 9f40: 00000000 c02aa630 c0299f88 60000013 c0298000 c029d0a4 c02b3ae8 c029d09c
[K   56.176193] 9f60: 00004000 69054041 002926a0 c0299f94 c0299f98 c0299f88 c0009c30 c0009a8c
[K   56.184546] 9f80: 60000013 ffffffff
[K   56.188168] [<c0009a64>] (default_idle+0x0/0x2c) from [<c0009c30>] (cpu_idle+0x64/0xac)
[K   56.196382] [<c0009bcc>] (cpu_idle+0x0/0xac) from [<c01e373c>] (rest_init+0x60/0x78)
[K   56.204292]  r6:c0293f4c r5:c02b3ab4 r4:c029a0b0 r3:c029c458
[K   56.210133] [<c01e36dc>] (rest_init+0x0/0x78) from [<c027a79c>] (start_kernel+0x2a4/0x2f8)
[K   56.218628] [<c027a4f8>] (start_kernel+0x0/0x2f8) from [<00008040>] (0x8040)
[K   56.225831] ---[ end trace a126a312e2dce91f ]---

编辑:hrtimer的处理程序:

static enum hrtimer_restart timer_master(struct hrtimer *handle)
{
    unsigned long flags;


    if (st == t0h) {
        st = t1;
        hrtimer_forward_now(handle, ktime_set(0, 2400 * 1000));
    } else if (st == t1) {
        st = t2;
        hrtimer_forward_now(handle, ktime_set(0, wdev->dwstream_timeslot * 1000));
        proc1((unsigned long)wdev->dev);
    } else if (st == t2) {
        st = t0h;
        hrtimer_forward_now(handle, ktime_set(0, (wdev->upstream_timeslot + 2 * delay)*1000));
    }

    return HRTIMER_RESTART;
}

和简化的proc1:

spin_lock_irq(&lock)
(...)
spin_unlock_irq(&lock)

看起来像spin_lock_irq()会弄得一团糟,但为什么呢?

我使用的是单核CPU:Intel IXP435。 谁知道我做错了什么?

0 个答案:

没有答案