diff options
Diffstat (limited to 'src/vppinfra')
-rw-r--r-- | src/vppinfra/linux/mem.c | 57 | ||||
-rw-r--r-- | src/vppinfra/mem.h | 15 |
2 files changed, 64 insertions, 8 deletions
diff --git a/src/vppinfra/linux/mem.c b/src/vppinfra/linux/mem.c index e0e22b0a775..3c449226273 100644 --- a/src/vppinfra/linux/mem.c +++ b/src/vppinfra/linux/mem.c @@ -26,6 +26,7 @@ #include <vppinfra/clib.h> #include <vppinfra/mem.h> +#include <vppinfra/time.h> #include <vppinfra/format.h> #include <vppinfra/clib_error.h> #include <vppinfra/linux/syscall.h> @@ -45,13 +46,34 @@ #define F_SEAL_WRITE 0x0008 /* prevent writes */ #endif -int -clib_mem_vm_get_log2_page_size (int fd) +uword +clib_mem_vm_get_page_size (int fd) { struct stat st = { 0 }; if (fstat (fd, &st) == -1) return 0; - return min_log2 (st.st_blksize); + return st.st_blksize; +} + +int +clib_mem_vm_get_log2_page_size (int fd) +{ + return min_log2 (clib_mem_vm_get_page_size (fd)); +} + +static void +clib_mem_vm_randomize_va (uword * requested_va, u32 log2_page_size) +{ + u8 bit_mask = 15; + + if (log2_page_size <= 12) + bit_mask = 15; + else if (log2_page_size > 12 && log2_page_size <= 16) + bit_mask = 3; + else + bit_mask = 0; + + *requested_va += (clib_cpu_time_now () & bit_mask) * (1 << log2_page_size); } clib_error_t * @@ -131,13 +153,19 @@ clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a) goto error; } } - log2_page_size = clib_mem_vm_get_log2_page_size (fd); + log2_page_size = clib_mem_vm_get_log2_page_size (fd); if (log2_page_size == 0) { err = clib_error_return_unix (0, "cannot determine page size"); goto error; } + + if (a->requested_va) + { + clib_mem_vm_randomize_va (&a->requested_va, log2_page_size); + mmap_flags |= MAP_FIXED; + } } else /* not CLIB_MEM_VM_F_SHARED */ { @@ -155,7 +183,6 @@ clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a) n_pages = ((a->size - 1) >> log2_page_size) + 1; - if (a->flags & CLIB_MEM_VM_F_HUGETLB_PREALLOC) { err = clib_sysfs_prealloc_hugepages (a->numa_node, @@ -186,7 +213,8 @@ clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a) } } - addr = mmap (0, a->size, (PROT_READ | PROT_WRITE), mmap_flags, fd, 0); + addr = mmap (uword_to_pointer (a->requested_va, void *), a->size, + (PROT_READ | PROT_WRITE), mmap_flags, fd, 0); if (addr == MAP_FAILED) { err = clib_error_return_unix (0, "mmap"); @@ -255,7 +283,24 @@ done: return r; } +clib_error_t * +clib_mem_vm_ext_map (clib_mem_vm_map_t * a) +{ + int mmap_flags = MAP_SHARED; + void *addr; + if (a->requested_va) + mmap_flags |= MAP_FIXED; + + addr = (void *) mmap (uword_to_pointer (a->requested_va, void *), a->size, + PROT_READ | PROT_WRITE, mmap_flags, a->fd, 0); + + if (addr == MAP_FAILED) + return clib_error_return_unix (0, "mmap"); + + a->addr = addr; + return 0; +} /* * fd.io coding-style-patch-verification: ON diff --git a/src/vppinfra/mem.h b/src/vppinfra/mem.h index 69ab880317d..b566e8d8895 100644 --- a/src/vppinfra/mem.h +++ b/src/vppinfra/mem.h @@ -330,7 +330,7 @@ typedef struct #define CLIB_MEM_VM_F_HUGETLB_PREALLOC (1 << 4) u32 flags; /**< vm allocation flags: <br> CLIB_MEM_VM_F_SHARED: request shared memory, file - destiptor will be provided on successful allocation. + descriptor will be provided on successful allocation. <br> CLIB_MEM_VM_F_HUGETLB: request hugepages. <br> CLIB_MEM_VM_F_NUMA_PREFER: numa_node field contains valid numa node preference. @@ -342,15 +342,26 @@ typedef struct uword size; /**< Allocation size, set by caller. */ int numa_node; /**< numa node preference. Valid if CLIB_MEM_VM_F_NUMA_PREFER set. */ void *addr; /**< Pointer to allocated memory, set on successful allocation. */ - int fd; /**< File desriptor, set on successful allocation if CLIB_MEM_VM_F_SHARED is set. */ + int fd; /**< File descriptor, set on successful allocation if CLIB_MEM_VM_F_SHARED is set. */ int log2_page_size; /* Page size in log2 format, set on successful allocation. */ int n_pages; /* Number of pages. */ + uword requested_va; /**< Request fixed position mapping */ } clib_mem_vm_alloc_t; clib_error_t *clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a); +u64 clib_mem_vm_get_page_size (int fd); int clib_mem_vm_get_log2_page_size (int fd); u64 *clib_mem_vm_get_paddr (void *mem, int log2_page_size, int n_pages); +typedef struct +{ + uword size; /**< Map size */ + int fd; /**< File descriptor to be mapped */ + uword requested_va; /**< Request fixed position mapping */ + void *addr; /**< Pointer to mapped memory, if successful */ +} clib_mem_vm_map_t; +clib_error_t *clib_mem_vm_ext_map (clib_mem_vm_map_t * a); + #include <vppinfra/error.h> /* clib_panic */ |