urcu: Add extra "engineering safety factor" memory barrier in update_counter_and_wait()
[urcu.git] / urcu-qsbr.c
index 155505abc7843385fafef29de57509ceb096519c..c678d38779eb683f1f78872a87e853a4c281f43d 100644 (file)
@@ -113,13 +113,24 @@ static void update_counter_and_wait(void)
        struct rcu_reader *index, *tmp;
 
 #if (BITS_PER_LONG < 64)
-       /* Switch parity: 1 -> 0, 0 -> 1 */
+       /* Switch parity: 0 -> 1, 1 -> 0 */
        STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR);
 #else  /* !(BITS_PER_LONG < 64) */
        /* Increment current G.P. */
        STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr + RCU_GP_CTR);
 #endif /* !(BITS_PER_LONG < 64) */
 
+       /*
+        * Enforce compiler-order of store to rcu_gp_ctr before before
+        * load rcu_reader ctr.
+        * This ensures synchronize_rcu() cannot be starved by readers.
+        *
+        * Adding a smp_mb() which is _not_ formally required, but makes the
+        * model easier to understand. It does not have a big performance impact
+        * anyway, given this is the write-side.
+        */
+       smp_mb();
+
        /*
         * Wait for each thread rcu_reader_qs_gp count to become 0.
         */
This page took 0.024802 seconds and 4 git commands to generate.