Understanding the FreeBSD locking mechanism
Yubin Ruan
ablacktshirt at gmail.com
Thu Apr 13 09:28:17 UTC 2017
On 2017年04月13日 02:53, Chris Torek wrote:
>>> If you obtain the locks in the other order -- i.e., if you grab
>>> the PROC_STATLOCK first, then try to lock PROC_LOCK -- you are
>>> trying to take a spin-type mutex while holding a default mutex,
>
>> Is this a typo? I guess you mean something like "you are trying
>> to take a blocking mutex while holding spin-type mutex".
>
> Yes, or rather brain-o (swapping words) -- these most often happen
> if I am interrupted while composing a message :-)
>
>> I think I get your point: if you take a spin-type mutex, you
>> already disable interrupt, which in effect means that no other
>> code can preempt you. Under this circumstance, if you continue to
>> take a blocking mutex, you may get blocked. Since you already
>> disable interrupt and nobody can interrupt/preempt you, you are blocked
>> on that CPU, not being able to do anything, which is pretty much a
>> "deadlock" (actually this is not a deadlock, but, it is similar)
>
> Right. It *may* deadlock, and it is definitely not good -- and
> the INVARIANTS kernel will check and panic.
I discover that in the current implementation in FreeBSD, spinlock
does not disable interrupt entirely:
607 for (;;) {
608 if (m->mtx_lock == MTX_UNOWNED &&
_mtx_obtain_lock(m, tid))
609 break;
610 /* Give interrupts a chance while we spin. */
611 spinlock_exit();
612 while (m->mtx_lock != MTX_UNOWNED) {
613 if (i++ < 10000000) {
614 cpu_spinwait();
615 continue;
616 }
617 if (i < 60000000 || kdb_active ||
panicstr != NULL)
618 DELAY(1);
619 else
620 _mtx_lock_spin_failed(m);
621 cpu_spinwait();
622 }
623 spinlock_enter();
624 }
This is `_mtx_lock_spin_cookie(...)` in kern/kern_mutex.c, which
implements the core logic of spinning. However, as you can see, while
spinning, it would enable interrupt "occasionally" and disable it
again... What is the rationale for that?
Regards,
Yubin Ruan
More information about the freebsd-hackers
mailing list