Skip to content

Commit

Permalink
rmlock: Add a required compiler membar to the rlock slow path
Browse files Browse the repository at this point in the history
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")
Differential Revision:	https://reviews.freebsd.org/D28821

(cherry picked from commit 1d44514)
  • Loading branch information
markjdb committed Mar 3, 2021
1 parent 81d747a commit 2655a71
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion sys/kern/kern_rmlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,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);
Expand Down

0 comments on commit 2655a71

Please sign in to comment.