From fc10f2b07238ea6e1d7f43e1e70d3cef5f0db7a4 Mon Sep 17 00:00:00 2001 From: Daniel Lenski Date: Fri, 7 Jul 2023 12:13:11 -0700 Subject: [PATCH] Architecture-agnostic fix for crashes caused by cache coherency_line_size of 0 in sysfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous fixes for this issue have been piecemeal and CPU architecture-specific: - For s390x: BUG#34095278, https://bugs.mysql.com/bug.php?id=107081 → f2d64bfa575700234d5f36418d5ef143b54e2a16 for s390x - For armhf: https://bugs.mysql.com/bug.php?id=110752 - All other arm variants are also affected (confirmed by us for arm64) It would be far better to address this in a proactive, architecture-agnostic way, to prevent future cases on unexpected CPU architecture or ABI variants. We can do this by making the `_cache_line_size()` function check for invalid values in sysfs (`/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size`), and fall back to 64 as a default return value. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services --- sql/memory/aligned_atomic.h | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/sql/memory/aligned_atomic.h b/sql/memory/aligned_atomic.h index 423366dab386..65813720aaf3 100644 --- a/sql/memory/aligned_atomic.h +++ b/sql/memory/aligned_atomic.h @@ -80,19 +80,21 @@ static inline size_t _cache_line_size() { #elif defined(__linux__) static inline size_t _cache_line_size() { long size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); - if (size == -1) return 64; -#if defined(__s390x__) - // returns 0 on s390x RHEL 7.x - if (size == 0) { - FILE *p = fopen( - "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r"); - if (p) { - fscanf(p, "%ld", &size); - fclose(p); - } + if (size > 0) + return static_cast(size); + // Known to return 0 on s390x RHEL 7.x, and armhf + + FILE *p = fopen( + "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r"); + if (p) { + fscanf(p, "%ld", &size); + fclose(p); } -#endif - return static_cast(size); + if (size > 0) + return static_cast(size); + + // Default to 64 + return 64; } #else