MySQL 8.4.0
Source Code Documentation
large_page_alloc-solaris.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2021, 2024, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is designed to work with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation. The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have either included with
15the program or referenced in the documentation.
16
17This program is distributed in the hope that it will be useful, but WITHOUT
18ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20for more details.
21
22You should have received a copy of the GNU General Public License along with
23this program; if not, write to the Free Software Foundation, Inc.,
2451 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
26*****************************************************************************/
27
28/** @file include/detail/ut/large_page_alloc-solaris.h
29 Solaris-specific implementation bits and pieces for large (huge) page
30 allocations. */
31
32#ifndef detail_ut_large_page_alloc_solaris_h
33#define detail_ut_large_page_alloc_solaris_h
34
35#include <sys/mman.h>
36#include <sys/types.h>
37
38#include "mysqld_error.h"
41
42extern const size_t large_page_default_size;
43
44namespace ut {
45namespace detail {
46
47/** Allocates memory backed by large (huge) pages.
48
49 @param[in] n_bytes Size of storage (in bytes) requested to be allocated.
50 @return Pointer to the allocated storage. nullptr if allocation failed.
51*/
52inline void *large_page_aligned_alloc(size_t n_bytes) {
53 // mmap on Solaris requires for n_bytes to be a multiple of large-page size
54 size_t n_bytes_rounded = pow2_round(n_bytes + (large_page_default_size - 1),
56 void *ptr = mmap(nullptr, n_bytes_rounded, PROT_READ | PROT_WRITE,
57 MAP_PRIVATE | MAP_ANON, -1, 0);
58 if (unlikely(ptr == (void *)-1)) {
59 ib::log_warn(ER_IB_MSG_856)
60 << "large_page_aligned_alloc mmap(" << n_bytes_rounded
61 << " bytes) failed;"
62 " errno "
63 << errno;
64 }
65 // We also must do additional step to make it happen
66 struct memcntl_mha m = {};
67 m.mha_cmd = MHA_MAPSIZE_VA;
68 m.mha_pagesize = large_page_default_size;
69 int ret = memcntl(ptr, n_bytes_rounded, MC_HAT_ADVISE, (caddr_t)&m, 0, 0);
70 if (unlikely(ret == -1)) {
71 ib::log_warn(ER_IB_MSG_856)
72 << "large_page_aligned_alloc memcntl(ptr, " << n_bytes_rounded
73 << " bytes) failed;"
74 " errno "
75 << errno;
76 return nullptr;
77 }
78 return (ptr != (void *)-1) ? ptr : nullptr;
79}
80
81/** Releases memory backed by large (huge) pages.
82
83 @param[in] ptr Pointer to large (huge) page aligned storage.
84 @param[in] n_bytes Size of the storage.
85 @return Returns true if releasing the large (huge) page succeeded.
86 */
87inline bool large_page_aligned_free(void *ptr, size_t n_bytes) {
88 if (unlikely(!ptr)) return false;
89 // Freeing huge-pages require size to be the multiple of huge-page size
90 size_t n_bytes_rounded = pow2_round(n_bytes + (large_page_default_size - 1),
92 auto ret = munmap(ptr, n_bytes_rounded);
93 if (unlikely(ret != 0)) {
94 ib::log_error(ER_IB_MSG_858)
95 << "large_page_aligned_free munmap(" << ptr << ", " << n_bytes_rounded
96 << ") failed;"
97 " errno "
98 << errno;
99 }
100 return ret == 0;
101}
102
103/** Queries all possible page-sizes. Solaris allows picking one at _runtime_
104 which is contrary to how Linux, Windows and OSX does.
105
106 @return std::vector of supported page sizes (in bytes).
107*/
108inline std::vector<size_t> large_page_all_supported_sizes() {
109 int nr_of_pages = getpagesizes(NULL, 0);
110 std::vector<size_t> supported_page_sizes(nr_of_pages);
111 if (nr_of_pages > 0) {
112 getpagesizes(supported_page_sizes.data(), nr_of_pages);
113 }
114 return supported_page_sizes;
115}
116
117/** Queries the page-size that is next to the minimum supported page-size
118 Lowest supported page size is usually 4K on x86_64 whereas it's 8K on SPARC.
119
120 @return Minimum supported large (huge) page size in bytes.
121*/
122inline size_t large_page_size() { return large_page_all_supported_sizes()[1]; }
123
124} // namespace detail
125} // namespace ut
126
127#endif
Small helper functions.
const size_t large_page_default_size
System-default huge (large) page setting.
Definition: ut0new.cc:40
constexpr bool unlikely(bool expr)
Definition: my_compiler.h:58
Definition: ut0tuple.h:57
static auto log_warn()
Definition: ut0log.h:452
static auto log_error()
Definition: ut0log.h:453
constexpr size_t pow2_round(size_t n, size_t m)
Calculates the biggest multiple of m that is not bigger than n when m is a power of two.
Definition: helper.h:57
void * large_page_aligned_alloc(size_t n_bytes)
Allocates memory backed by large (huge) pages.
Definition: large_page_alloc-linux.h:52
std::vector< size_t > large_page_all_supported_sizes()
Queries all possible page-sizes.
Definition: large_page_alloc-solaris.h:108
bool large_page_aligned_free(void *ptr, size_t n_bytes)
Releases memory backed by large (huge) pages.
Definition: large_page_alloc-linux.h:75
size_t large_page_size()
Queries the current size of large (huge) pages on running system.
Definition: large_page_alloc-linux.h:95
This file contains a set of libraries providing overloads for regular dynamic allocation routines whi...
Definition: aligned_alloc.h:48
#define NULL
Definition: types.h:55
__caddr_t caddr_t
Definition: types.h:82
Base of InnoDB utilities.