1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2020 Dmitry Kozlyuk 3 */ 4 5 #include <string.h> 6 #include <sys/mman.h> 7 #include <unistd.h> 8 9 #include <rte_eal_paging.h> 10 #include <rte_errno.h> 11 #include <rte_log.h> 12 13 #include "eal_private.h" 14 15 #ifdef RTE_EXEC_ENV_LINUX 16 #define EAL_DONTDUMP MADV_DONTDUMP 17 #define EAL_DODUMP MADV_DODUMP 18 #elif defined RTE_EXEC_ENV_FREEBSD 19 #define EAL_DONTDUMP MADV_NOCORE 20 #define EAL_DODUMP MADV_CORE 21 #else 22 #error "madvise doesn't support this OS" 23 #endif 24 25 static void * 26 mem_map(void *requested_addr, size_t size, int prot, int flags, 27 int fd, size_t offset) 28 { 29 void *virt = mmap(requested_addr, size, prot, flags, fd, offset); 30 if (virt == MAP_FAILED) { 31 RTE_LOG(DEBUG, EAL, 32 "Cannot mmap(%p, 0x%zx, 0x%x, 0x%x, %d, 0x%zx): %s\n", 33 requested_addr, size, prot, flags, fd, offset, 34 strerror(errno)); 35 rte_errno = errno; 36 return NULL; 37 } 38 return virt; 39 } 40 41 static int 42 mem_unmap(void *virt, size_t size) 43 { 44 int ret = munmap(virt, size); 45 if (ret < 0) { 46 RTE_LOG(DEBUG, EAL, "Cannot munmap(%p, 0x%zx): %s\n", 47 virt, size, strerror(errno)); 48 rte_errno = errno; 49 } 50 return ret; 51 } 52 53 void * 54 eal_mem_reserve(void *requested_addr, size_t size, int flags) 55 { 56 int sys_flags = MAP_PRIVATE | MAP_ANONYMOUS; 57 58 if (flags & EAL_RESERVE_HUGEPAGES) { 59 #ifdef MAP_HUGETLB 60 sys_flags |= MAP_HUGETLB; 61 #else 62 rte_errno = ENOTSUP; 63 return NULL; 64 #endif 65 } 66 67 if (flags & EAL_RESERVE_FORCE_ADDRESS) 68 sys_flags |= MAP_FIXED; 69 70 return mem_map(requested_addr, size, PROT_NONE, sys_flags, -1, 0); 71 } 72 73 void 74 eal_mem_free(void *virt, size_t size) 75 { 76 mem_unmap(virt, size); 77 } 78 79 int 80 eal_mem_set_dump(void *virt, size_t size, bool dump) 81 { 82 int flags = dump ? EAL_DODUMP : EAL_DONTDUMP; 83 int ret = madvise(virt, size, flags); 84 if (ret) { 85 RTE_LOG(DEBUG, EAL, "madvise(%p, %#zx, %d) failed: %s\n", 86 virt, size, flags, strerror(rte_errno)); 87 rte_errno = errno; 88 } 89 return ret; 90 } 91 92 static int 93 mem_rte_to_sys_prot(int prot) 94 { 95 int sys_prot = PROT_NONE; 96 97 if (prot & RTE_PROT_READ) 98 sys_prot |= PROT_READ; 99 if (prot & RTE_PROT_WRITE) 100 sys_prot |= PROT_WRITE; 101 if (prot & RTE_PROT_EXECUTE) 102 sys_prot |= PROT_EXEC; 103 104 return sys_prot; 105 } 106 107 void * 108 rte_mem_map(void *requested_addr, size_t size, int prot, int flags, 109 int fd, size_t offset) 110 { 111 int sys_flags = 0; 112 int sys_prot; 113 114 sys_prot = mem_rte_to_sys_prot(prot); 115 116 if (flags & RTE_MAP_SHARED) 117 sys_flags |= MAP_SHARED; 118 if (flags & RTE_MAP_ANONYMOUS) 119 sys_flags |= MAP_ANONYMOUS; 120 if (flags & RTE_MAP_PRIVATE) 121 sys_flags |= MAP_PRIVATE; 122 if (flags & RTE_MAP_FORCE_ADDRESS) 123 sys_flags |= MAP_FIXED; 124 125 return mem_map(requested_addr, size, sys_prot, sys_flags, fd, offset); 126 } 127 128 int 129 rte_mem_unmap(void *virt, size_t size) 130 { 131 return mem_unmap(virt, size); 132 } 133 134 size_t 135 rte_mem_page_size(void) 136 { 137 static size_t page_size; 138 139 if (!page_size) 140 page_size = sysconf(_SC_PAGESIZE); 141 142 return page_size; 143 } 144 145 int 146 rte_mem_lock(const void *virt, size_t size) 147 { 148 int ret = mlock(virt, size); 149 if (ret) 150 rte_errno = errno; 151 return ret; 152 } 153