FD.io VPP  v21.01.1
Vector Packet Processing
mem.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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 #define _GNU_SOURCE
17 #include <stdlib.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 #include <sys/mount.h>
22 #include <sys/mman.h>
23 #include <fcntl.h>
24 #include <linux/mempolicy.h>
25 #include <linux/memfd.h>
26 
27 #include <vppinfra/clib.h>
28 #include <vppinfra/mem.h>
29 #include <vppinfra/lock.h>
30 #include <vppinfra/time.h>
31 #include <vppinfra/format.h>
32 #include <vppinfra/clib_error.h>
33 #include <vppinfra/linux/syscall.h>
34 #include <vppinfra/linux/sysfs.h>
35 
36 #ifndef F_LINUX_SPECIFIC_BASE
37 #define F_LINUX_SPECIFIC_BASE 1024
38 #endif
39 
40 #ifndef F_ADD_SEALS
41 #define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
42 #define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
43 
44 #define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
45 #define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
46 #define F_SEAL_GROW 0x0004 /* prevent file from growing */
47 #define F_SEAL_WRITE 0x0008 /* prevent writes */
48 #endif
49 
50 #ifndef MFD_HUGETLB
51 #define MFD_HUGETLB 0x0004U
52 #endif
53 
54 #ifndef MAP_HUGE_SHIFT
55 #define MAP_HUGE_SHIFT 26
56 #endif
57 
58 #ifndef MFD_HUGE_SHIFT
59 #define MFD_HUGE_SHIFT 26
60 #endif
61 
62 #ifndef MAP_FIXED_NOREPLACE
63 #define MAP_FIXED_NOREPLACE 0x100000
64 #endif
65 
66 static void
68 {
70  CLIB_PAUSE ();
71 }
72 
73 static void
75 {
77 }
78 
79 __clib_export uword
81 {
82  unformat_input_t input;
83  static u32 size = 0;
84  int fd;
85 
86  if (size)
87  goto done;
88 
89  /*
90  * If the kernel doesn't support hugepages, /proc/meminfo won't
91  * say anything about it. Use the regular page size as a default.
92  */
93  size = clib_mem_get_page_size () / 1024;
94 
95  if ((fd = open ("/proc/meminfo", 0)) == -1)
96  return 0;
97 
98  unformat_init_clib_file (&input, fd);
99 
100  while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT)
101  {
102  if (unformat (&input, "Hugepagesize:%_%u kB", &size))
103  ;
104  else
105  unformat_skip_line (&input);
106  }
107  unformat_free (&input);
108  close (fd);
109 done:
110  return 1024ULL * size;
111 }
112 
113 static clib_mem_page_sz_t
115 {
117  FILE *fp;
118  char tmp[33] = { };
119 
120  if ((fp = fopen ("/proc/meminfo", "r")) == NULL)
122 
123  while (fscanf (fp, "%32s", tmp) > 0)
124  if (strncmp ("Hugepagesize:", tmp, 13) == 0)
125  {
126  u32 size;
127  if (fscanf (fp, "%u", &size) > 0)
128  log2_page_size = 10 + min_log2 (size);
129  break;
130  }
131 
132  fclose (fp);
133  return log2_page_size;
134 }
135 
136 void
138 {
140  uword page_size;
141  void *va;
142  int fd;
143 
145  return;
146 
147  /* system page size */
148  page_size = sysconf (_SC_PAGESIZE);
149  mm->log2_page_sz = min_log2 (page_size);
150 
151  /* default system hugeppage size */
152  if ((fd = memfd_create ("test", MFD_HUGETLB)) != -1)
153  {
155  close (fd);
156  }
157  else /* likely kernel older than 4.14 */
159 
160  /* numa nodes */
161  va = mmap (0, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
162  MAP_ANONYMOUS, -1, 0);
163  if (va == MAP_FAILED)
164  return;
165 
166  if (mlock (va, page_size))
167  goto done;
168 
169  for (int i = 0; i < CLIB_MAX_NUMAS; i++)
170  {
171  int status;
172  if (move_pages (0, 1, &va, &i, &status, 0) == 0)
173  mm->numa_node_bitmap |= 1ULL << i;
174  }
175 
176 done:
177  munmap (va, page_size);
178 }
179 
180 __clib_export u64
182 {
183  struct stat st = { 0 };
184  if (fstat (fd, &st) == -1)
185  return 0;
186  return st.st_blksize;
187 }
188 
189 __clib_export clib_mem_page_sz_t
191 {
192  uword page_size = clib_mem_get_fd_page_size (fd);
193  return page_size ? min_log2 (page_size) : CLIB_MEM_PAGE_SZ_UNKNOWN;
194 }
195 
196 __clib_export void
198  clib_mem_page_sz_t log2_page_size)
199 {
200  u8 bit_mask = 15;
201 
202  if (log2_page_size <= 12)
203  bit_mask = 15;
204  else if (log2_page_size > 12 && log2_page_size <= 16)
205  bit_mask = 3;
206  else
207  bit_mask = 0;
208 
209  *requested_va +=
210  (clib_cpu_time_now () & bit_mask) * (1ull << log2_page_size);
211 }
212 
213 static int
215 {
217  int fd = -1;
218  char *mount_dir;
219  u8 *temp;
220  u8 *filename;
221 
222  /*
223  * Since mkdtemp will modify template string "/tmp/hugepage_mount.XXXXXX",
224  * it must not be a string constant, but should be declared as
225  * a character array.
226  */
227  temp = format (0, "/tmp/hugepage_mount.XXXXXX%c", 0);
228 
229  /* create mount directory */
230  if ((mount_dir = mkdtemp ((char *) temp)) == 0)
231  {
232  vec_free (temp);
233  vec_reset_length (mm->error);
234  mm->error = clib_error_return_unix (mm->error, "mkdtemp");
235  return CLIB_MEM_ERROR;
236  }
237 
238  if (mount ("none", mount_dir, "hugetlbfs", 0, NULL))
239  {
240  vec_free (temp);
241  rmdir ((char *) mount_dir);
242  vec_reset_length (mm->error);
243  mm->error = clib_error_return_unix (mm->error, "mount");
244  return CLIB_MEM_ERROR;
245  }
246 
247  filename = format (0, "%s/%s%c", mount_dir, name, 0);
248 
249  if ((fd = open ((char *) filename, O_CREAT | O_RDWR, 0755)) == -1)
250  {
251  vec_reset_length (mm->error);
252  mm->error = clib_error_return_unix (mm->error, "mkdtemp");
253  }
254 
255  umount2 ((char *) mount_dir, MNT_DETACH);
256  rmdir ((char *) mount_dir);
257  vec_free (filename);
258  vec_free (temp);
259 
260  return fd;
261 }
262 
263 __clib_export int
264 clib_mem_vm_create_fd (clib_mem_page_sz_t log2_page_size, char *fmt, ...)
265 {
267  int fd;
268  unsigned int memfd_flags;
269  va_list va;
270  u8 *s = 0;
271 
272  if (log2_page_size == mm->log2_page_sz)
273  log2_page_size = CLIB_MEM_PAGE_SZ_DEFAULT;
274  else if (log2_page_size == mm->log2_default_hugepage_sz)
275  log2_page_size = CLIB_MEM_PAGE_SZ_DEFAULT_HUGE;
276 
277  switch (log2_page_size)
278  {
280  return CLIB_MEM_ERROR;
282  memfd_flags = MFD_ALLOW_SEALING;
283  break;
285  memfd_flags = MFD_HUGETLB;
286  break;
287  default:
288  memfd_flags = MFD_HUGETLB | log2_page_size << MFD_HUGE_SHIFT;
289  }
290 
291  va_start (va, fmt);
292  s = va_format (0, fmt, &va);
293  va_end (va);
294 
295  /* memfd_create maximum string size is 249 chars without trailing zero */
296  if (vec_len (s) > 249)
297  _vec_len (s) = 249;
298  vec_add1 (s, 0);
299 
300  /* memfd_create introduced in kernel 3.17, we don't support older kernels */
301  fd = memfd_create ((char *) s, memfd_flags);
302 
303  /* kernel versions < 4.14 does not support memfd_create for huge pages */
304  if (fd == -1 && errno == EINVAL &&
305  log2_page_size == CLIB_MEM_PAGE_SZ_DEFAULT_HUGE)
306  {
307  fd = legacy_memfd_create (s);
308  }
309  else if (fd == -1)
310  {
311  vec_reset_length (mm->error);
312  mm->error = clib_error_return_unix (mm->error, "memfd_create");
313  vec_free (s);
314  return CLIB_MEM_ERROR;
315  }
316 
317  vec_free (s);
318 
319  if ((memfd_flags & MFD_ALLOW_SEALING) &&
320  ((fcntl (fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1))
321  {
322  vec_reset_length (mm->error);
323  mm->error = clib_error_return_unix (mm->error, "fcntl (F_ADD_SEALS)");
324  close (fd);
325  return CLIB_MEM_ERROR;
326  }
327 
328  return fd;
329 }
330 
331 uword
333 {
335  uword pagesize = 1ULL << log2_page_sz;
336  uword sys_page_sz = 1ULL << mm->log2_page_sz;
337  uword n_bytes;
338  void *base = 0, *p;
339 
340  size = round_pow2 (size, pagesize);
341 
342  /* in adition of requested reservation, we also rserve one system page
343  * (typically 4K) adjacent to the start off reservation */
344 
345  if (start)
346  {
347  /* start address is provided, so we just need to make sure we are not
348  * replacing existing map */
349  if (start & pow2_mask (log2_page_sz))
350  return ~0;
351 
352  base = (void *) start - sys_page_sz;
353  base = mmap (base, size + sys_page_sz, PROT_NONE,
354  MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0);
355  return (base == MAP_FAILED) ? ~0 : start;
356  }
357 
358  /* to make sure that we get reservation aligned to page_size we need to
359  * request one additional page as mmap will return us address which is
360  * aligned only to system page size */
361  base = mmap (0, size + pagesize, PROT_NONE,
362  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
363 
364  if (base == MAP_FAILED)
365  return ~0;
366 
367  /* return additional space at the end of allocation */
368  p = base + size + pagesize;
369  n_bytes = (uword) p & pow2_mask (log2_page_sz);
370  if (n_bytes)
371  {
372  p -= n_bytes;
373  munmap (p, n_bytes);
374  }
375 
376  /* return additional space at the start of allocation */
377  n_bytes = pagesize - sys_page_sz - n_bytes;
378  if (n_bytes)
379  {
380  munmap (base, n_bytes);
381  base += n_bytes;
382  }
383 
384  return (uword) base + sys_page_sz;
385 }
386 
387 __clib_export clib_mem_vm_map_hdr_t *
389 {
391  uword sys_page_sz = 1ULL << mm->log2_page_sz;
392  clib_mem_vm_map_hdr_t *next;
393  if (hdr == 0)
394  {
395  hdr = mm->first_map;
396  if (hdr)
397  mprotect (hdr, sys_page_sz, PROT_READ);
398  return hdr;
399  }
400  next = hdr->next;
401  mprotect (hdr, sys_page_sz, PROT_NONE);
402  if (next)
403  mprotect (next, sys_page_sz, PROT_READ);
404  return next;
405 }
406 
407 void *
409  uword size, int fd, uword offset, char *name)
410 {
413  uword sys_page_sz = 1ULL << mm->log2_page_sz;
414  int mmap_flags = MAP_FIXED, is_huge = 0;
415 
416  if (fd != -1)
417  {
418  mmap_flags |= MAP_SHARED;
419  log2_page_sz = clib_mem_get_fd_log2_page_size (fd);
420  if (log2_page_sz > mm->log2_page_sz)
421  is_huge = 1;
422  }
423  else
424  {
425  mmap_flags |= MAP_PRIVATE | MAP_ANONYMOUS;
426 
427  if (log2_page_sz == mm->log2_page_sz)
428  log2_page_sz = CLIB_MEM_PAGE_SZ_DEFAULT;
429 
430  switch (log2_page_sz)
431  {
433  /* will fail later */
434  break;
436  log2_page_sz = mm->log2_page_sz;
437  break;
439  mmap_flags |= MAP_HUGETLB;
440  log2_page_sz = mm->log2_default_hugepage_sz;
441  is_huge = 1;
442  break;
443  default:
444  mmap_flags |= MAP_HUGETLB;
445  mmap_flags |= log2_page_sz << MAP_HUGE_SHIFT;
446  is_huge = 1;
447  }
448  }
449 
450  if (log2_page_sz == CLIB_MEM_PAGE_SZ_UNKNOWN)
451  return CLIB_MEM_VM_MAP_FAILED;
452 
453  size = round_pow2 (size, 1ULL << log2_page_sz);
454 
455  base = (void *) clib_mem_vm_reserve ((uword) base, size, log2_page_sz);
456 
457  if (base == (void *) ~0)
458  return CLIB_MEM_VM_MAP_FAILED;
459 
460  base = mmap (base, size, PROT_READ | PROT_WRITE, mmap_flags, fd, offset);
461 
462  if (base == MAP_FAILED)
463  return CLIB_MEM_VM_MAP_FAILED;
464 
465  if (is_huge && (mlock (base, size) != 0))
466  {
467  munmap (base, size);
468  return CLIB_MEM_VM_MAP_FAILED;
469  }
470 
471  hdr = mmap (base - sys_page_sz, sys_page_sz, PROT_READ | PROT_WRITE,
472  MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
473 
474  if (hdr != base - sys_page_sz)
475  {
476  munmap (base, size);
477  return CLIB_MEM_VM_MAP_FAILED;
478  }
479 
480  map_lock ();
481 
482  if (mm->last_map)
483  {
484  mprotect (mm->last_map, sys_page_sz, PROT_READ | PROT_WRITE);
485  mm->last_map->next = hdr;
486  mprotect (mm->last_map, sys_page_sz, PROT_NONE);
487  }
488  else
489  mm->first_map = hdr;
490 
491  CLIB_MEM_UNPOISON (hdr, sys_page_sz);
492  hdr->next = 0;
493  hdr->prev = mm->last_map;
494  mm->last_map = hdr;
495 
496  map_unlock ();
497 
498  hdr->base_addr = (uword) base;
499  hdr->log2_page_sz = log2_page_sz;
500  hdr->num_pages = size >> log2_page_sz;
501  hdr->fd = fd;
502  snprintf (hdr->name, CLIB_VM_MAP_HDR_NAME_MAX_LEN - 1, "%s", (char *) name);
503  hdr->name[CLIB_VM_MAP_HDR_NAME_MAX_LEN - 1] = 0;
504  mprotect (hdr, sys_page_sz, PROT_NONE);
505 
506  CLIB_MEM_UNPOISON (base, size);
507  return base;
508 }
509 
510 __clib_export int
511 clib_mem_vm_unmap (void *base)
512 {
514  uword size, sys_page_sz = 1ULL << mm->log2_page_sz;
515  clib_mem_vm_map_hdr_t *hdr = base - sys_page_sz;;
516 
517  if (mprotect (hdr, sys_page_sz, PROT_READ | PROT_WRITE) != 0)
518  return CLIB_MEM_ERROR;
519 
520  size = hdr->num_pages << hdr->log2_page_sz;
521  if (munmap ((void *) hdr->base_addr, size) != 0)
522  return CLIB_MEM_ERROR;
523 
524  map_lock ();
525 
526  if (hdr->next)
527  {
528  mprotect (hdr->next, sys_page_sz, PROT_READ | PROT_WRITE);
529  hdr->next->prev = hdr->prev;
530  mprotect (hdr->next, sys_page_sz, PROT_NONE);
531  }
532  else
533  mm->last_map = hdr->prev;
534 
535  if (hdr->prev)
536  {
537  mprotect (hdr->prev, sys_page_sz, PROT_READ | PROT_WRITE);
538  hdr->prev->next = hdr->next;
539  mprotect (hdr->prev, sys_page_sz, PROT_NONE);
540  }
541  else
542  mm->first_map = hdr->next;
543 
544  map_unlock ();
545 
546  if (munmap (hdr, sys_page_sz) != 0)
547  return CLIB_MEM_ERROR;
548 
549  return 0;
550 }
551 
552 __clib_export void
553 clib_mem_get_page_stats (void *start, clib_mem_page_sz_t log2_page_size,
554  uword n_pages, clib_mem_page_stats_t * stats)
555 {
556  int i, *status = 0;
557  void **ptr = 0;
558 
559  log2_page_size = clib_mem_log2_page_size_validate (log2_page_size);
560 
561  vec_validate (status, n_pages - 1);
562  vec_validate (ptr, n_pages - 1);
563 
564  for (i = 0; i < n_pages; i++)
565  ptr[i] = start + (i << log2_page_size);
566 
567  clib_memset (stats, 0, sizeof (clib_mem_page_stats_t));
568  stats->total = n_pages;
569  stats->log2_page_sz = log2_page_size;
570 
571  if (move_pages (0, n_pages, ptr, 0, status, 0) != 0)
572  {
573  stats->unknown = n_pages;
574  return;
575  }
576 
577  for (i = 0; i < n_pages; i++)
578  {
579  if (status[i] >= 0 && status[i] < CLIB_MAX_NUMAS)
580  {
581  stats->mapped++;
582  stats->per_numa[status[i]]++;
583  }
584  else if (status[i] == -EFAULT)
585  stats->not_mapped++;
586  else
587  stats->unknown++;
588  }
589 }
590 
591 
592 __clib_export u64 *
594  int n_pages)
595 {
596  int pagesize = sysconf (_SC_PAGESIZE);
597  int fd;
598  int i;
599  u64 *r = 0;
600 
601  log2_page_size = clib_mem_log2_page_size_validate (log2_page_size);
602 
603  if ((fd = open ((char *) "/proc/self/pagemap", O_RDONLY)) == -1)
604  return 0;
605 
606  for (i = 0; i < n_pages; i++)
607  {
608  u64 seek, pagemap = 0;
609  uword vaddr = pointer_to_uword (mem) + (((u64) i) << log2_page_size);
610  seek = ((u64) vaddr / pagesize) * sizeof (u64);
611  if (lseek (fd, seek, SEEK_SET) != seek)
612  goto done;
613 
614  if (read (fd, &pagemap, sizeof (pagemap)) != (sizeof (pagemap)))
615  goto done;
616 
617  if ((pagemap & (1ULL << 63)) == 0)
618  goto done;
619 
620  pagemap &= pow2_mask (55);
621  vec_add1 (r, pagemap * pagesize);
622  }
623 
624 done:
625  close (fd);
626  if (vec_len (r) != n_pages)
627  {
628  vec_free (r);
629  return 0;
630  }
631  return r;
632 }
633 
634 __clib_export int
635 clib_mem_set_numa_affinity (u8 numa_node, int force)
636 {
638  long unsigned int mask[16] = { 0 };
639  int mask_len = sizeof (mask) * 8 + 1;
640 
641  /* no numa support */
642  if (mm->numa_node_bitmap == 0)
643  {
644  if (numa_node)
645  {
646  vec_reset_length (mm->error);
647  mm->error = clib_error_return (mm->error, "%s: numa not supported",
648  (char *) __func__);
649  return CLIB_MEM_ERROR;
650  }
651  else
652  return 0;
653  }
654 
655  mask[0] = 1 << numa_node;
656 
657  if (set_mempolicy (force ? MPOL_BIND : MPOL_PREFERRED, mask, mask_len))
658  goto error;
659 
660  vec_reset_length (mm->error);
661  return 0;
662 
663 error:
664  vec_reset_length (mm->error);
665  mm->error = clib_error_return_unix (mm->error, (char *) __func__);
666  return CLIB_MEM_ERROR;
667 }
668 
669 __clib_export int
671 {
673 
674  if (set_mempolicy (MPOL_DEFAULT, 0, 0))
675  {
676  vec_reset_length (mm->error);
677  mm->error = clib_error_return_unix (mm->error, (char *) __func__);
678  return CLIB_MEM_ERROR;
679  }
680  return 0;
681 }
682 
683 /*
684  * fd.io coding-style-patch-verification: ON
685  *
686  * Local Variables:
687  * eval: (c-set-style "gnu")
688  * End:
689  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
__clib_export u8 * va_format(u8 *s, const char *fmt, va_list *va)
Definition: format.c:387
#define CLIB_PAUSE()
Definition: lock.h:23
__clib_export int clib_mem_vm_create_fd(clib_mem_page_sz_t log2_page_size, char *fmt,...)
Definition: mem.c:264
#define CLIB_MEM_UNPOISON(a, s)
Definition: sanitizer.h:47
#define CLIB_MEM_VM_MAP_FAILED
Definition: mem.h:54
__clib_export int clib_mem_vm_unmap(void *base)
Definition: mem.c:511
__clib_export void clib_mem_vm_randomize_va(uword *requested_va, clib_mem_page_sz_t log2_page_size)
Definition: mem.c:197
#define MAP_FIXED_NOREPLACE
Definition: mem.c:63
unsigned long u64
Definition: types.h:89
struct _clib_mem_vm_map_hdr clib_mem_vm_map_hdr_t
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define EINVAL
Definition: string.h:93
static int memfd_create(const char *name, unsigned int flags)
Definition: syscall.h:52
clib_mem_vm_map_hdr_t * first_map
Definition: mem.h:146
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
static u64 clib_cpu_time_now(void)
Definition: time.h:81
__clib_export clib_mem_vm_map_hdr_t * clib_mem_vm_get_next_map_hdr(clib_mem_vm_map_hdr_t *hdr)
Definition: mem.c:388
u16 mask
Definition: flow_types.api:52
static_always_inline uword clib_mem_get_page_size(void)
Definition: mem.h:468
static clib_mem_page_sz_t legacy_get_log2_default_hugepage_size(void)
Definition: mem.c:114
unsigned char u8
Definition: types.h:56
void unformat_init_clib_file(unformat_input_t *input, int file_descriptor)
Definition: unformat.c:1064
static uword min_log2(uword x)
Definition: clib.h:162
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define MFD_ALLOW_SEALING
Definition: main.c:104
static void unformat_skip_line(unformat_input_t *i)
Definition: format.h:221
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:408
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
static long set_mempolicy(int mode, const unsigned long *nodemask, unsigned long maxnode)
Definition: syscall.h:31
static uword pow2_mask(uword x)
Definition: clib.h:238
description fragment has unexpected format
Definition: map.api:433
#define clib_error_return(e, args...)
Definition: error.h:99
__clib_export int clib_mem_set_numa_affinity(u8 numa_node, int force)
Definition: mem.c:635
unsigned int u32
Definition: types.h:88
uword per_numa[CLIB_MAX_NUMAS]
Definition: mem.h:515
#define clib_atomic_test_and_set(a)
Definition: atomics.h:42
Definition: cJSON.c:84
uword not_mapped
Definition: mem.h:514
#define clib_atomic_release(a)
Definition: atomics.h:43
#define CLIB_VM_MAP_HDR_NAME_MAX_LEN
Definition: mem.h:89
struct _unformat_input_t unformat_input_t
#define clib_error_return_unix(e, args...)
Definition: error.h:102
clib_mem_page_sz_t
Definition: mem.h:57
u32 size
Definition: vhost_user.h:106
static int legacy_memfd_create(u8 *name)
Definition: mem.c:214
clib_mem_vm_map_hdr_t * last_map
Definition: mem.h:146
#define F_ADD_SEALS
Definition: mem.c:41
static void map_lock()
Definition: mem.c:67
clib_mem_page_sz_t log2_default_hugepage_sz
Definition: mem.h:134
#define MAP_HUGE_SHIFT
Definition: ip4_mtrie.c:791
int cJSON_bool fmt
Definition: cJSON.h:160
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
__clib_export u64 * clib_mem_vm_get_paddr(void *mem, clib_mem_page_sz_t log2_page_size, int n_pages)
Definition: mem.c:593
__clib_export uword clib_mem_get_default_hugepage_size(void)
Definition: mem.c:80
static uword round_pow2(uword x, uword pow2)
Definition: clib.h:265
string name[64]
Definition: ip.api:44
uword clib_mem_vm_reserve(uword start, uword size, clib_mem_page_sz_t log2_page_sz)
Definition: mem.c:332
#define CLIB_MEM_ERROR
Definition: mem.h:55
clib_error_t * error
Definition: mem.h:152
#define CLIB_MAX_NUMAS
Definition: mem.h:53
__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:553
__clib_export clib_mem_page_sz_t clib_mem_get_fd_log2_page_size(int fd)
Definition: mem.c:190
static uword pointer_to_uword(const void *p)
Definition: types.h:131
__clib_export u64 clib_mem_get_fd_page_size(int fd)
Definition: mem.c:181
template key/value backing page structure
Definition: bihash_doc.h:44
clib_mem_page_sz_t log2_page_sz
Definition: mem.h:131
u8 map_lock
Definition: mem.h:149
clib_mem_page_sz_t log2_page_sz
Definition: mem.h:511
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:162
__clib_export clib_mem_main_t clib_mem_main
Definition: mem.c:22
void * mem
static void map_unlock()
Definition: mem.c:74
static long move_pages(int pid, unsigned long count, void **pages, const int *nodes, int *status, int flags)
Definition: syscall.h:44
void clib_mem_main_init()
Definition: mem.c:137
u32 numa_node_bitmap
Definition: mem.h:137
__clib_export int clib_mem_set_default_numa_affinity()
Definition: mem.c:670
#define F_SEAL_SHRINK
Definition: mem.c:45
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170