FD.io VPP  v16.09
Vector Packet Processing
mem.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
17 
18  Permission is hereby granted, free of charge, to any person obtaining
19  a copy of this software and associated documentation files (the
20  "Software"), to deal in the Software without restriction, including
21  without limitation the rights to use, copy, modify, merge, publish,
22  distribute, sublicense, and/or sell copies of the Software, and to
23  permit persons to whom the Software is furnished to do so, subject to
24  the following conditions:
25 
26  The above copyright notice and this permission notice shall be
27  included in all copies or substantial portions of the Software.
28 
29  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 */
37 
38 #ifndef _included_clib_mem_h
39 #define _included_clib_mem_h
40 
41 #include <stdarg.h>
42 
43 #include <vppinfra/clib.h> /* uword, etc */
45 #include <vppinfra/os.h>
46 #include <vppinfra/string.h> /* memcpy, memset */
47 #include <vppinfra/valgrind.h>
48 
49 #define CLIB_MAX_MHEAPS 256
50 
51 /* Per CPU heaps. */
53 
54 always_inline void *
56 {
57  int cpu = os_get_cpu_number ();
58  return clib_per_cpu_mheaps[cpu];
59 }
60 
61 always_inline void *
63 {
64  int cpu = os_get_cpu_number ();
65  void *old = clib_per_cpu_mheaps[cpu];
66  clib_per_cpu_mheaps[cpu] = new_heap;
67  return old;
68 }
69 
70 /* Memory allocator which returns null when it fails. */
71 always_inline void *
73 {
74  void *heap, *p;
75  uword offset, cpu;
76 
77  if (align_offset > align)
78  {
79  if (align > 0)
80  align_offset %= align;
81  else
82  align_offset = align;
83  }
84 
85  cpu = os_get_cpu_number ();
86  heap = clib_per_cpu_mheaps[cpu];
87  heap = mheap_get_aligned (heap, size, align, align_offset, &offset);
88  clib_per_cpu_mheaps[cpu] = heap;
89 
90  if (offset != ~0)
91  {
92  p = heap + offset;
93 #if CLIB_DEBUG > 0
94  VALGRIND_MALLOCLIKE_BLOCK (p, mheap_data_bytes (heap, offset), 0, 0);
95 #endif
96  return p;
97  }
98  else
99  {
100  os_out_of_memory ();
101  return 0;
102  }
103 }
104 
105 /* Memory allocator which returns null when it fails. */
106 always_inline void *
108 {
109  return clib_mem_alloc_aligned_at_offset (size, /* align */ 1,
110  /* align_offset */ 0);
111 }
112 
113 always_inline void *
115 {
116  return clib_mem_alloc_aligned_at_offset (size, align, /* align_offset */ 0);
117 }
118 
119 /* Memory allocator which panics when it fails.
120  Use macro so that clib_panic macro can expand __FUNCTION__ and __LINE__. */
121 #define clib_mem_alloc_aligned_no_fail(size,align) \
122 ({ \
123  uword _clib_mem_alloc_size = (size); \
124  void * _clib_mem_alloc_p; \
125  _clib_mem_alloc_p = clib_mem_alloc_aligned (_clib_mem_alloc_size, (align)); \
126  if (! _clib_mem_alloc_p) \
127  clib_panic ("failed to allocate %d bytes", _clib_mem_alloc_size); \
128  _clib_mem_alloc_p; \
129 })
130 
131 #define clib_mem_alloc_no_fail(size) clib_mem_alloc_aligned_no_fail(size,1)
132 
133 /* Alias to stack allocator for naming consistency. */
134 #define clib_mem_alloc_stack(bytes) __builtin_alloca(bytes)
135 
138 {
139  void *heap = clib_mem_get_per_cpu_heap ();
140  uword offset = (uword) p - (uword) heap;
141  mheap_elt_t *e, *n;
142 
143  if (offset >= vec_len (heap))
144  return 0;
145 
146  e = mheap_elt_at_uoffset (heap, offset);
147  n = mheap_next_elt (e);
148 
149  /* Check that heap forward and reverse pointers agree. */
150  return e->n_user_data == n->prev_n_user_data;
151 }
152 
153 always_inline void
154 clib_mem_free (void *p)
155 {
156  u8 *heap = clib_mem_get_per_cpu_heap ();
157 
158  /* Make sure object is in the correct heap. */
160 
161  mheap_put (heap, (u8 *) p - heap);
162 
163 #if CLIB_DEBUG > 0
165 #endif
166 }
167 
168 always_inline void *
169 clib_mem_realloc (void *p, uword new_size, uword old_size)
170 {
171  /* By default use alloc, copy and free to emulate realloc. */
172  void *q = clib_mem_alloc (new_size);
173  if (q)
174  {
175  uword copy_size;
176  if (old_size < new_size)
177  copy_size = old_size;
178  else
179  copy_size = new_size;
180  clib_memcpy (q, p, copy_size);
181  clib_mem_free (p);
182  }
183  return q;
184 }
185 
187 clib_mem_size (void *p)
188 {
191  return mheap_elt_data_bytes (e);
192 }
193 
194 always_inline void *
196 {
197  return clib_mem_get_per_cpu_heap ();
198 }
199 
200 always_inline void *
201 clib_mem_set_heap (void *heap)
202 {
203  return clib_mem_set_per_cpu_heap (heap);
204 }
205 
206 void *clib_mem_init (void *heap, uword size);
207 
208 void clib_mem_exit (void);
209 
211 
212 void clib_mem_validate (void);
213 
214 void clib_mem_trace (int enable);
215 
216 typedef struct
217 {
218  /* Total number of objects allocated. */
220 
221  /* Total allocated bytes. Bytes used and free.
222  used + free = total */
223  uword bytes_total, bytes_used, bytes_free;
224 
225  /* Number of bytes used by mheap data structure overhead
226  (e.g. free lists, mheap header). */
228 
229  /* Amount of free space returned to operating system. */
231 
232  /* For malloc which puts small objects in sbrk region and
233  large objects in mmap'ed regions. */
236 
237  /* Max. number of bytes in this heap. */
240 
242 
243 u8 *format_clib_mem_usage (u8 * s, va_list * args);
244 
245 /* Include appropriate VM functions depending on whether
246  we are compiling for linux kernel, for Unix or standalone. */
247 #ifdef CLIB_LINUX_KERNEL
249 #endif
250 
251 #ifdef CLIB_UNIX
252 #include <vppinfra/vm_unix.h>
253 #endif
254 
255 #ifdef CLIB_STANDALONE
256 #include <vppinfra/vm_standalone.h>
257 #endif
258 
259 #include <vppinfra/error.h> /* clib_panic */
260 
261 #endif /* _included_clib_mem_h */
262 
263 /*
264  * fd.io coding-style-patch-verification: ON
265  *
266  * Local Variables:
267  * eval: (c-set-style "gnu")
268  * End:
269  */
uword bytes_overhead
Definition: mem.h:227
void clib_mem_validate(void)
Definition: mem_mheap.c:142
void * clib_per_cpu_mheaps[CLIB_MAX_MHEAPS]
Definition: mem_mheap.c:46
uword bytes_free_reclaimed
Definition: mem.h:230
static void * clib_mem_realloc(void *p, uword new_size, uword old_size)
Definition: mem.h:169
void os_out_of_memory(void)
Definition: unix-misc.c:217
static void usage(void)
Definition: health_check.c:14
uword bytes_used_sbrk
Definition: mem.h:234
#define CLIB_MAX_MHEAPS
Definition: mem.h:49
uword bytes_used
Definition: mem.h:223
uword object_count
Definition: mem.h:219
#define always_inline
Definition: clib.h:84
static uword mheap_elt_data_bytes(mheap_elt_t *e)
uword os_get_cpu_number(void)
Definition: unix-misc.c:224
static void * clib_mem_get_per_cpu_heap(void)
Definition: mem.h:55
u8 * format_clib_mem_usage(u8 *s, va_list *args)
Definition: mem_mheap.c:126
uword bytes_used_mmap
Definition: mem.h:235
static void * clib_mem_alloc_aligned_at_offset(uword size, uword align, uword align_offset)
Definition: mem.h:72
void * clib_mem_init(void *heap, uword size)
Definition: mem_mheap.c:60
#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)
Definition: valgrind.h:3894
void * mheap_get_aligned(void *v, uword n_user_data_bytes, uword align, uword align_offset, uword *offset_return)
Definition: mheap.c:649
uword bytes_max
Definition: mem.h:238
static void * clib_mem_set_heap(void *heap)
Definition: mem.h:201
#define clib_memcpy(a, b, c)
Definition: string.h:63
static uword clib_mem_size(void *p)
Definition: mem.h:187
static void * clib_mem_get_heap(void)
Definition: mem.h:195
#define ASSERT(truth)
u32 size
Definition: vhost-user.h:77
static void clib_mem_free(void *p)
Definition: mem.h:154
static uword clib_mem_is_heap_object(void *p)
Definition: mem.h:137
static void * clib_mem_alloc(uword size)
Definition: mem.h:107
u64 uword
Definition: types.h:112
static void * clib_mem_set_per_cpu_heap(u8 *new_heap)
Definition: mem.h:62
static mheap_elt_t * mheap_elt_at_uoffset(void *v, uword uo)
template key/value backing page structure
Definition: bihash_doc.h:44
void mheap_put(void *v, uword uoffset)
Definition: mheap.c:761
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
void clib_mem_usage(clib_mem_usage_t *usage)
Definition: mem_mheap.c:133
static mheap_elt_t * mheap_next_elt(mheap_elt_t *e)
struct clib_bihash_value offset
template key/value backing page structure
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:114
#define VALGRIND_FREELIKE_BLOCK(addr, rzB)
Definition: valgrind.h:3905
static uword mheap_data_bytes(void *v, uword uo)
void clib_mem_trace(int enable)
Definition: mem_mheap.c:154
uword clib_mem_get_page_size(void)
Definition: mem_mheap.c:110
void clib_mem_exit(void)
Definition: mem_mheap.c:49
static mheap_elt_t * mheap_user_pointer_to_elt(void *v)