0

我有一个问题,关于在具有先发制人的 linux 3.0 内核的 Android 嵌入式平台(基于 Exynos5dual)上 wait_event 和 wake_up 的奇怪行为。在具有非抢占式内核(任何版本)的普通 SMP 笔记本电脑上不会发生这种情况

我们有一个带有经典睡眠/唤醒场景的 linux 设备驱动程序,这就是发生的情况:

T0: taskA:
    if(!flag)
        wait_event_interruptible_timeout(wq, flag==true, timeout=0.5sec)

T1: (after a few msec) taskB: 
    atomic set flag
    wake_up_interruptible()

T2: (after timeout msec) taskA: 
    wait_event_interruptible_timeout expires (ret 0) instead of waking up at T1

标志的所有读写都是原子的,并且已经使用了从 atomic bitops(内核设置/测试位)到 volatile atomic_t,再到使用 atomic_t vars 对每个读/写使用内存屏障(根据this

如果 TaskA 实际上开始等待(wait_event_* 内核函数首先检查条件,因此可能并非总是如此),那么它会等待完全超时,而不是在标志更改值并调用 wake_up() 时被 taskB 唤醒。

我们怀疑这两个任务发生在不同的内核上。Core1 在 wait_event_..() 之后进入深度睡眠,并且无法被 Core2 上发生的 wake_up_interruptible() 唤醒。

有谁知道这是真的,还是其他原因?

注意:如果我们保存 sleeper 的任务结构 ptr,然后在(除此之外)wake_up_interruptible() 之前执行 wake_up_process (saved_ptr),问题似乎就消失。我们发现这不是最优的,想知道是否有更好的方法。

4

0 回答 0