spin_lock_bh() 是如何工作的?

How does spin_lock_bh() work?

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

ISR 只是调用 schedule_work() 让下半部分完成繁重的工作。该资源在 read()(即用户上下文)和实现下半部分的函数之间共享,这就是我使用 spin_lock_bh().

锁定的原因

我不明白的是锁定机制。假设某人当前持有锁,当 ISR 命中 schedule_work() 时会发生什么(即,当我们持有锁时触发硬件中断)?工作是否仍然按计划进行,然后 运行 在稍后的时间还是被搁置?换句话说......实际上 "locked" 或阻止的是什么(即工作队列或工作的执行)?工作队列是否得到更新?

为了对比我的问题,我知道如果我使用 spin_lock_irqsave(),ISR 将在持有锁时被禁用,所以我一开始就不会到达 schedule_work(),但是鉴于资源的共享方式,我认为我不需要或不想在持有锁时禁用硬件中断。

如果 ISR 可能被未禁用中断的代码持有,则它不能等待锁定。这将导致僵局。 spin_lock_irqsave 首先禁用中断,保存之前的状态,然后获取锁。还原以相反的顺序撤消此操作。

下半部分仍然是中断。 spin_lock_bh 通过禁用 bottom half 执行,然后获取锁来做等效的事情。这可以防止 bottom half 执行踩到我们的 read 代码。

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

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

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

访问与 "top-half" 共享的资源时可能需要禁用中断,但这不是您问题的范围。