From 48f3378d6c620e99f17679ee11982a57640d3bb4 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 1 Jun 2024 16:26:12 +0200 Subject: [PATCH] [3.13] gh-117657: Fix TSAN race in free-threaded GC (GH-119883) (#119903) 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`. (cherry picked from commit 60593b2052ca275559c11028d50e19f8e5dfee13) Co-authored-by: Sam Gross --- Python/gc_free_threading.c | 5 ++--- Tools/tsan/suppressions_free_threading.txt | 3 --- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index ee006bb4aa12b7..e6bd012c40ee82 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -86,7 +86,7 @@ worklist_pop(struct worklist *worklist) PyObject *op = (PyObject *)worklist->head; if (op != NULL) { worklist->head = op->ob_tid; - op->ob_tid = 0; + _Py_atomic_store_uintptr_relaxed(&op->ob_tid, 0); } return op; } @@ -189,6 +189,7 @@ merge_refcount(PyObject *op, Py_ssize_t extra) static void gc_restore_tid(PyObject *op) { + assert(_PyInterpreterState_GET()->stoptheworld.world_stopped); mi_segment_t *segment = _mi_ptr_segment(op); if (_Py_REF_IS_MERGED(op->ob_ref_shared)) { op->ob_tid = 0; @@ -676,7 +677,6 @@ call_weakref_callbacks(struct collection_state *state) Py_DECREF(temp); } - gc_restore_tid(op); Py_DECREF(op); // drop worklist reference } } @@ -986,7 +986,6 @@ cleanup_worklist(struct worklist *worklist) { PyObject *op; while ((op = worklist_pop(worklist)) != NULL) { - gc_restore_tid(op); gc_clear_unreachable(op); Py_DECREF(op); } diff --git a/Tools/tsan/suppressions_free_threading.txt b/Tools/tsan/suppressions_free_threading.txt index dfa4a1fe9ca438..27568c34e1689e 100644 --- a/Tools/tsan/suppressions_free_threading.txt +++ b/Tools/tsan/suppressions_free_threading.txt @@ -37,7 +37,6 @@ race_top:_PyImport_ReleaseLock race_top:_PyParkingLot_Park race_top:_PyType_HasFeature race_top:assign_version_tag -race_top:gc_restore_tid race_top:insertdict race_top:lookup_tp_dict race_top:mi_heap_visit_pages @@ -65,7 +64,6 @@ race_top:list_get_item_ref race_top:make_pending_calls race_top:set_add_entry race_top:should_intern_string -race_top:worklist_pop race_top:_PyEval_IsGILEnabled race_top:llist_insert_tail race_top:_Py_slot_tp_getattr_hook @@ -87,7 +85,6 @@ race_top:sock_close race_top:tstate_delete_common race_top:tstate_is_freed race_top:type_modified_unlocked -race_top:update_refs race_top:write_thread_id race_top:PyThreadState_Clear