Motr  M0
memory.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2020 Seagate Technology LLC and/or its Affiliates
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  *
19  */
20 
21 
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <sys/mman.h>
27 
28 #include "lib/arith.h" /* min_type, m0_is_po2 */
29 #include "lib/assert.h"
30 #include "lib/memory.h"
31 
32 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_MEMORY
33 #include "lib/trace.h"
34 
51 #ifdef HAVE_MALLINFO
52 
53 #include <malloc.h>
54 
55 M0_INTERNAL size_t m0_arch_alloc_size(void *data)
56 {
57  return malloc_usable_size(data);
58 }
59 
60 /* HAVE_MALLINFO */
61 #elif HAVE_MALLOC_SIZE
62 
63 #include <malloc/malloc.h>
64 
65 M0_INTERNAL size_t m0_arch_alloc_size(void *data)
66 {
67  return malloc_size(data);
68 }
69 
70 /* HAVE_MALLOC_SIZE */
71 #else
72 
73 M0_INTERNAL size_t m0_arch_alloc_size(void *data)
74 {
75  return 0;
76 }
77 
78 #endif
79 
80 void *m0_arch_alloc(size_t size)
81 {
82  return malloc(size);
83 }
84 
85 void m0_arch_free(void *data)
86 {
87  free(data);
88 }
89 
90 M0_INTERNAL void m0_arch_allocated_zero(void *data, size_t size)
91 {
92  memset(data, 0, size);
93 }
94 
95 M0_INTERNAL void *m0_arch_alloc_nz(size_t size)
96 {
97  return m0_arch_alloc(size);
98 }
99 
100 M0_INTERNAL void m0_arch_free_aligned(void *data, size_t size, unsigned shift)
101 {
102  free(data);
103 }
104 
105 M0_INTERNAL void *m0_arch_alloc_aligned(size_t alignment, size_t size)
106 {
107  int rc;
108  void *result;
109 
110  rc = posix_memalign(&result, alignment, size);
111  if (rc != 0)
112  result = NULL;
113  return result;
114 }
115 
116 M0_INTERNAL void *m0_arch_alloc_wired(size_t size, unsigned shift)
117 {
118  void *res;
119  int rc;
120 
121  res = m0_alloc_aligned(size, shift);
122  if (res == NULL)
123  goto out;
124 
125  rc = mlock(res, 1);
126  if (rc == -1) {
127  M0_LOG(M0_ERROR, "mlock() failed: rc=%d", errno);
128  m0_free_aligned(res, size, shift);
129  res = NULL;
130  goto out;
131  }
132 
133  rc = madvise((void*)((unsigned long)res & ~(m0_pagesize_get() - 1)), 1,
134  MADV_DONTFORK);
135  if (rc == -1) {
136  M0_LOG(M0_ERROR, "madvise() failed: rc=%d", errno);
137  m0_free_wired(res, size, shift);
138  res = NULL;
139  }
140 out:
141  return res;
142 }
143 
144 M0_INTERNAL void m0_arch_free_wired(void *data, size_t size, unsigned shift)
145 {
146  int rc;
147 
148  rc = madvise((void*)((unsigned long)data & ~(m0_pagesize_get() - 1)), 1,
149  MADV_DOFORK);
150  if (rc == -1)
151  M0_LOG(M0_WARN, "madvise() failed: rc=%d", errno);
152  munlock(data, 1);
153  m0_free_aligned(data, size, shift);
154 }
155 
156 M0_INTERNAL void m0_arch_memory_pagein(void *addr, size_t size)
157 {
158  char *current_byte = addr;
159  char *end_byte = (char *)addr + size;
160  int page_size = m0_pagesize_get();
161 
162  if (addr == NULL || size == 0)
163  return;
164  /*
165  * It reads and writes the first byte of the allocated block
166  * and then the first byte of each page in the allocated block.
167  */
168  M0_CASSERT(sizeof(current_byte) == sizeof(uint64_t));
169  *current_byte = 0xCC;
170  for (current_byte = (char *)m0_round_up((uint64_t)current_byte + 1,
171  page_size);
172  current_byte < end_byte; current_byte += page_size)
173  *current_byte = 0xCC;
174 }
175 
183 M0_INTERNAL int m0_arch_dont_dump(void *p, size_t size)
184 {
185  int rc;
186  rc = madvise(p, size, MADV_DONTDUMP);
187  if (rc != 0) {
188  rc = -errno;
189  M0_LOG(M0_ERROR, "madvised failed: %d. Please "
190  "sysctl -w vm.max_map_count=a_larger_number",
191  rc);
192  }
193 
194  return rc;
195 }
196 
197 M0_INTERNAL int m0_arch_memory_init(void)
198 {
199  void *nothing;
200 
201  /*
202  * m0_bitmap_init() relies on non-NULL-ness of m0_alloc(0) result.
203  */
204  nothing = m0_alloc(0);
205  M0_ASSERT(nothing != NULL);
206  m0_free(nothing);
207  return 0;
208 }
209 
210 M0_INTERNAL void m0_arch_memory_fini(void)
211 {
212 }
213 
214 M0_INTERNAL int m0_arch_pagesize_get()
215 {
216  return getpagesize();
217 }
218 
219 M0_INTERNAL int m0_arch_pageshift_get()
220 {
221  return ffs(getpagesize());
222 }
223 
224 #undef M0_TRACE_SUBSYSTEM
225 
228 /*
229  * Local variables:
230  * c-indentation-style: "K&R"
231  * c-basic-offset: 8
232  * tab-width: 8
233  * fill-column: 80
234  * scroll-step: 1
235  * End:
236  */
static struct m0_addb2_philter p
Definition: consumer.c:40
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_arch_free_wired(void *data, size_t size, unsigned shift)
Definition: memory.c:109
#define M0_LOG(level,...)
Definition: trace.h:167
M0_INTERNAL void m0_arch_memory_pagein(void *addr, size_t size)
Definition: memory.c:78
#define M0_CASSERT(cond)
M0_INTERNAL size_t m0_arch_alloc_size(void *data)
Definition: memory.c:83
struct m0_bufvec data
Definition: di.c:40
M0_INTERNAL void m0_free_aligned(void *data, size_t size, unsigned shift)
Definition: memory.c:192
M0_INTERNAL int m0_arch_pagesize_get(void)
Definition: memory.c:133
M0_INTERNAL void m0_arch_free_aligned(void *addr, size_t size, unsigned shift)
Definition: memory.c:98
M0_INTERNAL uint64_t m0_round_up(uint64_t val, uint64_t size)
Definition: misc.c:181
M0_INTERNAL void m0_free_wired(void *data, size_t size, unsigned shift)
Definition: memory.c:207
M0_INTERNAL int m0_pagesize_get(void)
Definition: memory.c:233
static char * addr
Definition: node_k.c:37
M0_INTERNAL void * m0_arch_alloc(size_t size)
Definition: memory.c:37
#define M0_ASSERT(cond)
M0_INTERNAL int m0_arch_memory_init(void)
Definition: memory.c:124
void * m0_alloc(size_t size)
Definition: memory.c:126
M0_INTERNAL void m0_arch_free(void *data)
Definition: memory.c:62
M0_INTERNAL void * m0_arch_alloc_nz(size_t size)
Definition: memory.c:72
Definition: xcode.h:73
M0_INTERNAL void * m0_arch_alloc_aligned(size_t alignment, size_t size)
Definition: memory.c:88
M0_INTERNAL void m0_arch_allocated_zero(void *data, size_t size)
Definition: memory.c:67
m0_bcount_t size
Definition: di.c:39
M0_INTERNAL int m0_arch_pageshift_get(void)
Definition: memory.c:138
M0_INTERNAL void * m0_arch_alloc_wired(size_t size, unsigned shift)
Definition: memory.c:104
#define out(...)
Definition: gen.c:41
M0_INTERNAL void * m0_alloc_aligned(size_t size, unsigned shift)
Definition: memory.c:168
void m0_free(void *data)
Definition: memory.c:146
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL void m0_arch_memory_fini(void)
Definition: memory.c:129
Definition: trace.h:478
M0_INTERNAL int m0_arch_dont_dump(void *p, size_t size)
Definition: memory.c:119