Skip to content

Commit 60593b2

Browse files
authored
gh-117657: Fix TSAN race in free-threaded GC (#119883)
Only call `gc_restore_tid()` from stop-the-world contexts. `worklist_pop()` can be called while other threads are running, so use a relaxed atomic to modify `ob_tid`.
1 parent 5152120 commit 60593b2

File tree

2 files changed

+2
-6
lines changed

2 files changed

+2
-6
lines changed

Python/gc_free_threading.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ worklist_pop(struct worklist *worklist)
8686
PyObject *op = (PyObject *)worklist->head;
8787
if (op != NULL) {
8888
worklist->head = op->ob_tid;
89-
op->ob_tid = 0;
89+
_Py_atomic_store_uintptr_relaxed(&op->ob_tid, 0);
9090
}
9191
return op;
9292
}
@@ -189,6 +189,7 @@ merge_refcount(PyObject *op, Py_ssize_t extra)
189189
static void
190190
gc_restore_tid(PyObject *op)
191191
{
192+
assert(_PyInterpreterState_GET()->stoptheworld.world_stopped);
192193
mi_segment_t *segment = _mi_ptr_segment(op);
193194
if (_Py_REF_IS_MERGED(op->ob_ref_shared)) {
194195
op->ob_tid = 0;
@@ -676,7 +677,6 @@ call_weakref_callbacks(struct collection_state *state)
676677
Py_DECREF(temp);
677678
}
678679

679-
gc_restore_tid(op);
680680
Py_DECREF(op); // drop worklist reference
681681
}
682682
}
@@ -986,7 +986,6 @@ cleanup_worklist(struct worklist *worklist)
986986
{
987987
PyObject *op;
988988
while ((op = worklist_pop(worklist)) != NULL) {
989-
gc_restore_tid(op);
990989
gc_clear_unreachable(op);
991990
Py_DECREF(op);
992991
}

Tools/tsan/suppressions_free_threading.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ race_top:_PyImport_ReleaseLock
3737
race_top:_PyParkingLot_Park
3838
race_top:_PyType_HasFeature
3939
race_top:assign_version_tag
40-
race_top:gc_restore_tid
4140
race_top:insertdict
4241
race_top:lookup_tp_dict
4342
race_top:mi_heap_visit_pages
@@ -64,7 +63,6 @@ race_top:list_get_item_ref
6463
race_top:make_pending_calls
6564
race_top:set_add_entry
6665
race_top:should_intern_string
67-
race_top:worklist_pop
6866
race_top:_PyEval_IsGILEnabled
6967
race_top:llist_insert_tail
7068
race_top:_Py_slot_tp_getattr_hook
@@ -86,7 +84,6 @@ race_top:sock_close
8684
race_top:tstate_delete_common
8785
race_top:tstate_is_freed
8886
race_top:type_modified_unlocked
89-
race_top:update_refs
9087
race_top:write_thread_id
9188
race_top:PyThreadState_Clear
9289

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy