Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

The ISR does nothing more than call schedule_work() to get the bottom half to do the heavy lifting. The resource is shared between read() (i.e., user context) and the function that implements the bottom half, which is why I am locking with 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() (i.e., a hardware interrupt fired while we were holding the lock)? 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 (i.e., 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.

like image 532
It'sPete Avatar asked May 16 '18 20:05

It'sPete


People also ask

How does spin_lock_BH work with bottom half?

A bottom half is still an interrupt. spin_lock_bh does the equivalent by disabling bottom half execution, then taking the lock. This prevents bottom half execution from stepping on our read code. A lock prevents multiple threads from executing the locked code.

What is a spin lock used for?

A spin lock can be used to protect shared data or resources from simultaneous access by routines that can execute concurrently and at IRQL >= DISPATCH_LEVEL in SMP machines. Many components use spin locks, including drivers. Any kind of driver might use one or more executive spin locks.

What are the main operations on a spinlock?

The Linux kernel provides following main operations on a spinlock: spin_lock_init - produces initialization of the given spinlock; spin_lock - acquires given spinlock; spin_lock_bh - disables software interrupts and acquire given spinlock;

Should thread_function1 lock or release spinlock?

So before accessing the variable, it should lock the spinlock. After that, it will release the spinlock. This example is using Approach 1. In this example, thread_function1 and thread_function2 are synchronized using the spinlock. In our next part of the tutorial, we will see another variant of the spinlock ( Reader/writer spinlocks ).


1 Answers

An ISR can't wait for a lock if it might be held by code that does not disable interrupts. That would result in a deadlock. spin_lock_irqsave first disables interrupts, saving the previous state, then takes the lock. 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. This prevents bottom half execution from stepping on our read code.

A lock prevents multiple threads from executing the locked code. The work queue is protected by only being operated on while holding the lock.

like image 132
stark Avatar answered Sep 21 '22 08:09

stark