FD.io VPP  v21.06
Vector Packet Processing
mem_dlmalloc.c
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 #include <vppinfra/format.h>
17 #include <vppinfra/dlmalloc.h>
18 #include <vppinfra/os.h>
19 #include <vppinfra/lock.h>
20 #include <vppinfra/hash.h>
21 #include <vppinfra/elf_clib.h>
22 #include <vppinfra/sanitizer.h>
23 
24 typedef struct
25 {
26  /* Address of callers: outer first, inner last. */
27  uword callers[12];
28 
29  /* Count of allocations with this traceback. */
31 
32  /* Count of bytes allocated with this traceback. */
34 
35  /* Offset of this item */
38 
39 typedef struct
40 {
43 
45 
46  /* Indices of free traces. */
48 
49  /* Hash table mapping callers to trace index. */
51 
52  /* Hash table mapping mheap offset to trace index. */
54 
55  /* So we can easily shut off current segment trace, if any */
57 
59 
61 
62 void
64 {
66  mheap_trace_t *t;
67  uword i, n_callers, trace_index, *p;
69  uword save_enabled;
70 
71  if (tm->enabled == 0 || (clib_mem_get_heap () != tm->current_traced_mheap))
72  return;
73 
74  /* Spurious Coverity warnings be gone. */
75  clib_memset (&trace, 0, sizeof (trace));
76 
77  clib_spinlock_lock (&tm->lock);
78 
79  /* Turn off tracing to avoid embarrassment... */
80  save_enabled = tm->enabled;
81  tm->enabled = 0;
82 
83  /* Skip our frame and mspace_get_aligned's frame */
84  n_callers = clib_backtrace (trace.callers, ARRAY_LEN (trace.callers), 2);
85  if (n_callers == 0)
86  goto out;
87 
88  if (!tm->trace_by_callers)
89  tm->trace_by_callers =
90  hash_create_shmem (0, sizeof (trace.callers), sizeof (uword));
91 
92  p = hash_get_mem (tm->trace_by_callers, &trace.callers);
93  if (p)
94  {
95  trace_index = p[0];
96  t = tm->traces + trace_index;
97  }
98  else
99  {
100  i = vec_len (tm->trace_free_list);
101  if (i > 0)
102  {
103  trace_index = tm->trace_free_list[i - 1];
104  _vec_len (tm->trace_free_list) = i - 1;
105  }
106  else
107  {
108  mheap_trace_t *old_start = tm->traces;
109  mheap_trace_t *old_end = vec_end (tm->traces);
110 
111  vec_add2 (tm->traces, t, 1);
112 
113  if (tm->traces != old_start)
114  {
115  hash_pair_t *p;
116  mheap_trace_t *q;
117  /* *INDENT-OFF* */
119  ({
120  q = uword_to_pointer (p->key, mheap_trace_t *);
121  ASSERT (q >= old_start && q < old_end);
122  p->key = pointer_to_uword (tm->traces + (q - old_start));
123  }));
124  /* *INDENT-ON* */
125  }
126  trace_index = t - tm->traces;
127  }
128 
129  t = tm->traces + trace_index;
130  t[0] = trace;
131  t->n_allocations = 0;
132  t->n_bytes = 0;
133  hash_set_mem (tm->trace_by_callers, t->callers, trace_index);
134  }
135 
136  t->n_allocations += 1;
137  t->n_bytes += size;
138  t->offset = offset; /* keep a sample to autopsy */
139  hash_set (tm->trace_index_by_offset, offset, t - tm->traces);
140 
141 out:
142  tm->enabled = save_enabled;
143  clib_spinlock_unlock (&tm->lock);
144 }
145 
146 void
148 {
149  mheap_trace_t *t;
150  uword trace_index, *p;
152  uword save_enabled;
153 
154  if (tm->enabled == 0)
155  return;
156 
157  clib_spinlock_lock (&tm->lock);
158 
159  /* Turn off tracing for a moment */
160  save_enabled = tm->enabled;
161  tm->enabled = 0;
162 
163  p = hash_get (tm->trace_index_by_offset, offset);
164  if (!p)
165  {
166  tm->enabled = save_enabled;
167  clib_spinlock_unlock (&tm->lock);
168  return;
169  }
170 
171  trace_index = p[0];
172  hash_unset (tm->trace_index_by_offset, offset);
173  ASSERT (trace_index < vec_len (tm->traces));
174 
175  t = tm->traces + trace_index;
176  ASSERT (t->n_allocations > 0);
177  ASSERT (t->n_bytes >= size);
178  t->n_allocations -= 1;
179  t->n_bytes -= size;
180  if (t->n_allocations == 0)
181  {
183  vec_add1 (tm->trace_free_list, trace_index);
184  clib_memset (t, 0, sizeof (t[0]));
185  }
186  tm->enabled = save_enabled;
187  clib_spinlock_unlock (&tm->lock);
188 }
189 
190 always_inline void
192 {
193  vec_free (tm->traces);
197 }
198 
199 static clib_mem_heap_t *
201  clib_mem_page_sz_t log2_page_sz, int is_locked,
202  char *name)
203 {
205  u8 flags = 0;
206  int sz = sizeof (clib_mem_heap_t);
207 
208  if (base == 0)
209  {
210  log2_page_sz = clib_mem_log2_page_size_validate (log2_page_sz);
211  size = round_pow2 (size, clib_mem_page_bytes (log2_page_sz));
212  base = clib_mem_vm_map_internal (0, log2_page_sz, size, -1, 0,
213  "main heap");
214 
215  if (base == CLIB_MEM_VM_MAP_FAILED)
216  return 0;
217 
218  flags = CLIB_MEM_HEAP_F_UNMAP_ON_DESTROY;
219  }
220  else
221  log2_page_sz = CLIB_MEM_PAGE_SZ_UNKNOWN;
222 
223  if (is_locked)
224  flags |= CLIB_MEM_HEAP_F_LOCKED;
225 
226  h = base;
227  h->base = base;
228  h->size = size;
229  h->log2_page_sz = log2_page_sz;
230  h->flags = flags;
231  sz = strlen (name);
232  strcpy (h->name, name);
233  sz = round_pow2 (sz + sizeof (clib_mem_heap_t), 16);
234  h->mspace = create_mspace_with_base (base + sz, size - sz, is_locked);
235 
237 
239  mspace_footprint (h->mspace));
240 
241  return h;
242 }
243 
244 /* Initialize CLIB heap based on memory/size given by user.
245  Set memory to 0 and CLIB will try to allocate its own heap. */
246 static void *
248  clib_mem_page_sz_t log2_page_sz)
249 {
251 
253 
254  h = clib_mem_create_heap_internal (base, size, log2_page_sz,
255  1 /*is_locked */ , "main heap");
256 
257  clib_mem_set_heap (h);
258 
259  if (mheap_trace_main.lock == 0)
260  clib_spinlock_init (&mheap_trace_main.lock);
261 
262  return h;
263 }
264 
265 __clib_export void *
267 {
268  return clib_mem_init_internal (memory, memory_size,
270 }
271 
272 __clib_export void *
274  clib_mem_page_sz_t log2_page_sz)
275 {
276  return clib_mem_init_internal (0, memory_size, log2_page_sz);
277 }
278 
279 __clib_export void *
281 {
282  return clib_mem_init_internal (memory, memory_size,
284 }
285 
286 __clib_export void
288 {
291  void *base = mspace_least_addr (heap->mspace);
292 
293  if (tm->enabled && heap->mspace == tm->current_traced_mheap)
294  tm->enabled = 0;
295 
296  destroy_mspace (heap->mspace);
297  clib_mem_vm_unmap (base);
298 }
299 
300 __clib_export u8 *
301 format_clib_mem_usage (u8 *s, va_list *va)
302 {
303  int verbose = va_arg (*va, int);
304  return format (s, "$$$$ heap at %llx verbose %d", clib_mem_get_heap (),
305  verbose);
306 }
307 
308 /*
309  * Magic decoder ring for mallinfo stats (ala dlmalloc):
310  *
311  * size_t arena; / * Non-mmapped space allocated (bytes) * /
312  * size_t ordblks; / * Number of free chunks * /
313  * size_t smblks; / * Number of free fastbin blocks * /
314  * size_t hblks; / * Number of mmapped regions * /
315  * size_t hblkhd; / * Space allocated in mmapped regions (bytes) * /
316  * size_t usmblks; / * Maximum total allocated space (bytes) * /
317  * size_t fsmblks; / * Space in freed fastbin blocks (bytes) * /
318  * size_t uordblks; / * Total allocated space (bytes) * /
319  * size_t fordblks; / * Total free space (bytes) * /
320  * size_t keepcost; / * Top-most, releasable space (bytes) * /
321  *
322  */
323 
324 u8 *
325 format_msize (u8 * s, va_list * va)
326 {
327  uword a = va_arg (*va, uword);
328 
329  if (a >= 1ULL << 30)
330  s = format (s, "%.2fG", (((f64) a) / ((f64) (1ULL << 30))));
331  else if (a >= 1ULL << 20)
332  s = format (s, "%.2fM", (((f64) a) / ((f64) (1ULL << 20))));
333  else if (a >= 1ULL << 10)
334  s = format (s, "%.2fK", (((f64) a) / ((f64) (1ULL << 10))));
335  else
336  s = format (s, "%lld", a);
337  return s;
338 }
339 
340 static int
341 mheap_trace_sort (const void *_t1, const void *_t2)
342 {
343  const mheap_trace_t *t1 = _t1;
344  const mheap_trace_t *t2 = _t2;
345  word cmp;
346 
347  cmp = (word) t2->n_bytes - (word) t1->n_bytes;
348  if (!cmp)
349  cmp = (word) t2->n_allocations - (word) t1->n_allocations;
350  return cmp;
351 }
352 
353 u8 *
354 format_mheap_trace (u8 * s, va_list * va)
355 {
356  mheap_trace_main_t *tm = va_arg (*va, mheap_trace_main_t *);
357  int verbose = va_arg (*va, int);
358  int have_traces = 0;
359  int i;
360 
361  clib_spinlock_lock (&tm->lock);
362  if (vec_len (tm->traces) > 0 &&
364  {
365  have_traces = 1;
366 
367  /* Make a copy of traces since we'll be sorting them. */
368  mheap_trace_t *t, *traces_copy;
369  u32 indent, total_objects_traced;
370 
371  traces_copy = vec_dup (tm->traces);
372 
373  qsort (traces_copy, vec_len (traces_copy), sizeof (traces_copy[0]),
375 
376  total_objects_traced = 0;
377  s = format (s, "\n");
378  vec_foreach (t, traces_copy)
379  {
380  /* Skip over free elements. */
381  if (t->n_allocations == 0)
382  continue;
383 
384  total_objects_traced += t->n_allocations;
385 
386  /* When not verbose only report allocations of more than 1k. */
387  if (!verbose && t->n_bytes < 1024)
388  continue;
389 
390  if (t == traces_copy)
391  s = format (s, "%=9s%=9s %=10s Traceback\n", "Bytes", "Count",
392  "Sample");
393  s = format (s, "%9d%9d %p", t->n_bytes, t->n_allocations, t->offset);
394  indent = format_get_indent (s);
395  for (i = 0; i < ARRAY_LEN (t->callers) && t->callers[i]; i++)
396  {
397  if (i > 0)
398  s = format (s, "%U", format_white_space, indent);
399 #if defined(CLIB_UNIX) && !defined(__APPLE__)
400  /* $$$$ does this actually work? */
401  s =
403  t->callers[i]);
404 #else
405  s = format (s, " %p\n", t->callers[i]);
406 #endif
407  }
408  }
409 
410  s = format (s, "%d total traced objects\n", total_objects_traced);
411 
412  vec_free (traces_copy);
413  }
414  clib_spinlock_unlock (&tm->lock);
415  if (have_traces == 0)
416  s = format (s, "no traced allocations\n");
417 
418  return s;
419 }
420 
421 __clib_export u8 *
422 format_clib_mem_heap (u8 * s, va_list * va)
423 {
424  clib_mem_heap_t *heap = va_arg (*va, clib_mem_heap_t *);
425  int verbose = va_arg (*va, int);
426  struct dlmallinfo mi;
428  u32 indent = format_get_indent (s) + 2;
429 
430  if (heap == 0)
431  heap = clib_mem_get_heap ();
432 
433  mi = mspace_mallinfo (heap->mspace);
434 
435  s = format (s, "base %p, size %U",
436  heap->base, format_memory_size, heap->size);
437 
438 #define _(i,v,str) \
439  if (heap->flags & CLIB_MEM_HEAP_F_##v) s = format (s, ", %s", str);
441 #undef _
442 
443  s = format (s, ", name '%s'", heap->name);
444 
446  {
449  heap->size >> heap->log2_page_sz, &stats);
450  s = format (s, "\n%U%U", format_white_space, indent,
452  }
453 
454  s = format (s, "\n%Utotal: %U, used: %U, free: %U, trimmable: %U",
455  format_white_space, indent,
456  format_msize, mi.arena,
459  if (verbose > 0)
460  {
461  s = format (s, "\n%Ufree chunks %llu free fastbin blks %llu",
462  format_white_space, indent + 2, mi.ordblks, mi.smblks);
463  s = format (s, "\n%Umax total allocated %U",
464  format_white_space, indent + 2, format_msize, mi.usmblks);
465  }
466 
467  if (mspace_is_traced (heap->mspace))
468  s = format (s, "\n%U", format_mheap_trace, tm, verbose);
469  return s;
470 }
471 
472 __clib_export void
474 {
475  struct dlmallinfo mi = mspace_mallinfo (heap->mspace);
476 
477  usage->bytes_total = mi.arena; /* non-mmapped space allocated from system */
478  usage->bytes_used = mi.uordblks; /* total allocated space */
479  usage->bytes_free = mi.fordblks; /* total free space */
480  usage->bytes_used_mmap = mi.hblkhd; /* space in mmapped regions */
481  usage->bytes_max = mi.usmblks; /* maximum total allocated space */
482  usage->bytes_free_reclaimed = mi.ordblks; /* number of free chunks */
483  usage->bytes_overhead = mi.keepcost; /* releasable (via malloc_trim) space */
484 
485  /* Not supported */
486  usage->bytes_used_sbrk = 0;
487  usage->object_count = 0;
488 }
489 
490 /* Call serial number for debugger breakpoints. */
492 
493 __clib_export void
495 {
496  (void) mspace_enable_disable_trace (h->mspace, enable);
497 
498  if (enable == 0)
499  mheap_trace_main_free (&mheap_trace_main);
500 }
501 
502 __clib_export void
503 clib_mem_trace (int enable)
504 {
506  void *current_heap = clib_mem_get_heap ();
507 
508  tm->enabled = enable;
509  mheap_trace (current_heap, enable);
510 
511  if (enable)
512  tm->current_traced_mheap = current_heap;
513  else
514  tm->current_traced_mheap = 0;
515 }
516 
517 int
519 {
521  return mspace_is_traced (h->mspace);
522 }
523 
524 __clib_export uword
526 {
527  uword rv;
529 
530  rv = tm->enabled;
531  tm->enabled = enable;
532  return rv;
533 }
534 
535 __clib_export clib_mem_heap_t *
536 clib_mem_create_heap (void *base, uword size, int is_locked, char *fmt, ...)
537 {
540  char *name;
541  u8 *s = 0;
542 
543  if (fmt == 0)
544  {
545  name = "";
546  }
547  else if (strchr (fmt, '%'))
548  {
549  va_list va;
550  va_start (va, fmt);
551  s = va_format (0, fmt, &va);
552  vec_add1 (s, 0);
553  va_end (va);
554  name = (char *) s;
555  }
556  else
557  name = fmt;
558 
559  h = clib_mem_create_heap_internal (base, size, log2_page_sz, is_locked,
560  name);
561  vec_free (s);
562  return h;
563 }
564 
565 __clib_export void
567 {
569 
570  if (tm->enabled && h->mspace == tm->current_traced_mheap)
571  tm->enabled = 0;
572 
573  destroy_mspace (h->mspace);
574  if (h->flags & CLIB_MEM_HEAP_F_UNMAP_ON_DESTROY)
575  clib_mem_vm_unmap (h->base);
576 }
577 
578 __clib_export uword
580 {
581  struct dlmallinfo dlminfo = mspace_mallinfo (h->mspace);
582  return dlminfo.fordblks;
583 }
584 
585 __clib_export void *
587 {
588  return h->base;
589 }
590 
591 __clib_export uword
593 {
594  return heap->size;
595 }
596 
597 /*
598  * fd.io coding-style-patch-verification: ON
599  *
600  * Local Variables:
601  * eval: (c-set-style "gnu")
602  * End:
603  */
__clib_export u8 * va_format(u8 *s, const char *fmt, va_list *va)
Definition: format.c:391
uword bytes_overhead
Definition: mem.h:397
uword bytes_total
Definition: mem.h:393
__clib_export void clib_mem_destroy(void)
Definition: mem_dlmalloc.c:287
static vlib_cli_command_t trace
(constructor) VLIB_CLI_COMMAND (trace)
Definition: vlib_api_cli.c:899
#define CLIB_MEM_VM_MAP_FAILED
Definition: mem.h:54
#define hash_set(h, key, value)
Definition: hash.h:255
uword bytes_free
Definition: mem.h:393
vhost_user_memory_t memory
Definition: vhost_user.h:131
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
Definition: lock.h:121
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
Definition: lock.h:82
__clib_export int clib_mem_vm_unmap(void *base)
Definition: mem.c:510
#define hash_unset(h, key)
Definition: hash.h:261
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
a
Definition: bitmap.h:544
__clib_export void clib_mem_destroy_heap(clib_mem_heap_t *h)
Definition: mem_dlmalloc.c:566
uword callers[12]
Definition: mem_dlmalloc.c:27
uword bytes_free_reclaimed
Definition: mem.h:400
void * current_traced_mheap
Definition: mem_dlmalloc.c:56
static void * clib_mem_init_internal(void *base, uword size, clib_mem_page_sz_t log2_page_sz)
Definition: mem_dlmalloc.c:247
uword size
Definition: mem.h:116
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static clib_mem_heap_t * clib_mem_set_heap(clib_mem_heap_t *heap)
Definition: mem.h:365
u8 * format_msize(u8 *s, va_list *va)
Definition: mem_dlmalloc.c:325
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:645
static void usage(void)
Definition: health_check.c:14
static u32 format_get_indent(u8 *s)
Definition: format.h:72
#define hash_set_mem(h, key, value)
Definition: hash.h:275
string name[64]
Definition: fib.api:25
DLMALLOC_EXPORT struct dlmallinfo mspace_mallinfo(mspace msp)
uword bytes_used_sbrk
Definition: mem.h:404
MALLINFO_FIELD_TYPE hblkhd
Definition: dlmalloc.h:804
char name[0]
Definition: mem.h:125
uword bytes_used
Definition: mem.h:393
unsigned char u8
Definition: types.h:56
__clib_export uword clib_mem_get_heap_size(clib_mem_heap_t *heap)
Definition: mem_dlmalloc.c:592
double f64
Definition: types.h:142
unsigned int u32
Definition: types.h:88
__clib_export uword clib_mem_get_heap_free_space(clib_mem_heap_t *h)
Definition: mem_dlmalloc.c:579
uword object_count
Definition: mem.h:389
clib_mem_heap_flag_t flags
Definition: mem.h:122
DLMALLOC_EXPORT mspace create_mspace_with_base(void *base, size_t capacity, int locked)
__clib_export void clib_mem_trace(int enable)
Definition: mem_dlmalloc.c:503
MALLINFO_FIELD_TYPE uordblks
Definition: dlmalloc.h:807
__clib_export uword clib_backtrace(uword *callers, uword max_callers, uword n_frames_to_skip)
Definition: backtrace.c:226
i64 word
Definition: types.h:111
void * clib_mem_vm_map_internal(void *base, clib_mem_page_sz_t log2_page_sz, uword size, int fd, uword offset, char *name)
Definition: mem.c:407
static_always_inline clib_mem_page_sz_t clib_mem_log2_page_size_validate(clib_mem_page_sz_t log2_page_size)
Definition: mem.h:537
MALLINFO_FIELD_TYPE arena
Definition: dlmalloc.h:800
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
clib_mem_page_sz_t log2_page_sz
Definition: mem.h:119
description fragment has unexpected format
Definition: map.api:433
u8 * format_memory_size(u8 *s, va_list *va)
Definition: std-formats.c:209
#define vec_end(v)
End (last data address) of vector.
MALLINFO_FIELD_TYPE ordblks
Definition: dlmalloc.h:801
int __clib_unused rv
Definition: application.c:491
__clib_export uword clib_mem_trace_enable_disable(uword enable)
Definition: mem_dlmalloc.c:525
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
#define hash_get(h, key)
Definition: hash.h:249
#define hash_unset_mem(h, key)
Definition: hash.h:291
vl_api_ikev2_sa_stats_t stats
__clib_export u8 * format_clib_mem_usage(u8 *s, va_list *va)
Definition: mem_dlmalloc.c:301
u8 * format_clib_mem_page_stats(u8 *s, va_list *va)
Definition: mem.c:75
mheap_trace_main_t mheap_trace_main
Definition: mem_dlmalloc.c:60
MALLINFO_FIELD_TYPE usmblks
Definition: dlmalloc.h:805
DLMALLOC_EXPORT void mspace_disable_expand(mspace msp)
u64 memory_size
Definition: vhost_user.h:124
clib_mem_page_sz_t
Definition: mem.h:57
u32 size
Definition: vhost_user.h:125
#define hash_free(h)
Definition: hash.h:310
mheap_trace_t * traces
Definition: mem_dlmalloc.c:44
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:444
uword bytes_used_mmap
Definition: mem.h:405
static int mheap_trace_sort(const void *_t1, const void *_t2)
Definition: mem_dlmalloc.c:341
int cJSON_bool fmt
Definition: cJSON.h:160
DLMALLOC_EXPORT int mspace_is_traced(mspace msp)
__clib_export void * clib_mem_get_heap_base(clib_mem_heap_t *h)
Definition: mem_dlmalloc.c:586
uword bytes_max
Definition: mem.h:408
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
MALLINFO_FIELD_TYPE keepcost
Definition: dlmalloc.h:809
static_always_inline clib_mem_page_sz_t clib_mem_get_log2_page_size(void)
Definition: mem.h:462
DLMALLOC_EXPORT int mspace_enable_disable_trace(mspace msp, int enable)
#define ARRAY_LEN(x)
Definition: clib.h:70
static uword round_pow2(uword x, uword pow2)
Definition: clib.h:279
uword * trace_by_callers
Definition: mem_dlmalloc.c:50
u8 * format_mheap_trace(u8 *s, va_list *va)
Definition: mem_dlmalloc.c:354
static void mheap_trace_main_free(mheap_trace_main_t *tm)
Definition: mem_dlmalloc.c:191
static clib_mem_heap_t * clib_mem_get_heap(void)
Definition: mem.h:359
int clib_mem_is_traced(void)
Definition: mem_dlmalloc.c:518
MALLINFO_FIELD_TYPE smblks
Definition: dlmalloc.h:802
static clib_mem_heap_t * clib_mem_create_heap_internal(void *base, uword size, clib_mem_page_sz_t log2_page_sz, int is_locked, char *name)
Definition: mem_dlmalloc.c:200
#define hash_create_shmem(elts, key_bytes, value_bytes)
Definition: hash.h:684
#define ASSERT(truth)
__clib_export void clib_mem_get_heap_usage(clib_mem_heap_t *heap, clib_mem_usage_t *usage)
Definition: mem_dlmalloc.c:473
void mheap_get_trace(uword offset, uword size)
Definition: mem_dlmalloc.c:63
__clib_export void * clib_mem_init_with_page_size(uword memory_size, clib_mem_page_sz_t log2_page_sz)
Definition: mem_dlmalloc.c:273
#define always_inline
Definition: rdma_mlx5dv.h:23
__clib_export void * clib_mem_init(void *memory, uword memory_size)
Definition: mem_dlmalloc.c:266
__clib_export void clib_mem_get_page_stats(void *start, clib_mem_page_sz_t log2_page_size, uword n_pages, clib_mem_page_stats_t *stats)
Definition: mem.c:552
uword clib_mem_validate_serial
Definition: mem_dlmalloc.c:491
__clib_export void mheap_trace(clib_mem_heap_t *h, int enable)
Definition: mem_dlmalloc.c:494
template key/value backing page structure
Definition: bihash_doc.h:44
__clib_export clib_mem_heap_t * clib_mem_create_heap(void *base, uword size, int is_locked, char *fmt,...)
Definition: mem_dlmalloc.c:536
void qsort(void *base, uword n, uword size, int(*compar)(const void *, const void *))
Definition: qsort.c:56
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define hash_foreach_pair(p, v, body)
Iterate over hash pairs.
Definition: hash.h:373
u64 uword
Definition: types.h:112
__clib_export void * clib_mem_init_thread_safe(void *memory, uword memory_size)
Definition: mem_dlmalloc.c:280
void mheap_put_trace(uword offset, uword size)
Definition: mem_dlmalloc.c:147
format_function_t format_clib_elf_symbol_with_address
Definition: elf_clib.h:134
#define hash_get_mem(h, key)
Definition: hash.h:269
struct clib_bihash_value offset
template key/value backing page structure
DLMALLOC_EXPORT size_t destroy_mspace(mspace msp)
DLMALLOC_EXPORT size_t mspace_footprint(mspace msp)
#define vec_foreach(var, vec)
Vector iterator.
MALLINFO_FIELD_TYPE fordblks
Definition: dlmalloc.h:808
void * base
Definition: mem.h:110
void clib_mem_main_init()
Definition: mem.c:136
uword * trace_index_by_offset
Definition: mem_dlmalloc.c:53
clib_spinlock_t lock
Definition: mem_dlmalloc.c:41
DLMALLOC_EXPORT void * mspace_least_addr(mspace msp)
__clib_export u8 * format_clib_mem_heap(u8 *s, va_list *va)
Definition: mem_dlmalloc.c:422
static_always_inline uword clib_mem_page_bytes(clib_mem_page_sz_t log2_page_size)
Definition: mem.h:547
#define CLIB_MEM_POISON(a, s)
Definition: sanitizer.h:46
void * mspace
Definition: mem.h:113