From 18d2acd2791a751c0b1894fd72dd0317583619cd Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Thu, 10 Nov 2022 12:20:19 -0500 Subject: nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. --- rts/include/stg/SMP.h | 2 ++ rts/sm/NonMovingMark.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'rts') diff --git a/rts/include/stg/SMP.h b/rts/include/stg/SMP.h index 2c14c17081..bb30935aed 100644 --- a/rts/include/stg/SMP.h +++ b/rts/include/stg/SMP.h @@ -580,6 +580,7 @@ load_load_barrier(void) { // These are typically necessary only in very specific cases (e.g. WSDeque) // where the ordered operations aren't expressive enough to capture the desired // ordering. +#define ACQUIRE_FENCE() __atomic_thread_fence(__ATOMIC_ACQUIRE) #define RELEASE_FENCE() __atomic_thread_fence(__ATOMIC_RELEASE) #define SEQ_CST_FENCE() __atomic_thread_fence(__ATOMIC_SEQ_CST) @@ -614,6 +615,7 @@ EXTERN_INLINE void load_load_barrier () {} /* nothing */ #define SEQ_CST_RELAXED_CAS(p,o,n) cas(p,o,n) // Fences +#define ACQUIRE_FENCE() #define RELEASE_FENCE() #define SEQ_CST_FENCE() diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c index d9758b943f..a42c3c46ce 100644 --- a/rts/sm/NonMovingMark.c +++ b/rts/sm/NonMovingMark.c @@ -1510,8 +1510,12 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) } case BLACKHOLE: { - PUSH_FIELD((StgInd *) p, indirectee); - StgClosure *indirectee = ((StgInd*)p)->indirectee; + // Synchronizes with the release-store in updateWithIndirection. + // See Note [Heap memory barriers] in SMP.h. + StgInd *ind = (StgInd *) p; + ACQUIRE_FENCE(); + StgClosure *indirectee = RELAXED_LOAD(&ind->indirectee); + markQueuePushClosure(queue, indirectee, &ind->indirectee); if (GET_CLOSURE_TAG(indirectee) == 0 || origin == NULL) { // do nothing } else { -- cgit v1.2.1