54. void mtx_enter(struct mutex *mtx)
...
for (;;) {
if (mtx->mtx_wantipl != IPL_NONE)
s = splraise(mtx->mtx_wantipl);
if (try_lock(mtx)) {
if (mtx->mtx_wantipl != IPL_NONE)
mtx->mtx_oldipl = s;
mtx->mtx_owner = curcpu();
mtx->mtx_ra =
__builtin_return_address(0);
return;
}
if (mtx->mtx_wantipl != IPL_NONE)
splx(s);
if (++i > MTX_TIMEOUT)
panic("mtx deadlocked ra:%pn",
mtx->mtx_ra);
}
55. IPI
CPU A CPU B
Interrupt
Fault
Disable interrupt
Acquire lock
Lock
Wait until released
TLB shootdown Blocked
IPI
Wait ACK
56. IPI
CPU A CPU B
Interrupt
Fault
Disable interrupt
Acquire lock
Lock
Wait until released
TLB shootdown
IPI
Wait ACK
57. IPI
CPU A CPU B
Interrupt
Fault
Disable interrupt
Acquire lock Re-enable interrupt
Lock
Wait until released
TLB shootdown Accept Interrupt
IPI
Wait ACK
58. IPI
CPU A CPU B
Interrupt
Fault
Disable interrupt
Acquire lock Re-enable interrupt
Lock
Wait until released
TLB shootdown Accept Interrupt
IPI
Wait ACK ACK for rendezvous
59. IPI
CPU A CPU B
Interrupt
Fault
IPI Disable interrupt
Acquire lock Re-enable interrupt
Lock
Wait until released
TLB shootdown Accept Interrupt
IPI
Wait ACK ACK for rendezvous
61. splhigh() IPI
CPU A CPU B
splhigh()
Fault
Acquire lock
Lock
Wait until released
TLB shootdown Blocked
IPI
Wait ACK
62. splhigh() IPI
CPU A CPU B
splhigh()
Fault
Acquire lock
Lock
Wait until released
TLB shootdown
IPI
Wait ACK
63. splhigh() IPI
CPU A CPU B
splhigh()
Fault
Acquire lock
Lock
Wait until released
TLB shootdown Accept Interrupt
IPI
Wait ACK
64. splhigh() IPI
CPU A CPU B
splhigh()
Fault
Acquire lock
Lock
Wait until released
TLB shootdown Accept Interrupt
IPI
Wait ACK ACK for rendezvous
65. splhigh() IPI
CPU A CPU B
IPL_IPI splhigh()
Fault
IPL_HIGH
Acquire lock
Lock
Wait until released
TLB shootdown Accept Interrupt
IPI
Wait ACK ACK for rendezvous