| 946 | struct rte_memseg *ms; |
| 947 | }; |
| 948 | static int |
| 949 | free_seg_walk(const struct rte_memseg_list *msl, void *arg) |
| 950 | { |
| 951 | struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; |
| 952 | struct rte_memseg_list *found_msl; |
| 953 | struct free_walk_param *wa = arg; |
| 954 | uintptr_t start_addr, end_addr; |
| 955 | int msl_idx, seg_idx, ret, dir_fd = -1; |
| 956 | const struct internal_config *internal_conf = |
| 957 | eal_get_internal_configuration(); |
| 958 | |
| 959 | start_addr = (uintptr_t) msl->base_va; |
| 960 | end_addr = start_addr + msl->len; |
| 961 | |
| 962 | if ((uintptr_t)wa->ms->addr < start_addr || |
| 963 | (uintptr_t)wa->ms->addr >= end_addr) |
| 964 | return 0; |
| 965 | |
| 966 | msl_idx = msl - mcfg->memsegs; |
| 967 | seg_idx = RTE_PTR_DIFF(wa->ms->addr, start_addr) / msl->page_sz; |
| 968 | |
| 969 | /* msl is const */ |
| 970 | found_msl = &mcfg->memsegs[msl_idx]; |
| 971 | |
| 972 | /* do not allow any page allocations during the time we're freeing, |
| 973 | * because file creation and locking operations are not atomic, |
| 974 | * and we might be the first or the last ones to use a particular page, |
| 975 | * so we need to ensure atomicity of every operation. |
| 976 | * |
| 977 | * during init, we already hold a write lock, so don't try to take out |
| 978 | * another one. |
| 979 | */ |
| 980 | if (wa->hi->lock_descriptor == -1 && !internal_conf->in_memory) { |
| 981 | dir_fd = open(wa->hi->hugedir, O_RDONLY); |
| 982 | if (dir_fd < 0) { |
| 983 | RTE_LOG(ERR, EAL, "%s(): Cannot open '%s': %s\n", |
| 984 | __func__, wa->hi->hugedir, strerror(errno)); |
| 985 | return -1; |
| 986 | } |
| 987 | /* blocking writelock */ |
| 988 | if (flock(dir_fd, LOCK_EX)) { |
| 989 | RTE_LOG(ERR, EAL, "%s(): Cannot lock '%s': %s\n", |
| 990 | __func__, wa->hi->hugedir, strerror(errno)); |
| 991 | close(dir_fd); |
| 992 | return -1; |
| 993 | } |
| 994 | } |
| 995 | |
| 996 | found_msl->version++; |
| 997 | |
| 998 | rte_fbarray_set_free(&found_msl->memseg_arr, seg_idx); |
| 999 | |
| 1000 | ret = free_seg(wa->ms, wa->hi, msl_idx, seg_idx); |
| 1001 | |
| 1002 | if (dir_fd >= 0) |
| 1003 | close(dir_fd); |
| 1004 | |
| 1005 | if (ret < 0) |
nothing calls this directly
no test coverage detected