Linux内核中的两个hrtimer回调可以同时运行吗?

时间:2016-05-22 18:40:51

标签: linux timer kernel locking interrupt

https://lwn.net/Articles/308545/中所述,hrtimer回调在禁用irqs的硬中断环境中运行。
但是SMP呢? 可以在另一个核心运行另一个hrtimer的第二个回调, 虽然第一个回调已经全部运行,或者它们是否在所有核心上相互排斥,因此它们之间不需要锁定?
编辑:
当“常规”硬件IRQ(我们称之为X)的处理程序在核心上运行时,所有IRQ仅在该核心上被禁用,但IRQ X在整个系统上被禁用,因此X的两个处理程序永远不会同时运行。
在这方面,hrtimer中断如何表现? 他们都共享相同的准IRQ,或者每个hrtimer有一个IRQ吗?

编辑:
用两个定时器A和B进行了一些实验:

// starting timer A to fire as fast as possible...
A_ktime = ktime_set(0, 1); // 1 NS
hrtimer_start( &A, A_ktime, HRTIMER_MODE_REL );

// starting timer B to fire 10 us later
B_ktime = ktime_set(0, 10000); // 10 us
hrtimer_start( &B, B_ktime, HRTIMER_MODE_REL );

将一些printks放入回调中,并将延迟放入计时器A

// fired after 1 NS
enum hrtimer_restart A(struct hrtimer *timer)
{
    printk("timer A: %lu\n",jiffies);
    int i;
    for(i=0;i<10000;i++){ // delay 10 seconds (1000 jiffies with HZ 100)
         udelay(1000);
    }
    printk("end timer A: %lu\n",jiffies);

    return HRTIMER_NORESTART;
}

// fired after 10 us
enum hrtimer_restart B(struct hrtimer *timer)
{
    printk("timer B: %lu\n",jiffies);
    return HRTIMER_NORESTART;
}

结果是可重现的,如

[    6.217393]     timer A: 4294937914
[   16.220352] end timer A: 4294938914
[   16.224059]     timer B: 4294938915
计时器A启动后1000点左右, 当计时器B设置为在不到一个jiffie之后启动时。

当进一步驾驶并将延迟增加到70秒时, 我在计时器A回调和计时器B回调之间获得了7000个jiffies。

[    6.218258]     timer A: 4294937914
[   76.220058] end timer A: 4294944914
[   76.224192]     timer B: 4294944915

编辑:

可能需要锁定,因为hrtimers 刚入队任何CPU。如果其中两个人在同一个人身上排队,可能会发生,他们互相推迟,但不能保证。

来自hrtimer.h:

    * On SMP it is possible to have a "callback function running and enqueued"
    * status. It happens for example when a posix timer expired and the callback
    * queued a signal. Between dropping the lock which protects the posix timer
    * and reacquiring the base lock of the hrtimer, another CPU can deliver the
    * signal and rearm the timer.

0 个答案:

没有答案