#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <unistd.h>
#include <linux/mempolicy.h>
#include <linux/memfd.h>
+#include <sched.h>
#include <vppinfra/format.h>
#include <vppinfra/linux/syscall.h>
if (*numa_node == CLIB_PMALLOC_NUMA_LOCAL)
{
u32 cpu;
- if (getcpu (&cpu, numa_node, 0) != 0)
+ if (getcpu (&cpu, numa_node) != 0)
return 1;
}
return 0;
}
int
-clib_pmalloc_init (clib_pmalloc_main_t * pm, uword size)
+clib_pmalloc_init (clib_pmalloc_main_t * pm, uword base_addr, uword size)
{
uword off, pagesize;
u64 *pt = 0;
+ int mmap_flags;
ASSERT (pm->error == 0);
pm->max_pages = size >> pm->def_log2_page_sz;
/* reserve VA space for future growth */
- pm->base = mmap (0, size + pagesize, PROT_NONE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
+
+ if (base_addr)
+ mmap_flags |= MAP_FIXED;
+
+ pm->base = mmap (uword_to_pointer (base_addr, void *), size + pagesize,
+ PROT_NONE, mmap_flags, -1, 0);
if (pm->base == MAP_FAILED)
{
pp->n_free_chunks = a->subpages_per_page;
}
+ if (pp->n_free_blocks < n_blocks)
+ return 0;
+
alloc_chunk_index = pp->first_chunk_index;
next_chunk:
int old_mpol = -1;
long unsigned int mask[16] = { 0 };
long unsigned int old_mask[16] = { 0 };
+ uword page_size = 1ULL << a->log2_subpage_sz;
uword size = (uword) n_pages << pm->def_log2_page_sz;
clib_error_free (pm->error);
if ((pm->flags & CLIB_PMALLOC_F_NO_PAGEMAP) == 0)
mmap_flags |= MAP_LOCKED;
- if (a->log2_subpage_sz != pm->sys_log2_page_sz)
- mmap_flags |= MAP_HUGETLB | MAP_LOCKED;
-
if (a->flags & CLIB_PMALLOC_ARENA_F_SHARED_MEM)
{
mmap_flags |= MAP_SHARED;
- if (mmap_flags & MAP_HUGETLB)
+ if (a->log2_subpage_sz != pm->sys_log2_page_sz)
pm->error = clib_mem_create_hugetlb_fd ((char *) a->name, &a->fd);
else
pm->error = clib_mem_create_fd ((char *) a->name, &a->fd);
}
else
{
+ if (a->log2_subpage_sz != pm->sys_log2_page_sz)
+ mmap_flags |= MAP_HUGETLB;
+
mmap_flags |= MAP_PRIVATE | MAP_ANONYMOUS;
a->fd = -1;
}
goto error;
}
+ /* Check if huge page is not allocated,
+ wrong allocation will generate the SIGBUS */
+ if (a->log2_subpage_sz != pm->sys_log2_page_sz)
+ {
+ for (int i = 0; i < n_pages; i++)
+ {
+ unsigned char flag;
+ mincore (va + i * page_size, 1, &flag);
+ // flag is 1 if the page was successfully allocated and in memory
+ if (!flag)
+ {
+ pm->error =
+ clib_error_return_unix (0,
+ "Unable to fulfill huge page allocation request");
+ goto error;
+ }
+ }
+ }
+
clib_memset (va, 0, size);
rv = set_mempolicy (old_mpol, old_mask, sizeof (old_mask) * 8 + 1);
pp->n_free_blocks = 1 << (pm->def_log2_page_sz - PMALLOC_LOG2_BLOCK_SZ);
pp->index = pp - pm->pages;
pp->arena_index = a->index;
- pp->pa = (uword) va + (1 << pm->def_log2_page_sz) * i;
vec_add1 (a->page_indices, pp->index);
a->n_pages++;
}
int verbose = va_arg (*va, int);
u32 indent = format_get_indent (s);
- s = format (s, "page %u: phys-addr %p ", pp->index, pp->pa);
-
if (pp->chunks == 0)
return s;
{
uword *lookup_val, pa, va;
lookup_val = vec_elt_at_index (pm->lookup_table, index);
- va = pointer_to_uword (pm->base) + (index << pm->lookup_log2_page_sz);
+ va =
+ pointer_to_uword (pm->base) +
+ ((uword) index << pm->lookup_log2_page_sz);
pa = va - *lookup_val;
s =
format (s, "\n %16p %13p %8U", uword_to_pointer (va, u64),