Commit 08bde5e
committed
libnetwork/networkdb: fix broadcast queue deadlocks
NetworkDB's JoinNetwork function enqueues a message onto a
TransmitLimitedQueue while holding the NetworkDB mutex locked for
writing. The TransmitLimitedQueue has its own synchronization;
it locks its mutex when enqueueing a message. Locking order:
1. (NetworkDB).RWMutex.Lock()
2. (TransmitLimitedQueue).mu.Lock()
NetworkDB's gossip periodic task calls GetBroadcasts on the same
TransmitLimitedQueue to retrieve the enqueued messages. GetBroadcasts
invokes the queue's NumNodes callback while the mutex is locked. The
NumNodes callback function that NetworkDB sets locks the NetworkDB mutex
for reading to take the length of the nodes map. Locking order:
1. (TransmitLimitedQueue).mu.Lock()
2. (NetworkDB).RWMutex.RLock()
If one goroutine calls GetBroadcasts on the queue concurrently with
another goroutine calling JoinNetwork on the NetworkDB, the goroutines
may deadlock due to the lock inversion.
Fix the deadlock by caching the number of nodes in an atomic variable so
that the NumNodes callback can load the value without blocking or
violating Go's memory model. And fix a similar deadlock situation with
the table-event broadcast queues.
Signed-off-by: Cory Snider <[email protected]>1 parent 8326491 commit 08bde5e
4 files changed
Lines changed: 28 additions & 23 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
135 | 135 | | |
136 | 136 | | |
137 | 137 | | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
| 138 | + | |
144 | 139 | | |
145 | 140 | | |
146 | 141 | | |
147 | 142 | | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
| 143 | + | |
154 | 144 | | |
155 | 145 | | |
156 | 146 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
43 | 44 | | |
44 | 45 | | |
45 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
59 | 63 | | |
60 | 64 | | |
61 | 65 | | |
| |||
171 | 175 | | |
172 | 176 | | |
173 | 177 | | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
174 | 182 | | |
175 | 183 | | |
176 | 184 | | |
| |||
637 | 645 | | |
638 | 646 | | |
639 | 647 | | |
640 | | - | |
641 | | - | |
642 | | - | |
643 | | - | |
644 | | - | |
645 | | - | |
646 | | - | |
647 | | - | |
648 | 648 | | |
649 | 649 | | |
650 | 650 | | |
651 | | - | |
652 | 651 | | |
653 | 652 | | |
654 | 653 | | |
655 | | - | |
656 | 654 | | |
657 | 655 | | |
658 | 656 | | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
659 | 660 | | |
660 | 661 | | |
661 | 662 | | |
| |||
664 | 665 | | |
665 | 666 | | |
666 | 667 | | |
667 | | - | |
668 | 668 | | |
| 669 | + | |
| 670 | + | |
669 | 671 | | |
670 | 672 | | |
671 | 673 | | |
| |||
727 | 729 | | |
728 | 730 | | |
729 | 731 | | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
730 | 735 | | |
731 | 736 | | |
732 | 737 | | |
| |||
745 | 750 | | |
746 | 751 | | |
747 | 752 | | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
748 | 756 | | |
749 | 757 | | |
750 | 758 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
| 79 | + | |
| 80 | + | |
79 | 81 | | |
80 | 82 | | |
81 | 83 | | |
| |||
121 | 123 | | |
122 | 124 | | |
123 | 125 | | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
0 commit comments