| 44 | |
| 45 | #define MAX_MMAP_WITH_DEFINED_ADDR_TRIES 5 |
| 46 | void * |
| 47 | eal_get_virtual_area(void *requested_addr, size_t *size, |
| 48 | size_t page_sz, int flags, int reserve_flags) |
| 49 | { |
| 50 | bool addr_is_hint, allow_shrink, unmap, no_align; |
| 51 | uint64_t map_sz; |
| 52 | void *mapped_addr, *aligned_addr; |
| 53 | uint8_t try = 0; |
| 54 | struct internal_config *internal_conf = |
| 55 | eal_get_internal_configuration(); |
| 56 | |
| 57 | if (system_page_sz == 0) |
| 58 | system_page_sz = rte_mem_page_size(); |
| 59 | |
| 60 | RTE_LOG(DEBUG, EAL, "Ask a virtual area of 0x%zx bytes\n", *size); |
| 61 | |
| 62 | addr_is_hint = (flags & EAL_VIRTUAL_AREA_ADDR_IS_HINT) > 0; |
| 63 | allow_shrink = (flags & EAL_VIRTUAL_AREA_ALLOW_SHRINK) > 0; |
| 64 | unmap = (flags & EAL_VIRTUAL_AREA_UNMAP) > 0; |
| 65 | |
| 66 | if (next_baseaddr == NULL && internal_conf->base_virtaddr != 0 && |
| 67 | rte_eal_process_type() == RTE_PROC_PRIMARY) |
| 68 | next_baseaddr = (void *) internal_conf->base_virtaddr; |
| 69 | |
| 70 | #ifdef RTE_ARCH_64 |
| 71 | if (next_baseaddr == NULL && internal_conf->base_virtaddr == 0 && |
| 72 | rte_eal_process_type() == RTE_PROC_PRIMARY) |
| 73 | next_baseaddr = (void *) eal_get_baseaddr(); |
| 74 | #endif |
| 75 | if (requested_addr == NULL && next_baseaddr != NULL) { |
| 76 | requested_addr = next_baseaddr; |
| 77 | requested_addr = RTE_PTR_ALIGN(requested_addr, page_sz); |
| 78 | addr_is_hint = true; |
| 79 | } |
| 80 | |
| 81 | /* we don't need alignment of resulting pointer in the following cases: |
| 82 | * |
| 83 | * 1. page size is equal to system size |
| 84 | * 2. we have a requested address, and it is page-aligned, and we will |
| 85 | * be discarding the address if we get a different one. |
| 86 | * |
| 87 | * for all other cases, alignment is potentially necessary. |
| 88 | */ |
| 89 | no_align = (requested_addr != NULL && |
| 90 | requested_addr == RTE_PTR_ALIGN(requested_addr, page_sz) && |
| 91 | !addr_is_hint) || |
| 92 | page_sz == system_page_sz; |
| 93 | |
| 94 | do { |
| 95 | map_sz = no_align ? *size : *size + page_sz; |
| 96 | if (map_sz > SIZE_MAX) { |
| 97 | RTE_LOG(ERR, EAL, "Map size too big\n"); |
| 98 | rte_errno = E2BIG; |
| 99 | return NULL; |
| 100 | } |
| 101 | |
| 102 | mapped_addr = eal_mem_reserve( |
| 103 | requested_addr, (size_t)map_sz, reserve_flags); |
no test coverage detected