-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MDEV-33447: libpmem is not available in RHEL 8
Because the Red Hat Enterprise Linux 8 core repository does not include libpmem, let us implement the necessary subset ourselves. pmem_persist(): Implement for 64-bit x86, ARM, POWER, RISC-V, Loongarch in a way that should be compatible with the https://github.com/pmem/pmdk/ implementation of pmem_persist(). The CMake option WITH_INNODB_PMEM can be used for enabling or disabling this interface at compile time. By default, it is enabled on all applicable systems that are covered by our CI system. Note: libpmem had not been previously enabled for Loongarch in our Debian packaging. It was enabled for RISC-V, but we will not enable it by default on RISC-V or Loongarch because we lack CI coverage. The generated code for x86_64 was reviewed and tested on two Intel implementations: one that only supports clflush, and another that supports both clflushopt and clwb. The generated machine code was also reviewed on https://godbolt.org using various compiler versions. Godbolt helpfully includes an option to compile to binary code and display the encoding, which was useful on POWER. Reviewed by: Vladislav Vaintroub
- Loading branch information
Showing
10 changed files
with
182 additions
and
62 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/***************************************************************************** | ||
Copyright (c) 2024, MariaDB plc | ||
This program is free software; you can redistribute it and/or modify it under | ||
the terms of the GNU General Public License as published by the Free Software | ||
Foundation; version 2 of the License. | ||
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 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 Street, Fifth Floor, Boston, MA 02110-1335 USA | ||
*****************************************************************************/ | ||
|
||
#pragma once | ||
#include <cstddef> | ||
|
||
#if defined __x86_64__ || defined __aarch64__ | ||
struct pmem_control | ||
{ | ||
void (*persist)(const void *, size_t); | ||
public: | ||
pmem_control(); | ||
}; | ||
extern const pmem_control pmem; | ||
# define pmem_persist(buf, size) pmem.persist(buf, size) | ||
#else | ||
void pmem_persist(const void *buf, size_t size); | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/***************************************************************************** | ||
Copyright (c) 2024, MariaDB plc | ||
This program is free software; you can redistribute it and/or modify it under | ||
the terms of the GNU General Public License as published by the Free Software | ||
Foundation; version 2 of the License. | ||
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 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 Street, Fifth Floor, Boston, MA 02110-1335 USA | ||
*****************************************************************************/ | ||
|
||
/* This is based on the implementation of pmem_persist() in | ||
https://github.com/pmem/pmdk/, Copyright 2014-2020, Intel Corporation, | ||
last revised in libpmem-1.12.0. */ | ||
|
||
#include "my_global.h" | ||
#include "cache.h" | ||
#include <cstdint> | ||
|
||
#if defined __x86_64__ || defined __aarch64__ | ||
# ifdef __x86_64__ | ||
static void pmem_clflush(const void *buf, size_t size) | ||
{ | ||
for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), | ||
end= uintptr_t(buf) + size; | ||
u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) | ||
__asm__ __volatile__("clflush %0" :: | ||
"m"(*reinterpret_cast<const char*>(u)) : "memory"); | ||
} | ||
|
||
static void pmem_clflushopt(const void *buf, size_t size) | ||
{ | ||
for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), | ||
end= uintptr_t(buf) + size; | ||
u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) | ||
__asm__ __volatile__(".byte 0x66; clflush %0" /* clflushopt */ :: | ||
"m"(*reinterpret_cast<const char*>(u)) : "memory"); | ||
__asm__ __volatile__("sfence" ::: "memory"); | ||
} | ||
|
||
static void pmem_clwb(const void *buf, size_t size) | ||
{ | ||
for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), | ||
end= uintptr_t(buf) + size; | ||
u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) | ||
__asm__ __volatile__(".byte 0x66; xsaveopt %0" /* clwb */ :: | ||
"m"(*reinterpret_cast<const char*>(u)) : "memory"); | ||
__asm__ __volatile__("sfence" ::: "memory"); | ||
} | ||
|
||
# include <cpuid.h> | ||
static decltype(pmem_control::persist) pmem_persist_init() | ||
{ | ||
uint32_t eax= 0, ebx= 0, ecx= 0, edx= 0; | ||
__cpuid_count(7, 0, eax, ebx, ecx, edx); | ||
if (ebx & 1U<<24 /* CLWB */) | ||
return pmem_clwb; | ||
else if (ebx & 1U<<23 /* CLFLUSHOPT */) | ||
return pmem_clflushopt; | ||
else | ||
return pmem_clflush; | ||
} | ||
# elif defined __aarch64__ | ||
static void pmem_cvac(const void* buf, size_t size) | ||
{ | ||
for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), | ||
end= uintptr_t(buf) + size; | ||
u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) | ||
__asm__ __volatile__("dc cvac, %0" :: "r"(u) : "memory"); | ||
__asm__ __volatile__("dmb ishst" ::: "memory"); | ||
} | ||
|
||
static void pmem_cvap(const void* buf, size_t size) | ||
{ | ||
for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), | ||
end= uintptr_t(buf) + size; | ||
u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) | ||
__asm__ __volatile__(".arch armv8.2-a\n dc cvap, %0" :: "r"(u) : "memory"); | ||
__asm__ __volatile__("dmb ishst" ::: "memory"); | ||
} | ||
|
||
# include <sys/auxv.h> | ||
# include <asm/hwcap.h> | ||
# ifndef HWCAP_DCPOP | ||
# define HWCAP_DCPOP (1 << 16) | ||
# endif | ||
|
||
static decltype(pmem_control::persist) pmem_persist_init() | ||
{ | ||
return (getauxval(AT_HWCAP) & HWCAP_DCPOP) ? pmem_cvap : pmem_cvac; | ||
} | ||
# endif | ||
|
||
pmem_control::pmem_control() : persist(pmem_persist_init()) {} | ||
const pmem_control pmem; | ||
#else | ||
void pmem_persist(const void *buf, size_t size) | ||
{ | ||
# ifdef __ppc64__ | ||
for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), | ||
end= uintptr_t(buf) + size; | ||
u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) | ||
{ | ||
/* GCC is just passing the inline asm snippets to the assembler, | ||
and it does not even define these mnemonics by itself. Clang does, | ||
and it includes a built-in assembler. | ||
Let us hope that having a recent enough GCC is an adequate proxy | ||
for having a recent enough assembler. */ | ||
# if __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 12) | ||
__asm__ __volatile__("dcbstps 0,%0" :: r(u) : "memory"); | ||
# else | ||
__asm__ __volatile__(".long (0x7cc000AC | %0 << 11)" :: "r"(u) : "memory"); | ||
# endif | ||
} | ||
|
||
# if __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 18) | ||
__asm__ __volatile__("phwsync" ::: "memory"); | ||
# else | ||
__asm__ __volatile__(".long 0x7c80040a" ::: "memory"); | ||
# endif | ||
# elif defined __riscv && __riscv_xlen == 64 | ||
__asm__ __volatile__("fence w,w" ::: "memory"); | ||
# elif defined __loongarch64 | ||
__asm__ __volatile__("dbar 0" ::: "memory"); | ||
# else | ||
# error "Missing implementation; recompile with cmake -DWITH_INNODB_PMEM=OFF" | ||
# endif | ||
} | ||
#endif |
3f9f5ca
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dr-m i can´t find a mariadb 10.11.x snapshot for windows here https://ci.mariadb.org/
windows builds failing ?
3f9f5ca
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You’d better ask such questions on https://mariadb.zulipchat.com in the "buildbot" stream, or in one of the mailing lists listed at https://mariadb.org/contribute/. Tests on Windows are part of the main branch protection, so they should not fail, but I don’t think that any packages for Windows are being made available via that interface. I am not familiar with the release process.