[dpdk-dev,18/41] test: fix malloc autotest to support memory hotplug
Checks
Commit Message
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(-)
Comments
On Sat, Mar 03, 2018 at 01:46:06PM +0000, Anatoly Burakov wrote:
> 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(-)
>
> 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"
> +
I guess there is no way to test without importing a private EAL
function, correct? If yes, maybe it deserves a quick explanation.
@@ -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;
}