/* * This function is a NUMA-aware equivalent of calc_num_pages. * It takes in the list of hugepage sizes and the * number of pages thereof, and calculates the best number of * pages of each size to fulfill the request for <memory> ram */ static int calc_num_pages_per_socket(uint64_t * memory, struct hugepage_info *hp_info, struct hugepage_info *hp_used, unsigned num_hp_info) { unsigned socket, j, i = 0; unsigned requested, available; int total_num_pages = 0; uint64_t remaining_mem, cur_mem; uint64_t total_mem = internal_config.memory; if (num_hp_info == 0) return -1; /* if specific memory amounts per socket weren't requested */ if (internal_config.force_sockets == 0) { int cpu_per_socket[RTE_MAX_NUMA_NODES]; size_t default_size, total_size; unsigned lcore_id; /* Compute number of cores per socket */ memset(cpu_per_socket, 0, sizeof(cpu_per_socket)); RTE_LCORE_FOREACH(lcore_id) { cpu_per_socket[rte_lcore_to_socket_id(lcore_id)]++; } /* * Automatically spread requested memory amongst detected sockets according * to number of cores from cpu mask present on each socket */ total_size = internal_config.memory; for (socket = 0; socket < RTE_MAX_NUMA_NODES && total_size != 0; socket++) { /* Set memory amount per socket */ default_size = (internal_config.memory * cpu_per_socket[socket]) / rte_lcore_count(); /* Limit to maximum available memory on socket */ default_size = RTE_MIN(default_size, get_socket_mem_size(socket)); /* Update sizes */ memory[socket] = default_size; total_size -= default_size; } /* * If some memory is remaining, try to allocate it by getting all * available memory from sockets, one after the other */ for (socket = 0; socket < RTE_MAX_NUMA_NODES && total_size != 0; socket++) { /* take whatever is available */ default_size = RTE_MIN(get_socket_mem_size(socket) - memory[socket], total_size); /* Update sizes */ memory[socket] += default_size; total_size -= default_size; } }
static int calc_num_pages_per_socket(uint64_t *memory, struct odp_hugepage_type *hp_info, struct odp_hugepage_type *hp_used, unsigned num_hp_info) { unsigned socket, j, i = 0; unsigned requested, available; int total_num_pages = 0; uint64_t remaining_mem, cur_mem; uint64_t total_mem = local_config.memory; if (num_hp_info == 0) return -1; if (local_config.force_sockets == 0) { int cpu_per_socket[ODP_MAX_NUMA_NODES]; size_t default_size, total_size; unsigned core_id; memset(cpu_per_socket, 0, sizeof(cpu_per_socket)); ODP_LCORE_FOREACH(core_id) { cpu_per_socket[odp_core_to_socket_id(core_id)]++; } total_size = local_config.memory; for (socket = 0; socket < ODP_MAX_NUMA_NODES && total_size != 0; socket++) { default_size = (local_config.memory * cpu_per_socket[socket]) / odp_core_num(); default_size = ODP_MIN(default_size, get_socket_mem_size(socket)); memory[socket] = default_size; total_size -= default_size; } for (socket = 0; socket < ODP_MAX_NUMA_NODES && total_size != 0; socket++) { default_size = ODP_MIN(get_socket_mem_size(socket) - memory[socket], total_size); memory[socket] += default_size; total_size -= default_size; } }
/* * This function is a NUMA-aware equivalent of calc_num_pages. * It takes in the list of hugepage sizes and the * number of pages thereof, and calculates the best number of * pages of each size to fulfill the request for <memory> ram */ static int calc_num_pages_per_socket(uint64_t * memory, struct hugepage_info *hp_info, struct hugepage_info *hp_used, unsigned num_hp_info) { unsigned socket, j, i = 0; unsigned requested, available; int total_num_pages = 0; uint64_t remaining_mem, cur_mem; uint64_t total_mem = internal_config.memory; if (num_hp_info == 0) return -1; for (socket = 0; socket < RTE_MAX_NUMA_NODES && total_mem != 0; socket++) { /* if specific memory amounts per socket weren't requested */ if (internal_config.force_sockets == 0) { /* take whatever is available */ memory[socket] = RTE_MIN(get_socket_mem_size(socket), total_mem); } /* skips if the memory on specific socket wasn't requested */ for (i = 0; i < num_hp_info && memory[socket] != 0; i++){ hp_used[i].hugedir = hp_info[i].hugedir; hp_used[i].num_pages[socket] = RTE_MIN( memory[socket] / hp_info[i].hugepage_sz, hp_info[i].num_pages[socket]); cur_mem = hp_used[i].num_pages[socket] * hp_used[i].hugepage_sz; memory[socket] -= cur_mem; total_mem -= cur_mem; total_num_pages += hp_used[i].num_pages[socket]; /* check if we have met all memory requests */ if (memory[socket] == 0) break; /* check if we have any more pages left at this size, if so * move on to next size */ if (hp_used[i].num_pages[socket] == hp_info[i].num_pages[socket]) continue; /* At this point we know that there are more pages available that are * bigger than the memory we want, so lets see if we can get enough * from other page sizes. */ remaining_mem = 0; for (j = i+1; j < num_hp_info; j++) remaining_mem += hp_info[j].hugepage_sz * hp_info[j].num_pages[socket]; /* is there enough other memory, if not allocate another page and quit */ if (remaining_mem < memory[socket]){ cur_mem = RTE_MIN(memory[socket], hp_info[i].hugepage_sz); memory[socket] -= cur_mem; total_mem -= cur_mem; hp_used[i].num_pages[socket]++; total_num_pages++; break; /* we are done with this socket*/ } } /* if we didn't satisfy all memory requirements per socket */ if (memory[socket] > 0) { /* to prevent icc errors */ requested = (unsigned) (internal_config.socket_mem[socket] / 0x100000); available = requested - ((unsigned) (memory[socket] / 0x100000)); RTE_LOG(INFO, EAL, "Not enough memory available on socket %u! " "Requested: %uMB, available: %uMB\n", socket, requested, available); return -1; } } /* if we didn't satisfy total memory requirements */ if (total_mem > 0) { requested = (unsigned) (internal_config.memory / 0x100000); available = requested - (unsigned) (total_mem / 0x100000); RTE_LOG(INFO, EAL, "Not enough memory available! Requested: %uMB," " available: %uMB\n", requested, available); return -1; } return total_num_pages; }