[dpdk-dev,v2,18/41] test: fix malloc autotest to support memory hotplug

Message ID ed78c352e05e38b66ac3c5f0a00f31ec5d978fa7.1520428025.git.anatoly.burakov@intel.com (mailing list archive)
State Superseded, archived
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Burakov, Anatoly March 7, 2018, 4:56 p.m. UTC
  The test was expecting memory already being allocated on all sockets,
and thus was failing because calling rte_malloc could trigger memory
hotplug event and allocate memory where there was none before.

Fix it to instead report availability of memory on specific sockets
by attempting to allocate a page and see if that succeeds. Technically,
this can still cause failure as memory might not be available at the
time of check, but become available by the time the test is run, but
this is a corner case not worth considering.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 test/test/test_malloc.c | 52 +++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 44 insertions(+), 8 deletions(-)
  

Patch

diff --git a/test/test/test_malloc.c b/test/test/test_malloc.c
index 8484fb6..2aaf1b8 100644
--- a/test/test/test_malloc.c
+++ b/test/test/test_malloc.c
@@ -22,6 +22,8 @@ 
 #include <rte_random.h>
 #include <rte_string_fns.h>
 
+#include "../../lib/librte_eal/common/eal_memalloc.h"
+
 #include "test.h"
 
 #define N 10000
@@ -708,22 +710,56 @@  test_malloc_bad_params(void)
 
 /* Check if memory is avilable on a specific socket */
 static int
-is_mem_on_socket(int32_t socket)
+is_mem_on_socket(unsigned int socket)
 {
+	struct rte_malloc_socket_stats stats;
 	const struct rte_mem_config *mcfg =
 			rte_eal_get_configuration()->mem_config;
-	unsigned i;
+	uint64_t prev_pgsz;
+	unsigned int i;
+
+	/* we cannot know if there's memory on a specific socket, since it might
+	 * be available, but not yet allocated. so, in addition to checking
+	 * already mapped memory, we will attempt to allocate a page from that
+	 * socket and see if it works.
+	 */
+	if (socket >= rte_num_sockets())
+		return 0;
 
+	rte_malloc_get_socket_stats(socket, &stats);
+
+	/* if heap has memory allocated, stop */
+	if (stats.heap_totalsz_bytes > 0)
+		return 1;
+
+	/* to allocate a page, we will have to know its size, so go through all
+	 * supported page sizes and try with each one.
+	 */
+	prev_pgsz = 0;
 	for (i = 0; i < RTE_MAX_MEMSEG_LISTS; i++) {
-		const struct rte_memseg_list *msl =
-				&mcfg->memsegs[i];
-		const struct rte_fbarray *arr = &msl->memseg_arr;
+		const struct rte_memseg_list *msl = &mcfg->memsegs[i];
+		uint64_t page_sz;
 
-		if (msl->socket_id != socket)
+		/* skip unused memseg lists */
+		if (msl->memseg_arr.len == 0)
 			continue;
+		page_sz = msl->hugepage_sz;
 
-		if (arr->count)
-			return 1;
+		/* skip page sizes we've tried already */
+		if (prev_pgsz == page_sz)
+			continue;
+
+		prev_pgsz = page_sz;
+
+		struct rte_memseg *ms = eal_memalloc_alloc_page(page_sz,
+				socket);
+
+		if (ms == NULL)
+			continue;
+
+		eal_memalloc_free_page(ms);
+
+		return 1;
 	}
 	return 0;
 }