From 1159dbe75fc0f8fc36f31225cefb4e3de9fc7100 Mon Sep 17 00:00:00 2001 From: Wenlong Zhang Date: Fri, 12 Jan 2024 08:36:20 +0000 Subject: [PATCH] mysql 8.0.33 binary crashes on startup on loongarch64 --- add-loongarch64-support-for-mysql.patch | 39 +++ mysql.spec | 9 +- revert-be8348a7.patch | 417 ++++++++++++++++++++++++ 3 files changed, 464 insertions(+), 1 deletion(-) create mode 100644 add-loongarch64-support-for-mysql.patch create mode 100644 revert-be8348a7.patch diff --git a/add-loongarch64-support-for-mysql.patch b/add-loongarch64-support-for-mysql.patch new file mode 100644 index 0000000..fb6215c --- /dev/null +++ b/add-loongarch64-support-for-mysql.patch @@ -0,0 +1,39 @@ +From ce258625ef5aa2fb6d5825af9e4000faefa452a9 Mon Sep 17 00:00:00 2001 +From: Wenlong Zhang +Date: Fri, 12 Jan 2024 09:27:08 +0800 +Subject: [PATCH] add loongarch64 support for mysql + +--- + boost/boost_1_77_0/boost/predef/other/endian.h | 1 + + .../icu/icu-release-69-1/source/i18n/double-conversion-utils.h | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/boost/boost_1_77_0/boost/predef/other/endian.h b/boost/boost_1_77_0/boost/predef/other/endian.h +index d8ec63ff..255a2587 100644 +--- a/boost/boost_1_77_0/boost/predef/other/endian.h ++++ b/boost/boost_1_77_0/boost/predef/other/endian.h +@@ -125,6 +125,7 @@ information and acquired knowledge: + defined(__MIPSEL) || \ + defined(__MIPSEL__) || \ + defined(__riscv) || \ ++ defined(__loongarch__) || \ + defined(__e2k__) + # undef BOOST_ENDIAN_LITTLE_BYTE + # define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +diff --git a/extra/icu/icu-release-69-1/source/i18n/double-conversion-utils.h b/extra/icu/icu-release-69-1/source/i18n/double-conversion-utils.h +index c9374636..44e55d58 100644 +--- a/extra/icu/icu-release-69-1/source/i18n/double-conversion-utils.h ++++ b/extra/icu/icu-release-69-1/source/i18n/double-conversion-utils.h +@@ -128,7 +128,8 @@ int main(int argc, char** argv) { + defined(__riscv) || defined(__e2k__) || \ + defined(__or1k__) || defined(__arc__) || \ + defined(__microblaze__) || defined(__XTENSA__) || \ +- defined(__EMSCRIPTEN__) || defined(__wasm32__) ++ defined(__EMSCRIPTEN__) || defined(__wasm32__) || \ ++ defined(__loongarch__) + #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 + #elif defined(__mc68000__) || \ + defined(__pnacl__) || defined(__native_client__) +-- +2.41.0 + diff --git a/mysql.spec b/mysql.spec index 2a0445e..0a47e0a 100644 --- a/mysql.spec +++ b/mysql.spec @@ -1,4 +1,4 @@ -%define anolis_release 2 +%define anolis_release 3 # Name of the package without any prefixes %global pkg_name %{name} %global pkgnamepatch mysql @@ -116,6 +116,8 @@ Patch53: %{pkgnamepatch}-mtr.patch # Patches taken from boost 1.59 Patch111: boost-1.57.0-mpl-print.patch Patch112: boost-1.58.0-pool.patch +Patch113: revert-be8348a7.patch +Patch114: add-loongarch64-support-for-mysql.patch BuildRequires: cmake BuildRequires: gcc-c++ @@ -374,6 +376,8 @@ pushd boost/boost_$(echo %{boost_bundled_version}| tr . _) %patch111 -p1 %patch112 -p1 popd +%patch113 -p1 +%patch114 -p1 # generate a list of tests that fail, but are not disabled by upstream cat %{SOURCE50} | tee -a mysql-test/%{skiplist} @@ -927,6 +931,9 @@ fi %endif %changelog +* Fri Jan 12 2024 Wenlong Zhang - 8.0.33-3 +- mysql 8.0.33 binary crashes on startup on loongarch64 + * Wed Dec 27 2023 Chang Gao - 8.0.33-2 - Correct the source url diff --git a/revert-be8348a7.patch b/revert-be8348a7.patch new file mode 100644 index 0000000..b394e3a --- /dev/null +++ b/revert-be8348a7.patch @@ -0,0 +1,417 @@ +From 0f8503643565e78b13c3d61a6839c149bccab9c6 Mon Sep 17 00:00:00 2001 +From: Wenlong Zhang +Date: Fri, 12 Jan 2024 14:56:17 +0800 +Subject: [PATCH] revert be8348a7 +This patch reverts the following commit: + +From be8348a7c3e8510b998a063065b626a459631b32 Mon Sep 17 00:00:00 2001 +From: Slawomir Maludzinski +Date: Mon, 12 Dec 2022 15:37:29 +0100 +Subject: [PATCH] BUG#34849343 Aligned_atomic not working as intended - + aligned_alloc + +Problem +------- +The Aligned_atomic class in sql/memory/aligned_atomic.h was created with the +intention to align and pad a std::atomic object so that it starts at the +beginning of a cache line and is padded so that it fills the entire cache +line. The intended use case was to ensure that an array of Aligned_atomic +objects keeps the elements in contiguous memory but different cache lines, +eliminating false sharing. + +Aligned_atomic is implemented by constructing a new char* buffer the size of +a cache line, and then in-place-construct a std::atomic at the beginning +of the buffer. It keeps a std::atomic* as a member; this member is aligned +to the cache line size. + +This only has performance impact, no functional defect. + +Analysis / Root-cause analysis +------------------------------ +This implementation does not seem meet the intentions, AFAIU: +- There is a call to `new` for each Aligned_atomic object. So the elements +are not contiguous. +- The pointer to the buffer is aligned, but not the buffer itself. So it is +possible that the buffer begins in the middle of a cache line and extends +into the next cache line. In fact, if the alignment is smaller than the size +of the atomic type, an std::atomic may intersect with two cache lines, and if +two such objects end up adjacent to each other, there can be false sharing. +More likely, there can be false sharing between the Aligned_atomic and some +object of another type. + +The major drawback is probably that the construction of an array of +Aligned_atomic will allocate many small objects instead of one big, which +uses more memory and CPU than necessary. + +--- + include/my_aligned_malloc.h | 55 ---------------- + mysys/CMakeLists.txt | 1 - + mysys/my_aligned_malloc.cc | 79 ----------------------- + sql/memory/aligned_atomic.h | 71 ++++++-------------- + unittest/gunit/memory/aligned_atomic-t.cc | 34 ---------- + 5 files changed, 18 insertions(+), 222 deletions(-) + delete mode 100644 include/my_aligned_malloc.h + delete mode 100644 mysys/my_aligned_malloc.cc + +diff --git a/include/my_aligned_malloc.h b/include/my_aligned_malloc.h +deleted file mode 100644 +index 1673b744..00000000 +--- a/include/my_aligned_malloc.h ++++ /dev/null +@@ -1,55 +0,0 @@ +-/* Copyright (c) 2022, 2023, Oracle and/or its affiliates. +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License, version 2.0, +- as published by the Free Software Foundation. +- +- This program is also distributed with certain software (including +- but not limited to OpenSSL) that is licensed under separate terms, +- as designated in a particular file or component or in included license +- documentation. The authors of MySQL hereby grant you an additional +- permission to link the program and your derivative works with the +- separately licensed software that they have included with MySQL. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License, version 2.0, for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, write to the Free Software +- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +- +-#ifndef __MY_ALIGNED_MALLOC_H__ +-#define __MY_ALIGNED_MALLOC_H__ +- +-#include +- +-/** +- Function allocates size bytes and returns a pointer to the allocated memory. +- Size and alignment parameters depend on platform on which the function is +- executed. Please check posix_memalign, memalign and _aligned_malloc functions +- for details. To conform with all platforms size should be multiple of aligment +- and aligment should be power of two. +- +- We can use C++17 aligned new/aligned delete on non-windows platforms once the +- minimum supported version of tcmalloc becomes >= 2.6.2. Right now TC malloc +- crashes. +- +- @param[in] size Multiple of alignment. +- @param[in] alignment Memory aligment, which must be power of two. +- +- @return Pointer to allocated memory. +- +- @see my_aligned_free +-*/ +-void *my_aligned_malloc(size_t size, size_t alignment); +- +-/** +- Free allocated memory using my_aligned_malloc function. +- +- @param[in] ptr Pointer to allocated memory using my_aligned_malloc function. +-*/ +-void my_aligned_free(void *ptr); +- +-#endif /* __MY_ALIGNED_MALLOC_H__ */ +diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt +index 7b2f108c..e83d1642 100644 +--- a/mysys/CMakeLists.txt ++++ b/mysys/CMakeLists.txt +@@ -55,7 +55,6 @@ SET(MYSYS_SOURCES + mf_wcomp.cc + mulalloc.cc + my_access.cc +- my_aligned_malloc.cc + my_alloc.cc + my_bit.cc + my_bitmap.cc +diff --git a/mysys/my_aligned_malloc.cc b/mysys/my_aligned_malloc.cc +deleted file mode 100644 +index 8de56246..00000000 +--- a/mysys/my_aligned_malloc.cc ++++ /dev/null +@@ -1,79 +0,0 @@ +-/* Copyright (c) 2022, 2023, Oracle and/or its affiliates. +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License, version 2.0, +- as published by the Free Software Foundation. +- +- This program is also distributed with certain software (including +- but not limited to OpenSSL) that is licensed under separate terms, +- as designated in a particular file or component or in included license +- documentation. The authors of MySQL hereby grant you an additional +- permission to link the program and your derivative works with the +- separately licensed software that they have included with MySQL. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License, version 2.0, for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, write to the Free Software +- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +-#include "my_aligned_malloc.h" +- +-#include "config.h" +- +-#if defined(HAVE_POSIX_MEMALIGN) +-#include +-#elif defined(HAVE_MEMALIGN) +-#include +-#elif defined(HAVE_ALIGNED_MALLOC) +-#include +-#include +-#else +-#error "Missing implementation for posix_memalign, memalign or _aligned_malloc" +-#endif +- +-void *my_aligned_malloc(size_t size, size_t alignment) { +- void *ptr = nullptr; +-#if defined(HAVE_POSIX_MEMALIGN) +- /* Linux */ +- if (posix_memalign(&ptr, alignment, size)) { +- return nullptr; +- } +-#elif defined(HAVE_MEMALIGN) +- /* Solaris */ +- ptr = memalign(alignment, size); +- if (ptr == NULL) { +- return NULL; +- } +-#elif defined(HAVE_ALIGNED_MALLOC) +- /* Windows */ +- ptr = _aligned_malloc(size, alignment); +- if (ptr == NULL) { +- return NULL; +- } +-#else +-#error "Missing implementation for posix_memalign, memalign or _aligned_malloc" +-#endif +- return ptr; +-} +- +-void my_aligned_free(void *ptr) { +- if (ptr == nullptr) { +- return; +- } +-#if defined(HAVE_POSIX_MEMALIGN) +- /* Allocated with posix_memalign() */ +- free(ptr); +-#elif defined(HAVE_MEMALIGN) +- /* Allocated with memalign() */ +- free(ptr); +-#elif defined(HAVE_ALIGNED_MALLOC) +- /* Allocated with _aligned_malloc() */ +- _aligned_free(ptr); +-#else +- /* Allocated with malloc() */ +- free(ptr); +-#endif +-} +diff --git a/sql/memory/aligned_atomic.h b/sql/memory/aligned_atomic.h +index 423366da..985efb75 100644 +--- a/sql/memory/aligned_atomic.h ++++ b/sql/memory/aligned_atomic.h +@@ -38,9 +38,8 @@ + #include + #endif + +-#include "my_aligned_malloc.h" +- + namespace memory { ++ + /** + Calculates and returns the size of the CPU cache line. + +@@ -259,28 +258,14 @@ class Aligned_atomic { + + @return The pointer to the underlying `std::atomic` object. + */ +- std::atomic *operator->(); +- /* +- Pointer operator that allows the access to the underlying `std::atomic` +- object. +- +- @return The const pointer to the underlying `std::atomic` object. +- */ +- const std::atomic *operator->() const; ++ std::atomic *operator->() const; + /* + Dereference operator that allows the access to the underlying + `std::atomic` object. + + @return The reference to the underlying `std::atomic` object. + */ +- std::atomic &operator*(); +- /* +- Dereference operator that allows the access to the underlying +- `std::atomic` object. +- +- @return The const reference to the underlying `std::atomic` object. +- */ +- const std::atomic &operator*() const; ++ std::atomic &operator*() const; + /* + The size of `std::atomic`, as returned by `sizeof std::atomic`. + +@@ -298,7 +283,7 @@ class Aligned_atomic { + /** The size of the byte buffer. */ + size_t m_storage_size{0}; + /** The byte buffer to use as underlying storage. */ +- void *m_storage{nullptr}; ++ alignas(std::max_align_t) unsigned char *m_storage{nullptr}; + /** The pointer to the underlying `std::atomic` object. */ + std::atomic *m_underlying{nullptr}; + }; +@@ -306,10 +291,9 @@ class Aligned_atomic { + + template + memory::Aligned_atomic::Aligned_atomic() +- : m_storage_size{memory::minimum_cacheline_for>()} { +- m_storage = my_aligned_malloc(m_storage_size, cache_line_size()); +- m_underlying = new (this->m_storage) std::atomic(); +-} ++ : m_storage_size{memory::minimum_cacheline_for>()}, ++ m_storage{new unsigned char[m_storage_size]}, ++ m_underlying{new (this->m_storage) std::atomic()} {} + + template + memory::Aligned_atomic::Aligned_atomic(T value) +@@ -318,16 +302,12 @@ memory::Aligned_atomic::Aligned_atomic(T value) + } + + template +-memory::Aligned_atomic::Aligned_atomic(Aligned_atomic &&rhs) { +- if (this->m_underlying != nullptr) { +- this->m_underlying->~atomic(); +- } +- my_aligned_free(this->m_storage); ++memory::Aligned_atomic::Aligned_atomic(Aligned_atomic &&rhs) ++ : m_storage_size{rhs.m_storage_size}, m_underlying{rhs.m_underlying} { ++ delete[] this->m_storage; + this->m_storage = rhs.m_storage; +- this->m_storage_size = rhs.m_storage_size; +- this->m_underlying = rhs.m_underlying; +- rhs.m_storage = nullptr; + rhs.m_storage_size = 0; ++ rhs.m_storage = nullptr; + rhs.m_underlying = nullptr; + } + +@@ -335,25 +315,22 @@ template + memory::Aligned_atomic::~Aligned_atomic() { + if (this->m_underlying != nullptr) { + this->m_underlying->~atomic(); ++ this->m_underlying = nullptr; + } +- my_aligned_free(this->m_storage); ++ delete[] this->m_storage; + this->m_storage = nullptr; + this->m_storage_size = 0; +- this->m_underlying = nullptr; + } + + template + memory::Aligned_atomic &memory::Aligned_atomic::operator=( + Aligned_atomic &&rhs) { +- if (this->m_underlying != nullptr) { +- this->m_underlying->~atomic(); +- } +- my_aligned_free(this->m_storage); +- this->m_storage = rhs.m_storage; ++ delete[] this->m_storage; + this->m_storage_size = rhs.m_storage_size; ++ this->m_storage = rhs.m_storage; + this->m_underlying = rhs.m_underlying; +- rhs.m_storage = nullptr; + rhs.m_storage_size = 0; ++ rhs.m_storage = nullptr; + rhs.m_underlying = nullptr; + return (*this); + } +@@ -393,25 +370,13 @@ bool memory::Aligned_atomic::operator!=(T rhs) const { + } + + template +-std::atomic *memory::Aligned_atomic::operator->() { +- assert(this->m_underlying != nullptr); +- return this->m_underlying; +-} +- +-template +-const std::atomic *memory::Aligned_atomic::operator->() const { ++std::atomic *memory::Aligned_atomic::operator->() const { + assert(this->m_underlying != nullptr); + return this->m_underlying; + } + + template +-std::atomic &memory::Aligned_atomic::operator*() { +- assert(this->m_underlying != nullptr); +- return *this->m_underlying; +-} +- +-template +-const std::atomic &memory::Aligned_atomic::operator*() const { ++std::atomic &memory::Aligned_atomic::operator*() const { + assert(this->m_underlying != nullptr); + return *this->m_underlying; + } +diff --git a/unittest/gunit/memory/aligned_atomic-t.cc b/unittest/gunit/memory/aligned_atomic-t.cc +index 39ac0724..63fdc3aa 100644 +--- a/unittest/gunit/memory/aligned_atomic-t.cc ++++ b/unittest/gunit/memory/aligned_atomic-t.cc +@@ -25,9 +25,7 @@ + #include + #include + +-#define private public + #include "sql/memory/aligned_atomic.h" +-#undef private + + #include + #include +@@ -59,37 +57,5 @@ TEST_F(Aligned_atomic_test, Class_template_test) { + EXPECT_EQ(atm3->load(), 2); + } + +-TEST_F(Aligned_atomic_test, minimum_cacheline_for) { +- EXPECT_EQ(memory::minimum_cacheline_for(), memory::cache_line_size()); +- EXPECT_EQ(memory::minimum_cacheline_for(), memory::cache_line_size()); +- EXPECT_EQ(memory::minimum_cacheline_for>(), +- memory::cache_line_size()); +- EXPECT_EQ(memory::minimum_cacheline_for>(), +- memory::cache_line_size()); +-} +- +-TEST_F(Aligned_atomic_test, aligned_allocation) { +- memory::Aligned_atomic atm1{1}; +- EXPECT_EQ((unsigned long long)atm1.m_underlying % memory::cache_line_size(), +- 0); +- +- memory::Aligned_atomic atm2{true}; +- EXPECT_EQ((unsigned long long)atm2.m_underlying % memory::cache_line_size(), +- 0); +- +- memory::Aligned_atomic atm3{0}; +- EXPECT_EQ((unsigned long long)atm3.m_underlying % memory::cache_line_size(), +- 0); +-} +- +-TEST_F(Aligned_atomic_test, aligned_allocation_array) { +- static const int array_size = 10; +- memory::Aligned_atomic atm[array_size]; +- +- for (int i = 0; i < array_size; i++) +- EXPECT_EQ( +- (unsigned long long)atm[i].m_underlying % memory::cache_line_size(), 0); +-} +- + } // namespace unittests + } // namespace memory +-- +2.41.0 + -- Gitee