xref: /dpdk/lib/eal/unix/eal_unix_memory.c (revision ae67895b507bb6af22263c79ba0d5c374b396485)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2020 Dmitry Kozlyuk
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #include <string.h>
699a2dd95SBruce Richardson #include <sys/mman.h>
799a2dd95SBruce Richardson #include <unistd.h>
86beb2d29SLance Richardson #include <inttypes.h>
999a2dd95SBruce Richardson 
1099a2dd95SBruce Richardson #include <rte_eal_paging.h>
1199a2dd95SBruce Richardson #include <rte_errno.h>
1299a2dd95SBruce Richardson #include <rte_log.h>
1399a2dd95SBruce Richardson 
1499a2dd95SBruce Richardson #include "eal_private.h"
1599a2dd95SBruce Richardson 
1699a2dd95SBruce Richardson #ifdef RTE_EXEC_ENV_LINUX
1799a2dd95SBruce Richardson #define EAL_DONTDUMP MADV_DONTDUMP
1899a2dd95SBruce Richardson #define EAL_DODUMP   MADV_DODUMP
1999a2dd95SBruce Richardson #elif defined RTE_EXEC_ENV_FREEBSD
2099a2dd95SBruce Richardson #define EAL_DONTDUMP MADV_NOCORE
2199a2dd95SBruce Richardson #define EAL_DODUMP   MADV_CORE
2299a2dd95SBruce Richardson #else
2399a2dd95SBruce Richardson #error "madvise doesn't support this OS"
2499a2dd95SBruce Richardson #endif
2599a2dd95SBruce Richardson 
2699a2dd95SBruce Richardson static void *
mem_map(void * requested_addr,size_t size,int prot,int flags,int fd,uint64_t offset)2799a2dd95SBruce Richardson mem_map(void *requested_addr, size_t size, int prot, int flags,
286beb2d29SLance Richardson 	int fd, uint64_t offset)
2999a2dd95SBruce Richardson {
3099a2dd95SBruce Richardson 	void *virt = mmap(requested_addr, size, prot, flags, fd, offset);
3199a2dd95SBruce Richardson 	if (virt == MAP_FAILED) {
32*ae67895bSDavid Marchand 		EAL_LOG(DEBUG,
33*ae67895bSDavid Marchand 		    "Cannot mmap(%p, 0x%zx, 0x%x, 0x%x, %d, 0x%"PRIx64"): %s",
3499a2dd95SBruce Richardson 		    requested_addr, size, prot, flags, fd, offset,
3599a2dd95SBruce Richardson 		    strerror(errno));
3699a2dd95SBruce Richardson 		rte_errno = errno;
3799a2dd95SBruce Richardson 		return NULL;
3899a2dd95SBruce Richardson 	}
3999a2dd95SBruce Richardson 	return virt;
4099a2dd95SBruce Richardson }
4199a2dd95SBruce Richardson 
4299a2dd95SBruce Richardson static int
mem_unmap(void * virt,size_t size)4399a2dd95SBruce Richardson mem_unmap(void *virt, size_t size)
4499a2dd95SBruce Richardson {
4599a2dd95SBruce Richardson 	int ret = munmap(virt, size);
4699a2dd95SBruce Richardson 	if (ret < 0) {
47*ae67895bSDavid Marchand 		EAL_LOG(DEBUG, "Cannot munmap(%p, 0x%zx): %s",
4899a2dd95SBruce Richardson 			virt, size, strerror(errno));
4999a2dd95SBruce Richardson 		rte_errno = errno;
5099a2dd95SBruce Richardson 	}
5199a2dd95SBruce Richardson 	return ret;
5299a2dd95SBruce Richardson }
5399a2dd95SBruce Richardson 
5499a2dd95SBruce Richardson void *
eal_mem_reserve(void * requested_addr,size_t size,int flags)5599a2dd95SBruce Richardson eal_mem_reserve(void *requested_addr, size_t size, int flags)
5699a2dd95SBruce Richardson {
5799a2dd95SBruce Richardson 	int sys_flags = MAP_PRIVATE | MAP_ANONYMOUS;
5899a2dd95SBruce Richardson 
5999a2dd95SBruce Richardson 	if (flags & EAL_RESERVE_HUGEPAGES) {
6099a2dd95SBruce Richardson #ifdef MAP_HUGETLB
6199a2dd95SBruce Richardson 		sys_flags |= MAP_HUGETLB;
6299a2dd95SBruce Richardson #else
6399a2dd95SBruce Richardson 		rte_errno = ENOTSUP;
6499a2dd95SBruce Richardson 		return NULL;
6599a2dd95SBruce Richardson #endif
6699a2dd95SBruce Richardson 	}
6799a2dd95SBruce Richardson 
6899a2dd95SBruce Richardson 	if (flags & EAL_RESERVE_FORCE_ADDRESS)
6999a2dd95SBruce Richardson 		sys_flags |= MAP_FIXED;
7099a2dd95SBruce Richardson 
7199a2dd95SBruce Richardson 	return mem_map(requested_addr, size, PROT_NONE, sys_flags, -1, 0);
7299a2dd95SBruce Richardson }
7399a2dd95SBruce Richardson 
7499a2dd95SBruce Richardson void
eal_mem_free(void * virt,size_t size)7599a2dd95SBruce Richardson eal_mem_free(void *virt, size_t size)
7699a2dd95SBruce Richardson {
7799a2dd95SBruce Richardson 	mem_unmap(virt, size);
7899a2dd95SBruce Richardson }
7999a2dd95SBruce Richardson 
8099a2dd95SBruce Richardson int
eal_mem_set_dump(void * virt,size_t size,bool dump)8199a2dd95SBruce Richardson eal_mem_set_dump(void *virt, size_t size, bool dump)
8299a2dd95SBruce Richardson {
8399a2dd95SBruce Richardson 	int flags = dump ? EAL_DODUMP : EAL_DONTDUMP;
8499a2dd95SBruce Richardson 	int ret = madvise(virt, size, flags);
8599a2dd95SBruce Richardson 	if (ret) {
86*ae67895bSDavid Marchand 		EAL_LOG(DEBUG, "madvise(%p, %#zx, %d) failed: %s",
8799a2dd95SBruce Richardson 				virt, size, flags, strerror(rte_errno));
8899a2dd95SBruce Richardson 		rte_errno = errno;
8999a2dd95SBruce Richardson 	}
9099a2dd95SBruce Richardson 	return ret;
9199a2dd95SBruce Richardson }
9299a2dd95SBruce Richardson 
9399a2dd95SBruce Richardson static int
mem_rte_to_sys_prot(int prot)9499a2dd95SBruce Richardson mem_rte_to_sys_prot(int prot)
9599a2dd95SBruce Richardson {
9699a2dd95SBruce Richardson 	int sys_prot = PROT_NONE;
9799a2dd95SBruce Richardson 
9899a2dd95SBruce Richardson 	if (prot & RTE_PROT_READ)
9999a2dd95SBruce Richardson 		sys_prot |= PROT_READ;
10099a2dd95SBruce Richardson 	if (prot & RTE_PROT_WRITE)
10199a2dd95SBruce Richardson 		sys_prot |= PROT_WRITE;
10299a2dd95SBruce Richardson 	if (prot & RTE_PROT_EXECUTE)
10399a2dd95SBruce Richardson 		sys_prot |= PROT_EXEC;
10499a2dd95SBruce Richardson 
10599a2dd95SBruce Richardson 	return sys_prot;
10699a2dd95SBruce Richardson }
10799a2dd95SBruce Richardson 
10899a2dd95SBruce Richardson void *
rte_mem_map(void * requested_addr,size_t size,int prot,int flags,int fd,uint64_t offset)10999a2dd95SBruce Richardson rte_mem_map(void *requested_addr, size_t size, int prot, int flags,
1106beb2d29SLance Richardson 	int fd, uint64_t offset)
11199a2dd95SBruce Richardson {
11299a2dd95SBruce Richardson 	int sys_flags = 0;
11399a2dd95SBruce Richardson 	int sys_prot;
11499a2dd95SBruce Richardson 
11599a2dd95SBruce Richardson 	sys_prot = mem_rte_to_sys_prot(prot);
11699a2dd95SBruce Richardson 
11799a2dd95SBruce Richardson 	if (flags & RTE_MAP_SHARED)
11899a2dd95SBruce Richardson 		sys_flags |= MAP_SHARED;
11999a2dd95SBruce Richardson 	if (flags & RTE_MAP_ANONYMOUS)
12099a2dd95SBruce Richardson 		sys_flags |= MAP_ANONYMOUS;
12199a2dd95SBruce Richardson 	if (flags & RTE_MAP_PRIVATE)
12299a2dd95SBruce Richardson 		sys_flags |= MAP_PRIVATE;
12399a2dd95SBruce Richardson 	if (flags & RTE_MAP_FORCE_ADDRESS)
12499a2dd95SBruce Richardson 		sys_flags |= MAP_FIXED;
12599a2dd95SBruce Richardson 
12699a2dd95SBruce Richardson 	return mem_map(requested_addr, size, sys_prot, sys_flags, fd, offset);
12799a2dd95SBruce Richardson }
12899a2dd95SBruce Richardson 
12999a2dd95SBruce Richardson int
rte_mem_unmap(void * virt,size_t size)13099a2dd95SBruce Richardson rte_mem_unmap(void *virt, size_t size)
13199a2dd95SBruce Richardson {
13299a2dd95SBruce Richardson 	return mem_unmap(virt, size);
13399a2dd95SBruce Richardson }
13499a2dd95SBruce Richardson 
13599a2dd95SBruce Richardson size_t
rte_mem_page_size(void)13699a2dd95SBruce Richardson rte_mem_page_size(void)
13799a2dd95SBruce Richardson {
13899a2dd95SBruce Richardson 	static size_t page_size;
13999a2dd95SBruce Richardson 
14099a2dd95SBruce Richardson 	if (!page_size)
14199a2dd95SBruce Richardson 		page_size = sysconf(_SC_PAGESIZE);
14299a2dd95SBruce Richardson 
14399a2dd95SBruce Richardson 	return page_size;
14499a2dd95SBruce Richardson }
14599a2dd95SBruce Richardson 
14699a2dd95SBruce Richardson int
rte_mem_lock(const void * virt,size_t size)14799a2dd95SBruce Richardson rte_mem_lock(const void *virt, size_t size)
14899a2dd95SBruce Richardson {
14999a2dd95SBruce Richardson 	int ret = mlock(virt, size);
15099a2dd95SBruce Richardson 	if (ret)
15199a2dd95SBruce Richardson 		rte_errno = errno;
15299a2dd95SBruce Richardson 	return ret;
15399a2dd95SBruce Richardson }
154