从内核空间中的线程调度
我写了一个netfilter模块,在这个模块中我必须编写一个额外的线程来定期清理数据结构。 在每一轮清理完成后,我使用schedule()
函数从线程完成。 在使用信号量锁之前,除了"General Protection Fault"
发生之外,它工作得很好。 所以我使用信号量在insert
和delete
操作期间锁定和解锁数据结构。 现在它显示了一个错误,告诉"BUG: Scheduling while atomic"
。 在谷歌搜索后,我得到它显示,因为明确调用schedule()
函数,它不应该被称为。
有什么方法可以解决它? 有没有其他方式让线程将CPU产生给其他线程?
所以一个基本的总结(不能给出其他评论中指定的原因的详细答案):
信号量或互斥锁将尝试获取锁,如果无法达到,它将允许其他东西在等待时运行(这是通过schedule()
调用完成的)。 另一方面,自旋锁是一种锁定机制,它不断地试图抓住一个锁直到它不放弃控制,直到它成功为止(注意:还有spinlock_irq_save等等,它们也阻止你被isr打断你可以看看这些)。
就原子而言,这意味着内核无法允许另一个进程在后台运行。 例如,如果您处于中断状态,内核不允许其他人由于堆栈管理而运行。 如果你在自旋锁内,内核不允许其他人运行,因为如果它安排等待自旋锁的另一个进程,你可能会陷入死锁状态。 你可以通过使用in_atomic()
宏来判断你是否是原子。
对于你的情况,你提到了一个插入和删除函数,这些函数显然是从原子上下文中调用的(至少在某些时候)。 如果这些只是从原子上下文中调用,那么您可以使用自旋锁并完成它。 如果两者都被调用,则可以使用spinlock_irq_save(防止中断中断spinlocked区域)。 再次,请注意关闭中断很长一段时间。
也可以推迟释放,直到后来如果在释放中有某些东西,你不想从原子上下文中做。 在这种情况下,创建一个自旋锁保护的链接列表,该列表通过删除来确定。 然后在你的线程中,你从列表中弹出项目,并将它们释放。 为了插入,在锁定列表之前先执行malloc。
希望这可以帮助。
约翰
链接地址: http://www.djcxy.com/p/14851.html