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

Anatoly Burakov anatoly.burakov at intel.com
Sat Mar 3 14:46:06 CET 2018


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 at intel.com>
---
 test/test/test_malloc.c | 52 +++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 44 insertions(+), 8 deletions(-)

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;
 }
-- 
2.7.4


More information about the dev mailing list