spin_lock_bh()如何工作?

时间:2018-05-16 20:20:46

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

我有一个我正在使用的设备驱动程序,它在ISR(更具体地说是ISR的下半部分)和read()调用之间有共享资源。

ISR只会致电schedule_work()让下半部分完成繁重的任务。资源在read()(即用户上下文)和实现下半部分的函数之间共享,这就是我与spin_lock_bh()锁定的原因。

我不明白的是锁定的机制。假设有人持有锁定,当ISR命中schedule_work()时会发生什么(即,在我们持有锁定时发生硬件中断)?工作是否仍然安排好,然后在以后运行或者是否会被丢弃?换句话说......实际上“锁定”或阻止了什么(即工作队列或工作的执行)?工作队列是否得到更新?

为了对比我的问题,我理解如果我使用spin_lock_irqsave(),ISR将在持有锁时被禁用,所以我不会首先到达schedule_work(),但是给出了如何共享资源,我认为我不需要或者想要在持有锁时禁用硬件中断。

2 个答案:

答案 0 :(得分:1)

如果ISR可能由不禁用中断的代码保留,则ISR无法等待锁定。那会导致僵局。 spin_lock_irqsave首先禁用中断,保存先前的状态,然后锁定。恢复以相反的顺序撤消。

下半部分仍然是中断。 spin_lock_bh通过禁用下半部分执行然后获取锁定来执行等效操作。这可以防止下半部分执行我们的read代码。

锁可防止多个线程执行锁定的代码。只有在按住锁定的情况下操作工作队列才能保护工作队列。

答案 1 :(得分:1)

spin_lock_bh禁用softirqs(bh是一个古老的术语,实际上是指softirqs)。但是,由schedule_work触发的work_queues实际上不是在softirq中运行,而是在专用线程中运行,因此是进程上下文。

因此,您的驱动程序只需要简单的spin_lock()即可防止并发的read()调用。

在访问与“上半部分”共享的资源时,可能需要禁用中断,但这不是您要解决的问题。