Why is spinlock no-op in Linux kernel (non-SMP)?
質問
I've been reading this for quite some time but doesn't make sense to me.. Probably because I'm new to all this and still don't understand few kernel concepts.
This was what i came up with (no error or NULL handing, it's just for the sake of the question):
Kernel spinlocks are executed inside kernel threads, which is preemtive.
void spinlock_acquire(spinlock_t *spinlock)
{
tryagain:
while(spinlock->plock != UNLOCKED) ;
context_switch_block;
if(spinlock->plock != UNLOCKED) {
context_switch_unblock;
goto tryagain;
}
spinlock_lock(spinlock, current_thread);
context_switch_unblock;
}
解決
Before Linux was a preemptive kernel, spinlocks on UP were basically no-ops. Once the kernel was made preemptive, a call to preempt_disable()
was added to spinlocks.
So it goes more or less like this:
- You want to protect against some conflicting CPU, use some kind of spinlock.
- You want to protect against a conflicting softirq, tasklet,... use
spin_lock_bh
, which disables softirqs, tasklets, etc... (bh
is for historical name, it comes from "bottom half"). - You want to protect against a conflicting hardware interrupt use
spin_lock_irq*
, which disables hardware interrupts. - All spinlocks protect against preemption.
- On a UP kernel, spinlocks don't take a real spinlock (since there are no conflicting CPUs, and we cannot be preempted, and there are spinlock variants for dealing with hardirqs, softirqs,...).
- On a UP machine with an SMP kernel, spinlocks may be turned into nops.
- Even on a UP kernel with preemption disabled, spinlocks may have code for spinlock debugging, if it is enabled.
他のヒント
Spin lock is unnecessary on non-SMP. Since a spin lock disabled interrupts, it is not possible to anyone else to have the lock at that point. Once thread A disabled interrupts, is is not possible for thread B to try and acquire the same lock, as there is nothing that can cause A to lose the CPU in favor of B. As such, all spin lock does on non-SMP is, well, nothing (except if you ask it to disable interrupts).
Shachar