Commit f99d237
authored
nvme: deadlock enabling doorbell buffer while doing I/O (#1080)
9a3a93a introduced a bug in the previously-okay SubQueue::pop; before,
acc_mem.access() would go through MemAccessor, acquire a reference on
the underlying MemCtx (an Arc refcount bump), drop the lock, and
continue. immediately after, SubQueue::pop would lock the SubQueue's
state and actually perform the pop.
this ordering is backwards from set_db_buf, which locks the SubQueue's
state *then* conditionally performs acc_mem.access() if the buffer is
set up as part of an import.
after 9a3a93a, SubQueue::pop uses access_borrowed() to avoid contention
on the refcount for MemCtx, the cost of retaining the lock on the
SubQueue's MemAccessor node while taking the lock on the same queue's
SubQueueState. at this point a concurrent SubQueue::pop and
SubQueue::set_db_buf could deadlock; one holds the queue state lock, the
other holds the accessor node lock, and both will try to take the other.
resolve this tension by picking a consistent ordering for the queue
state and acc_mem locks: SubQueueState first, then
acc_mem.{access,_borrow}(). this was already the ordering in
CompQueue::push and both set_db_buf, so pop() gets the trivial change.1 parent a54b7de commit f99d237
1 file changed
Lines changed: 11 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
116 | | - | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
117 | 123 | | |
118 | 124 | | |
119 | 125 | | |
| |||
649 | 655 | | |
650 | 656 | | |
651 | 657 | | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
652 | 662 | | |
653 | 663 | | |
654 | 664 | | |
655 | 665 | | |
656 | 666 | | |
657 | | - | |
658 | 667 | | |
659 | 668 | | |
660 | 669 | | |
| |||
0 commit comments