Blob Blame History Raw
From 284ae3e9ff9a92575c28c858efd2c85c8de6d440 Mon Sep 17 00:00:00 2001
From: Chao Zhu <chaozhu@linux.vnet.ibm.com>
Date: Thu, 6 Apr 2017 15:36:09 +0530
Subject: [PATCH] eal/ppc: fix mmap for memory initialization

On IBM POWER platform, when mapping /dev/zero file to hugepage memory
space, mmap will not respect the requested address hint. This will cause
the memory initialization for the second process fails. This patch adds
the required mmap flags to make it work. Beside this, users need to set
the nr_overcommit_hugepages to expand the VA range. When
doing the initialization, users need to set both nr_hugepages and
nr_overcommit_hugepages to the same value, like 64, 128, etc.

Signed-off-by: Chao Zhu <chaozhu@linux.vnet.ibm.com>
Acked-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/linux_gsg/sys_reqs.rst        |  6 ++++++
 lib/librte_eal/linuxapp/eal/eal_memory.c | 16 ++++++++++++++--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/doc/guides/linux_gsg/sys_reqs.rst b/doc/guides/linux_gsg/sys_reqs.rst
index 61222c699b7d..3a28c9e51775 100644
--- a/doc/guides/linux_gsg/sys_reqs.rst
+++ b/doc/guides/linux_gsg/sys_reqs.rst
@@ -200,6 +200,12 @@ On a NUMA machine, pages should be allocated explicitly on separate nodes::
 
     For 1G pages, it is not possible to reserve the hugepage memory after the system has booted.
 
+    On IBM POWER system, the nr_overcommit_hugepages should be set to the same value as nr_hugepages.
+    For example, if the required page number is 128, the following commands are used::
+
+        echo 128 > /sys/kernel/mm/hugepages/hugepages-16384kB/nr_hugepages
+        echo 128 > /sys/kernel/mm/hugepages/hugepages-16384kB/nr_overcommit_hugepages
+
 Using Hugepages with the DPDK
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 90cc3224be85..618a09b429bc 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -331,7 +331,13 @@ get_virtual_area(size_t *size, size_t hugepage_sz)
 	}
 	do {
 		addr = mmap(addr,
-				(*size) + hugepage_sz, PROT_READ, MAP_PRIVATE, fd, 0);
+				(*size) + hugepage_sz, PROT_READ,
+#ifdef RTE_ARCH_PPC_64
+				MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
+#else
+				MAP_PRIVATE,
+#endif
+				fd, 0);
 		if (addr == MAP_FAILED)
 			*size -= hugepage_sz;
 	} while (addr == MAP_FAILED && *size > 0);
@@ -1359,7 +1365,13 @@ rte_eal_hugepage_attach(void)
 		 * use mmap to get identical addresses as the primary process.
 		 */
 		base_addr = mmap(mcfg->memseg[s].addr, mcfg->memseg[s].len,
-				 PROT_READ, MAP_PRIVATE, fd_zero, 0);
+				 PROT_READ,
+#ifdef RTE_ARCH_PPC_64
+				 MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
+#else
+				 MAP_PRIVATE,
+#endif
+				 fd_zero, 0);
 		if (base_addr == MAP_FAILED ||
 		    base_addr != mcfg->memseg[s].addr) {
 			max_seg = s;
-- 
2.9.4