gh-148613: Fix race in gc_set_threshold and gc_get_threshold#150356
gh-148613: Fix race in gc_set_threshold and gc_get_threshold#150356LindaSummer wants to merge 5 commits into
gc_set_threshold and gc_get_threshold#150356Conversation
|
Hi @picnixz, Sorry to bother you. Wish you a good day! |
|
I think this fix can be correct but this doesn't really fix the underlying problem: we are reading unsynced values so this change doesn't give us any guarantees that the values are consistent with a concurrent call to set them. Indeed we could read half of them from one write and another half from another. I think this is fine but perhaps we need exclusive access. @nascheme what do you think? |
|
I think so as well. It will only mitigate some cases. AFAIU, the problem is that we have 3 values to read or write but these values can be changed by another thread at any moment right? the correct fix should be to lock the entire GC state when writing or reading. Note that |
|
The approach of "sprinkling in" relaxed atomics to silence TSAN warnings is not correct, IMO. They don't ensure ordering. I'd suggest we keep using relaxed atomics for |
Hi @nascheme , @picnixz and @pablogsal , Thanks very much for your review and suggestions! |
4cdb1dc to
8b997a9
Compare
Issue
gh-148613
Root Cause
In free-threading, the
gc_generation.thresholdraces in threads when one thread has objects triggered the GC.cpython/Python/gc_free_threading.c
Lines 2025 to 2031 in cb72193
Inside
gc_should_collectwe read thegcstate->young.thresholdandgcstate->old[0].thresholdwithout thread syncing.cpython/Python/gc_free_threading.c
Lines 1996 to 2004 in cb72193
At the same time, the
thresholdsetting also has no syncing protection.cpython/Modules/gcmodule.c
Lines 170 to 175 in cb72193
This explains why a cyclic referenced object caused this TSAN report.
The cyclic object couldn't make ref count to zero in scoped call stack, and it increments the
_gc_thread_state.alloc_counttoLOCAL_ALLOC_COUNT_THRESHOLD.Then the GC collect triggered in this thread and races with another thread's update of
gc_generation.threshold.Proposed Changes
Add relaxed atomic load/store protection for the
gc_generation.thresholdsetter and getter.