我想抱着互斥锁睡觉
I want to sleep while holding a mutex
我需要写入和读取以太网芯片的 FIFO,为此我想使用 DMA 控制器。所以我修改了一个现有的驱动程序,并在触发 DMA 传输后使用 wait_event_interruptible 使进程进入睡眠状态,并使用 wake_up_interruptible 使其被 ISR 唤醒。我的问题是原始驱动程序使用自旋锁来保护 FIFO 访问。但众所周知,在持有自旋锁的同时,我不应该睡觉。所以我尝试用互斥量替换自旋锁。 (因为,我可能会在获取互斥锁的时候休眠,拿到互斥锁后,DMA触发后我会再次休眠。我被ISR唤醒,我会释放互斥锁。没问题!我想。)但是我仍然明白这个 'scheduling while atomic BUG'。问题是:我需要在持有锁(用于 FIFO 读写)的同时进入睡眠状态,直到 DMA 完成。拿着互斥量睡觉不就好了吗?
添加:在我的例子中,读取接收 FIFO 的接收函数是 NAPI 轮询函数,它是软中断之一(中断掩码已重置,但它仍然是中断上下文。tasklet 也是中断上下文)。要读取 FIFO,我使用 DMA 并进入睡眠状态,所以这就是问题所在:在 softirq 期间睡眠。
可以在持有互斥量的情况下休眠。
scheduling while atomic BUG
指的是在原子上下文中休眠。可能,您忘记解锁某个锁,或者您试图在中断处理程序中休眠。
我需要写入和读取以太网芯片的 FIFO,为此我想使用 DMA 控制器。所以我修改了一个现有的驱动程序,并在触发 DMA 传输后使用 wait_event_interruptible 使进程进入睡眠状态,并使用 wake_up_interruptible 使其被 ISR 唤醒。我的问题是原始驱动程序使用自旋锁来保护 FIFO 访问。但众所周知,在持有自旋锁的同时,我不应该睡觉。所以我尝试用互斥量替换自旋锁。 (因为,我可能会在获取互斥锁的时候休眠,拿到互斥锁后,DMA触发后我会再次休眠。我被ISR唤醒,我会释放互斥锁。没问题!我想。)但是我仍然明白这个 'scheduling while atomic BUG'。问题是:我需要在持有锁(用于 FIFO 读写)的同时进入睡眠状态,直到 DMA 完成。拿着互斥量睡觉不就好了吗?
添加:在我的例子中,读取接收 FIFO 的接收函数是 NAPI 轮询函数,它是软中断之一(中断掩码已重置,但它仍然是中断上下文。tasklet 也是中断上下文)。要读取 FIFO,我使用 DMA 并进入睡眠状态,所以这就是问题所在:在 softirq 期间睡眠。
可以在持有互斥量的情况下休眠。
scheduling while atomic BUG
指的是在原子上下文中休眠。可能,您忘记解锁某个锁,或者您试图在中断处理程序中休眠。