@@ -95,6 +95,7 @@ eal_long_options[] = {
{OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM },
{OPT_VMWARE_TSC_MAP, 0, NULL, OPT_VMWARE_TSC_MAP_NUM },
{OPT_XEN_DOM0, 0, NULL, OPT_XEN_DOM0_NUM },
+ {OPT_CONTIG_MEM, 0, NULL, OPT_CONTIG_MEM_NUM },
{0, 0, NULL, 0 }
};
@@ -854,6 +855,12 @@ eal_parse_common_option(int opt, const char *optarg,
conf->process_type = eal_parse_proc_type(optarg);
break;
+#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
+ case OPT_CONTIG_MEM_NUM:
+ conf->contig_mem = 1;
+ break;
+#endif
+
case OPT_MASTER_LCORE_NUM:
if (eal_parse_master_lcore(optarg) < 0) {
RTE_LOG(ERR, EAL, "invalid parameter for --"
@@ -66,6 +66,7 @@ struct internal_config {
volatile unsigned no_hugetlbfs; /**< true to disable hugetlbfs */
unsigned hugepage_unlink; /**< true to unlink backing files */
volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
+ volatile unsigned contig_mem; /**< true to create contiguous eal memory */
volatile unsigned no_pci; /**< true to disable PCI */
volatile unsigned no_hpet; /**< true to disable HPET */
volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
@@ -55,6 +55,8 @@ enum {
OPT_HUGE_DIR_NUM,
#define OPT_HUGE_UNLINK "huge-unlink"
OPT_HUGE_UNLINK_NUM,
+#define OPT_CONTIG_MEM "contig-mem"
+ OPT_CONTIG_MEM_NUM,
#define OPT_LCORES "lcores"
OPT_LCORES_NUM,
#define OPT_LOG_LEVEL "log-level"
@@ -851,9 +851,21 @@ unmap_unneeded_hugepages(struct hugepage_file *hugepg_tbl,
/* find a page that matches the criteria */
if ((hp->size == hpi[size].hugepage_sz) &&
(hp->socket_id == (int) socket)) {
+#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
+ int nr_pg_left = hpi[size].num_pages[socket] - pages_found;
+ /*
+ * if contig_mem is enabled and the page doesn't have
+ * requested space, unmap it.
+ * Also, if we skipped enough pages, unmap the rest.
+ */
+ if ((pages_found == hpi[size].num_pages[socket]) ||
+ ((internal_config.contig_mem) &&
+ (hp->repeated < nr_pg_left))) {
+#else
/* if we skipped enough pages, unmap the rest */
if (pages_found == hpi[size].num_pages[socket]) {
+#endif
uint64_t unmap_len;
#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
@@ -875,9 +887,6 @@ unmap_unneeded_hugepages(struct hugepage_file *hugepg_tbl,
#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
/* else, check how much do we need to map */
else {
- int nr_pg_left =
- hpi[size].num_pages[socket] - pages_found;
-
/* if we need enough memory to fit into the segment */
if (hp->repeated <= nr_pg_left) {
pages_found += hp->repeated;
@@ -949,7 +958,9 @@ 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 num_hp_info,
+ struct hugepage_file *hugepg_tbl __rte_unused,
+ unsigned nr_hugefiles __rte_unused)
{
unsigned socket, j, i = 0;
unsigned requested, available;
@@ -960,6 +971,46 @@ calc_num_pages_per_socket(uint64_t * memory,
if (num_hp_info == 0)
return -1;
+#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
+ /*
+ * If contiguous memory is required, but specific memory amounts
+ * per socket weren't requested
+ */
+ if ((internal_config.force_sockets == 0)
+ && (internal_config.contig_mem == 1)) {
+ size_t max_contig_memory_per_socket[RTE_MAX_NUMA_NODES];
+ size_t total_size, max_contig_memory = 0;
+
+ memset(max_contig_memory_per_socket, 0,
+ sizeof(max_contig_memory_per_socket));
+
+ /* Calculate maximum contiguous memory size */
+ for (i = 0; i < nr_hugefiles; i++) {
+ socket = hugepg_tbl[i].socket_id;
+
+ max_contig_memory_per_socket[socket] =
+ RTE_MAX(max_contig_memory_per_socket[socket],
+ (hugepg_tbl[i].size * hugepg_tbl[i].repeated));
+ max_contig_memory = RTE_MAX(max_contig_memory,
+ max_contig_memory_per_socket[socket]);
+ }
+
+ total_size = internal_config.memory;
+
+ /* If no enough contiguous memory */
+ if (max_contig_memory < total_mem) {
+ /* To display warning, set how much we can find */
+ total_mem -= max_contig_memory;
+ goto out;
+ }
+
+ /* Find suitable contiguous memory */
+ for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) {
+ if (total_size <= max_contig_memory_per_socket[socket])
+ memory[socket] = total_size;
+ }
+ } else
+#endif
/* if specific memory amounts per socket weren't requested */
if (internal_config.force_sockets == 0) {
int cpu_per_socket[RTE_MAX_NUMA_NODES];
@@ -1009,6 +1060,18 @@ calc_num_pages_per_socket(uint64_t * memory,
for (socket = 0; socket < RTE_MAX_NUMA_NODES && total_mem != 0; socket++) {
/* skips if the memory on specific socket wasn't requested */
for (i = 0; i < num_hp_info && memory[socket] != 0; i++){
+#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
+ if (internal_config.contig_mem) {
+ size_t memory_size;
+
+ memory_size = hp_info[i].num_pages[socket] *
+ hp_info[i].hugepage_sz;
+ /* If memory size isn't enough, skip it */
+ if (memory[socket] > memory_size)
+ continue;
+ }
+#endif
+
hp_used[i].hugedir = hp_info[i].hugedir;
hp_used[i].num_pages[socket] = RTE_MIN(
memory[socket] / hp_info[i].hugepage_sz,
@@ -1064,6 +1127,9 @@ calc_num_pages_per_socket(uint64_t * memory,
}
}
+#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
+out:
+#endif
/* if we didn't satisfy total memory requirements */
if (total_mem > 0) {
requested = (unsigned) (internal_config.memory / 0x100000);
@@ -1268,7 +1334,8 @@ rte_eal_hugepage_init(void)
/* calculate final number of pages */
nr_hugepages = calc_num_pages_per_socket(memory,
internal_config.hugepage_info, used_hp,
- internal_config.num_hugepage_sizes);
+ internal_config.num_hugepage_sizes,
+ tmp_hp, nr_hugefiles);
/* error if not enough memory available */
if (nr_hugepages < 0)