简体   繁体   English

spin_lock_bh()如何工作?

[英]How does spin_lock_bh() work?

I have a device driver I am working with that has a shared resource between the ISR (more specifically the bottom half of the ISR) and the read() call. 我有一个我正在使用的设备驱动程序,它在ISR(更具体地说是ISR的下半部分)和read()调用之间有一个共享资源。

The ISR does nothing more than call schedule_work() to get the bottom half to do the heavy lifting. ISR只是调用schedule_work()来让下半部分完成繁重的工作。 The resource is shared between read() (ie, user context) and the function that implements the bottom half, which is why I am locking with spin_lock_bh() . 资源在read() (即用户上下文)和实现下半部分的函数之间共享,这就是我使用spin_lock_bh()锁定的原因。

What I don't understand is the mechanics of the locking. 我不明白的是锁定的机制。 Say someone currently holds the lock, what happens when the ISR hits schedule_work() (ie, a hardware interrupt fired while we were holding the lock)? 假设有人持有锁定,当ISR命中schedule_work()时会发生什么(即,在我们持有锁定时触发硬件中断)? Does the work still get scheduled and then ran at a later time or does it get dropped to the floor? 工作是否仍然安排好,然后在以后运行或者是否会被丢弃? Stated differently... what is actually "locked" or prevented (ie, the work queue or the execution of the work)? 换句话说......实际上“锁定”或阻止了什么(即工作队列或工作的执行)? Does the work queue get updated? 工作队列是否得到更新?

To contrast my question, I understand that if I were using spin_lock_irqsave() , the ISR would be disabled while holding the lock, so I wouldn't get to schedule_work() in the first place, but given how the resource is shared, I don't think I need to or want to disable hardware interrupts when holding the lock. 为了对比我的问题,我理解如果我使用spin_lock_irqsave() ,ISR将在持有锁时被禁用,所以我不会首先得到schedule_work() ,但考虑到如何共享资源,我不要认为我需要或想要在持有锁时禁用硬件中断。

An ISR can't wait for a lock if it might be held by code that does not disable interrupts. 如果ISR可能由不禁用中断的代码保留,则ISR不能等待锁定。 That would result in a deadlock. 那会导致僵局。 spin_lock_irqsave first disables interrupts, saving the previous state, then takes the lock. spin_lock_irqsave首先禁用中断,保存先前的状态,然后进行锁定。 The restore undoes this in reverse order. 恢复以相反的顺序撤消此操作。

A bottom half is still an interrupt. 下半部分仍然是一个中断。 spin_lock_bh does the equivalent by disabling bottom half execution, then taking the lock. spin_lock_bh通过禁用下半部分执行然后获取锁定来执行等效操作。 This prevents bottom half execution from stepping on our read code. 这可以防止下半部分执行我们的read代码。

A lock prevents multiple threads from executing the locked code. 锁可防止多个线程执行锁定的代码。 The work queue is protected by only being operated on while holding the lock. 只有在握住锁的情况下操作才能保护工作队列。

spin_lock_bh disables softirqs (bh is an ancient term that actually refers to softirqs). spin_lock_bh禁用softirqs(bh是一个古老的术语,实际上指的是softirqs)。 However, work_queues triggered with schedule_work don't actually run in a softirq but in a dedicated thread, thus process context. 但是,使用schedule_work触发的work_queues实际上并不在softirq中运行,而是在专用线程中运行,因此处理上下文。

Therefore your driver needs just the simple spin_lock() to protect against concurrent read() calls. 因此,您的驱动程序只需要简单的spin_lock()来防止并发read()调用。

It may need to disable interrupts when accessing resources shared with the "top-half" but that was not the scope of your question. 在访问与“上半部分”共享的资源时,可能需要禁用中断,但这不是您的问题的范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM