Commit ead4767
committed
rqspinlock: Enclose lock/unlock within lock entry acquisitions
There is a tiny window between the fast-path cmpxchg and the grabbing of
the lock entry where an NMI could land, attempt the same lock that was
just acquired, and end up timing out. This is not ideal. Instead, move
the lock entry acquisition from the fast path to before the cmpxchg, and
remove the grabbing of the lock entry in the slow path, assuming it was
already taken by the fast path.
There is a similar case when unlocking the lock. If the NMI lands
between the WRITE_ONCE and smp_store_release, it is possible that we end
up in a situation where the NMI fails to diagnose the AA condition,
leading to a timeout.
Note the changes to the comments in release_held_lock_entry and
res_spin_unlock. They talk about prevention of the following scenario:
(assuming we don't place unlock release after WRITE_ONCE)
grab entry A
lock A
grab entry B
lock B
unlock B
smp_store_release(B->locked, 0)
grab entry B
lock B
grab entry A
lock A
! <detect ABBA>
WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL)
If the store release were placed after the WRITE_ONCE, the other CPU
would not observe B in the table of the CPU unlocking the lock B.
Avoiding this while it was convenient was a prudent choice, but since it
leads to missed diagnosis of AA deadlocks in case of NMIs, it does not
make sense to keep such ordering any further. Moreover, while this
particular schedule is a misdiagnosis, the CPUs are obviously
participating in an ABBA deadlock otherwise, and are only lucky to avoid
an error before due to the aforementioned race.
Signed-off-by: Kumar Kartikeya Dwivedi <[email protected]>1 parent 590699d commit ead4767
2 files changed
+37
-39
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
129 | 129 | | |
130 | 130 | | |
131 | 131 | | |
132 | | - | |
133 | 132 | | |
| 133 | + | |
134 | 134 | | |
135 | 135 | | |
136 | 136 | | |
| |||
139 | 139 | | |
140 | 140 | | |
141 | 141 | | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
| 142 | + | |
| 143 | + | |
149 | 144 | | |
150 | 145 | | |
151 | 146 | | |
| |||
175 | 170 | | |
176 | 171 | | |
177 | 172 | | |
178 | | - | |
179 | | - | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
180 | 182 | | |
181 | | - | |
182 | 183 | | |
183 | 184 | | |
184 | 185 | | |
| |||
192 | 193 | | |
193 | 194 | | |
194 | 195 | | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | 196 | | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
204 | 212 | | |
205 | | - | |
206 | | - | |
207 | | - | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
208 | 216 | | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | | - | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
215 | 221 | | |
216 | | - | |
217 | 222 | | |
218 | 223 | | |
219 | 224 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
275 | 275 | | |
276 | 276 | | |
277 | 277 | | |
278 | | - | |
| 278 | + | |
279 | 279 | | |
280 | 280 | | |
281 | 281 | | |
| |||
397 | 397 | | |
398 | 398 | | |
399 | 399 | | |
400 | | - | |
401 | | - | |
402 | | - | |
403 | | - | |
| 400 | + | |
404 | 401 | | |
405 | 402 | | |
406 | 403 | | |
| |||
448 | 445 | | |
449 | 446 | | |
450 | 447 | | |
451 | | - | |
452 | | - | |
453 | | - | |
454 | | - | |
455 | | - | |
| 448 | + | |
456 | 449 | | |
457 | 450 | | |
458 | 451 | | |
| |||
0 commit comments