From: Sam Gross Date: Wed, 26 Feb 2025 18:59:59 +0000 (-0500) Subject: [3.13] gh-117657: Enable test_opcache under TSAN (GH-129831) (GH-130597) X-Git-Tag: v3.13.3~205 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9966daee602ef8413990683d6fd6f51e6392b885;p=thirdparty%2FPython%2Fcpython.git [3.13] gh-117657: Enable test_opcache under TSAN (GH-129831) (GH-130597) Fix a few thread-safety bugs to enable test_opcache when run with TSAN: * Use relaxed atomics when clearing `ht->_spec_cache.getitem` (gh-115999) * Add temporary suppression for type slot modifications (gh-127266) * Use atomic load when reading `*dictptr` (cherry picked from commit f151d271591ec525eaf01fa7b128e575374888b9) --- diff --git a/Lib/test/libregrtest/tsan.py b/Lib/test/libregrtest/tsan.py index 822ac0f4044d..0c0ab20fa0b0 100644 --- a/Lib/test/libregrtest/tsan.py +++ b/Lib/test/libregrtest/tsan.py @@ -13,6 +13,7 @@ TSAN_TESTS = [ 'test_importlib', 'test_io', 'test_logging', + 'test_opcache', 'test_queue', 'test_signal', 'test_socket', diff --git a/Objects/object.c b/Objects/object.c index c0ce4291eb73..0539bcbb4621 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1584,7 +1584,7 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) else { PyObject **dictptr = _PyObject_ComputedDictPointer(obj); if (dictptr != NULL) { - dict = *dictptr; + dict = FT_ATOMIC_LOAD_PTR_ACQUIRE(*dictptr); } else { dict = NULL; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c84841070555..6e8064540e51 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1043,7 +1043,8 @@ type_modified_unlocked(PyTypeObject *type) if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { // This field *must* be invalidated if the type is modified (see the // comment on struct _specialization_cache): - ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL; + FT_ATOMIC_STORE_PTR_RELAXED( + ((PyHeapTypeObject *)type)->_spec_cache.getitem, NULL); } } @@ -1119,7 +1120,8 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { // This field *must* be invalidated if the type is modified (see the // comment on struct _specialization_cache): - ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL; + FT_ATOMIC_STORE_PTR_RELAXED( + ((PyHeapTypeObject *)type)->_spec_cache.getitem, NULL); } } diff --git a/Tools/tsan/suppressions_free_threading.txt b/Tools/tsan/suppressions_free_threading.txt index 6add088daef7..5ba0a81ac71c 100644 --- a/Tools/tsan/suppressions_free_threading.txt +++ b/Tools/tsan/suppressions_free_threading.txt @@ -47,5 +47,8 @@ race_top:PyThreadState_Clear # Only seen on macOS, sample: https://gist.github.com/aisk/dda53f5d494a4556c35dde1fce03259c race_top:set_default_allocator_unlocked +# gh-127266: type slot updates are not thread-safe (test_opcache.test_load_attr_method_lazy_dict) +race_top:update_one_slot + # https://gist.github.com/mpage/6962e8870606cfc960e159b407a0cb40 thread:pthread_create