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