Index: sys/kern/subr_smr.c =================================================================== --- sys/kern/subr_smr.c +++ sys/kern/subr_smr.c @@ -275,7 +275,7 @@ c = zpcpu_get_cpu(smr, i); c_seq = SMR_SEQ_INVALID; for (;;) { - c_seq = atomic_load_int(&c->c_seq); + c_seq = atomic_load_acq_int(&c->c_seq); if (c_seq == SMR_SEQ_INVALID) break; @@ -323,15 +323,21 @@ if (c_seq != SMR_SEQ_INVALID && SMR_SEQ_GT(rd_seq, c_seq)) rd_seq = c_seq; } + /* Same semantic for reads of c->c_seq above as in smr_enter(). */ + atomic_thread_fence_acq(); /* * Advance the rd_seq as long as we observed the most recent one. */ s_rd_seq = atomic_load_int(&s->s_rd_seq); - do { + for (;;) { if (SMR_SEQ_LEQ(rd_seq, s_rd_seq)) break; - } while (atomic_fcmpset_int(&s->s_rd_seq, &s_rd_seq, rd_seq) == 0); + if (atomic_fcmpset_int(&s->s_rd_seq, &s_rd_seq, rd_seq) != 0) { + atomic_thread_fence_rel(); + break; + } + } out: critical_exit(); Index: tools/uma/smrstress/smrstress.c =================================================================== --- tools/uma/smrstress/smrstress.c +++ tools/uma/smrstress/smrstress.c @@ -84,7 +84,7 @@ /* Wait for the writer to exit. */ while (smrs_completed == 0) { smr_enter(smrs_smr); - cur = (void *)atomic_load_ptr(&smrs_current); + cur = (void *)atomic_load_acq_ptr(&smrs_current); if (cur->generation == -1) smrs_error(cur, "read early: Use after free!\n"); atomic_add_int(&cur->count, 1); @@ -107,6 +107,7 @@ for (i = 0; i < smrs_iterations; i++) { cur = uma_zalloc_smr(smrs_zone, M_WAITOK); + atomic_thread_fence_rel(); cur = (void *)atomic_swap_ptr(&smrs_current, (uintptr_t)cur); uma_zfree_smr(smrs_zone, cur); }