rmlock: Add a required compiler membar to the rlock slow path
The tracker flags need to be loaded only after the tracker is removed from its per-CPU queue. Otherwise, readers may fail to synchronize with pending writers attempting to propagate priority to active readers, and readers and writers deadlock on each other. This was observed in a stable/12-based armv7 kernel where the compiler had reordered the load of rmp_flags to before the stores updating the queue. Reviewed by: rlibby, scottl Discussed with: kib Sponsored by: Rubicon Communications, LLC ("Netgate") MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D28821
This commit is contained in:
parent
6ab923cbca
commit
1d44514fcd
@ -362,7 +362,11 @@ _rm_rlock_hard(struct rmlock *rm, struct rm_priotracker *tracker, int trylock)
|
||||
/* Remove our tracker from the per-cpu list. */
|
||||
rm_tracker_remove(pc, tracker);
|
||||
|
||||
/* Check to see if the IPI granted us the lock after all. */
|
||||
/*
|
||||
* Check to see if the IPI granted us the lock after all. The load of
|
||||
* rmp_flags must happen after the tracker is removed from the list.
|
||||
*/
|
||||
__compiler_membar();
|
||||
if (tracker->rmp_flags) {
|
||||
/* Just add back tracker - we hold the lock. */
|
||||
rm_tracker_add(pc, tracker);
|
||||
|
Loading…
Reference in New Issue
Block a user