rcu: remove qatomic_mb_set, expand comments
Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
792f77f376
commit
6e288b00ef
@ -87,7 +87,10 @@ static inline void rcu_read_lock(void)
|
||||
ctr = qatomic_read(&rcu_gp_ctr);
|
||||
qatomic_set(&p_rcu_reader->ctr, ctr);
|
||||
|
||||
/* Write p_rcu_reader->ctr before reading RCU-protected pointers. */
|
||||
/*
|
||||
* Read rcu_gp_ptr and write p_rcu_reader->ctr before reading
|
||||
* RCU-protected pointers.
|
||||
*/
|
||||
smp_mb_placeholder();
|
||||
}
|
||||
|
||||
|
24
util/rcu.c
24
util/rcu.c
@ -83,12 +83,6 @@ static void wait_for_readers(void)
|
||||
*/
|
||||
qemu_event_reset(&rcu_gp_event);
|
||||
|
||||
/* Instead of using qatomic_mb_set for index->waiting, and
|
||||
* qatomic_mb_read for index->ctr, memory barriers are placed
|
||||
* manually since writes to different threads are independent.
|
||||
* qemu_event_reset has acquire semantics, so no memory barrier
|
||||
* is needed here.
|
||||
*/
|
||||
QLIST_FOREACH(index, ®istry, node) {
|
||||
qatomic_set(&index->waiting, true);
|
||||
}
|
||||
@ -96,6 +90,10 @@ static void wait_for_readers(void)
|
||||
/* Here, order the stores to index->waiting before the loads of
|
||||
* index->ctr. Pairs with smp_mb_placeholder() in rcu_read_unlock(),
|
||||
* ensuring that the loads of index->ctr are sequentially consistent.
|
||||
*
|
||||
* If this is the last iteration, this barrier also prevents
|
||||
* frees from seeping upwards, and orders the two wait phases
|
||||
* on architectures with 32-bit longs; see synchronize_rcu().
|
||||
*/
|
||||
smp_mb_global();
|
||||
|
||||
@ -104,7 +102,7 @@ static void wait_for_readers(void)
|
||||
QLIST_REMOVE(index, node);
|
||||
QLIST_INSERT_HEAD(&qsreaders, index, node);
|
||||
|
||||
/* No need for mb_set here, worst of all we
|
||||
/* No need for memory barriers here, worst of all we
|
||||
* get some extra futex wakeups.
|
||||
*/
|
||||
qatomic_set(&index->waiting, false);
|
||||
@ -149,26 +147,26 @@ void synchronize_rcu(void)
|
||||
|
||||
/* Write RCU-protected pointers before reading p_rcu_reader->ctr.
|
||||
* Pairs with smp_mb_placeholder() in rcu_read_lock().
|
||||
*
|
||||
* Also orders write to RCU-protected pointers before
|
||||
* write to rcu_gp_ctr.
|
||||
*/
|
||||
smp_mb_global();
|
||||
|
||||
QEMU_LOCK_GUARD(&rcu_registry_lock);
|
||||
if (!QLIST_EMPTY(®istry)) {
|
||||
/* In either case, the qatomic_mb_set below blocks stores that free
|
||||
* old RCU-protected pointers.
|
||||
*/
|
||||
if (sizeof(rcu_gp_ctr) < 8) {
|
||||
/* For architectures with 32-bit longs, a two-subphases algorithm
|
||||
* ensures we do not encounter overflow bugs.
|
||||
*
|
||||
* Switch parity: 0 -> 1, 1 -> 0.
|
||||
*/
|
||||
qatomic_mb_set(&rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR);
|
||||
qatomic_set(&rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR);
|
||||
wait_for_readers();
|
||||
qatomic_mb_set(&rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR);
|
||||
qatomic_set(&rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR);
|
||||
} else {
|
||||
/* Increment current grace period. */
|
||||
qatomic_mb_set(&rcu_gp_ctr, rcu_gp_ctr + RCU_GP_CTR);
|
||||
qatomic_set(&rcu_gp_ctr, rcu_gp_ctr + RCU_GP_CTR);
|
||||
}
|
||||
|
||||
wait_for_readers();
|
||||
|
Loading…
Reference in New Issue
Block a user