197f17497SC.J. Collier/*-
297f17497SC.J. Collier *   BSD LICENSE
397f17497SC.J. Collier *
497f17497SC.J. Collier *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
597f17497SC.J. Collier *   All rights reserved.
697f17497SC.J. Collier *
797f17497SC.J. Collier *   Redistribution and use in source and binary forms, with or without
897f17497SC.J. Collier *   modification, are permitted provided that the following conditions
997f17497SC.J. Collier *   are met:
1097f17497SC.J. Collier *
1197f17497SC.J. Collier *     * Redistributions of source code must retain the above copyright
1297f17497SC.J. Collier *       notice, this list of conditions and the following disclaimer.
1397f17497SC.J. Collier *     * Redistributions in binary form must reproduce the above copyright
1497f17497SC.J. Collier *       notice, this list of conditions and the following disclaimer in
1597f17497SC.J. Collier *       the documentation and/or other materials provided with the
1697f17497SC.J. Collier *       distribution.
1797f17497SC.J. Collier *     * Neither the name of Intel Corporation nor the names of its
1897f17497SC.J. Collier *       contributors may be used to endorse or promote products derived
1997f17497SC.J. Collier *       from this software without specific prior written permission.
2097f17497SC.J. Collier *
2197f17497SC.J. Collier *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2297f17497SC.J. Collier *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2397f17497SC.J. Collier *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2497f17497SC.J. Collier *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2597f17497SC.J. Collier *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2697f17497SC.J. Collier *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2797f17497SC.J. Collier *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2897f17497SC.J. Collier *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2997f17497SC.J. Collier *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3097f17497SC.J. Collier *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3197f17497SC.J. Collier *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3297f17497SC.J. Collier */
3397f17497SC.J. Collier
3497f17497SC.J. Collier#include <stdio.h>
3597f17497SC.J. Collier#include <stdint.h>
3639157ec0SLuca Boccassi#include <string.h>
3797f17497SC.J. Collier#include <inttypes.h>
3897f17497SC.J. Collier#include <sys/queue.h>
3997f17497SC.J. Collier
4097f17497SC.J. Collier#include <rte_random.h>
4197f17497SC.J. Collier#include <rte_cycles.h>
4297f17497SC.J. Collier#include <rte_memory.h>
4397f17497SC.J. Collier#include <rte_memzone.h>
4497f17497SC.J. Collier#include <rte_eal.h>
4597f17497SC.J. Collier#include <rte_eal_memconfig.h>
4697f17497SC.J. Collier#include <rte_common.h>
4797f17497SC.J. Collier#include <rte_string_fns.h>
4897f17497SC.J. Collier#include <rte_errno.h>
4997f17497SC.J. Collier#include <rte_malloc.h>
5097f17497SC.J. Collier#include "../../lib/librte_eal/common/malloc_elem.h"
5197f17497SC.J. Collier
5297f17497SC.J. Collier#include "test.h"
5397f17497SC.J. Collier
5497f17497SC.J. Collier/*
5597f17497SC.J. Collier * Memzone
5697f17497SC.J. Collier * =======
5797f17497SC.J. Collier *
5897f17497SC.J. Collier * - Search for three reserved zones or reserve them if they do not exist:
5997f17497SC.J. Collier *
6097f17497SC.J. Collier *   - One is on any socket id.
6197f17497SC.J. Collier *   - The second is on socket 0.
6297f17497SC.J. Collier *   - The last one is on socket 1 (if socket 1 exists).
6397f17497SC.J. Collier *
6497f17497SC.J. Collier * - Check that the zones exist.
6597f17497SC.J. Collier *
6697f17497SC.J. Collier * - Check that the zones are cache-aligned.
6797f17497SC.J. Collier *
6897f17497SC.J. Collier * - Check that zones do not overlap.
6997f17497SC.J. Collier *
7097f17497SC.J. Collier * - Check that the zones are on the correct socket id.
7197f17497SC.J. Collier *
7297f17497SC.J. Collier * - Check that a lookup of the first zone returns the same pointer.
7397f17497SC.J. Collier *
7497f17497SC.J. Collier * - Check that it is not possible to create another zone with the
7597f17497SC.J. Collier *   same name as an existing zone.
7697f17497SC.J. Collier *
7797f17497SC.J. Collier * - Check flags for specific huge page size reservation
7897f17497SC.J. Collier */
7997f17497SC.J. Collier
8039157ec0SLuca Boccassi#define TEST_MEMZONE_NAME(suffix) "MZ_TEST_" suffix
8139157ec0SLuca Boccassi
8297f17497SC.J. Collier/* Test if memory overlaps: return 1 if true, or 0 if false. */
8397f17497SC.J. Collierstatic int
8497f17497SC.J. Collieris_memory_overlap(phys_addr_t ptr1, size_t len1, phys_addr_t ptr2, size_t len2)
8597f17497SC.J. Collier{
8697f17497SC.J. Collier	if (ptr2 >= ptr1 && (ptr2 - ptr1) < len1)
8797f17497SC.J. Collier		return 1;
8897f17497SC.J. Collier	else if (ptr2 < ptr1 && (ptr1 - ptr2) < len2)
8997f17497SC.J. Collier		return 1;
9097f17497SC.J. Collier	return 0;
9197f17497SC.J. Collier}
9297f17497SC.J. Collier
9397f17497SC.J. Collierstatic int
9497f17497SC.J. Colliertest_memzone_invalid_alignment(void)
9597f17497SC.J. Collier{
9697f17497SC.J. Collier	const struct rte_memzone * mz;
9797f17497SC.J. Collier
9839157ec0SLuca Boccassi	mz = rte_memzone_lookup(TEST_MEMZONE_NAME("invalid_alignment"));
9997f17497SC.J. Collier	if (mz != NULL) {
10097f17497SC.J. Collier		printf("Zone with invalid alignment has been reserved\n");
10197f17497SC.J. Collier		return -1;
10297f17497SC.J. Collier	}
10397f17497SC.J. Collier
10439157ec0SLuca Boccassi	mz = rte_memzone_reserve_aligned(TEST_MEMZONE_NAME("invalid_alignment"),
10539157ec0SLuca Boccassi					 100, SOCKET_ID_ANY, 0, 100);
10697f17497SC.J. Collier	if (mz != NULL) {
10797f17497SC.J. Collier		printf("Zone with invalid alignment has been reserved\n");
10897f17497SC.J. Collier		return -1;
10997f17497SC.J. Collier	}
11097f17497SC.J. Collier	return 0;
11197f17497SC.J. Collier}
11297f17497SC.J. Collier
11397f17497SC.J. Collierstatic int
11497f17497SC.J. Colliertest_memzone_reserving_zone_size_bigger_than_the_maximum(void)
11597f17497SC.J. Collier{
11697f17497SC.J. Collier	const struct rte_memzone * mz;
11797f17497SC.J. Collier
11839157ec0SLuca Boccassi	mz = rte_memzone_lookup(
11939157ec0SLuca Boccassi			TEST_MEMZONE_NAME("zone_size_bigger_than_the_maximum"));
12097f17497SC.J. Collier	if (mz != NULL) {
12197f17497SC.J. Collier		printf("zone_size_bigger_than_the_maximum has been reserved\n");
12297f17497SC.J. Collier		return -1;
12397f17497SC.J. Collier	}
12497f17497SC.J. Collier
12539157ec0SLuca Boccassi	mz = rte_memzone_reserve(
12639157ec0SLuca Boccassi			TEST_MEMZONE_NAME("zone_size_bigger_than_the_maximum"),
12739157ec0SLuca Boccassi			(size_t)-1, SOCKET_ID_ANY, 0);
12897f17497SC.J. Collier	if (mz != NULL) {
12997f17497SC.J. Collier		printf("It is impossible to reserve such big a memzone\n");
13097f17497SC.J. Collier		return -1;
13197f17497SC.J. Collier	}
13297f17497SC.J. Collier
13397f17497SC.J. Collier	return 0;
13497f17497SC.J. Collier}
13597f17497SC.J. Collier
13697f17497SC.J. Collierstatic int
13797f17497SC.J. Colliertest_memzone_reserve_flags(void)
13897f17497SC.J. Collier{
13997f17497SC.J. Collier	const struct rte_memzone *mz;
14097f17497SC.J. Collier	const struct rte_memseg *ms;
14197f17497SC.J. Collier	int hugepage_2MB_avail = 0;
14297f17497SC.J. Collier	int hugepage_1GB_avail = 0;
14397f17497SC.J. Collier	int hugepage_16MB_avail = 0;
14497f17497SC.J. Collier	int hugepage_16GB_avail = 0;
14597f17497SC.J. Collier	const size_t size = 100;
14697f17497SC.J. Collier	int i = 0;
14797f17497SC.J. Collier	ms = rte_eal_get_physmem_layout();
14897f17497SC.J. Collier	for (i = 0; i < RTE_MAX_MEMSEG; i++) {
14997f17497SC.J. Collier		if (ms[i].hugepage_sz == RTE_PGSIZE_2M)
15097f17497SC.J. Collier			hugepage_2MB_avail = 1;
15197f17497SC.J. Collier		if (ms[i].hugepage_sz == RTE_PGSIZE_1G)
15297f17497SC.J. Collier			hugepage_1GB_avail = 1;
15397f17497SC.J. Collier		if (ms[i].hugepage_sz == RTE_PGSIZE_16M)
15497f17497SC.J. Collier			hugepage_16MB_avail = 1;
15597f17497SC.J. Collier		if (ms[i].hugepage_sz == RTE_PGSIZE_16G)
15697f17497SC.J. Collier			hugepage_16GB_avail = 1;
15797f17497SC.J. Collier	}
15897f17497SC.J. Collier	/* Display the availability of 2MB ,1GB, 16MB, 16GB pages */
15997f17497SC.J. Collier	if (hugepage_2MB_avail)
16097f17497SC.J. Collier		printf("2MB Huge pages available\n");
16197f17497SC.J. Collier	if (hugepage_1GB_avail)
16297f17497SC.J. Collier		printf("1GB Huge pages available\n");
16397f17497SC.J. Collier	if (hugepage_16MB_avail)
16497f17497SC.J. Collier		printf("16MB Huge pages available\n");
16597f17497SC.J. Collier	if (hugepage_16GB_avail)
16697f17497SC.J. Collier		printf("16GB Huge pages available\n");
16797f17497SC.J. Collier	/*
16897f17497SC.J. Collier	 * If 2MB pages available, check that a small memzone is correctly
16997f17497SC.J. Collier	 * reserved from 2MB huge pages when requested by the RTE_MEMZONE_2MB flag.
17097f17497SC.J. Collier	 * Also check that RTE_MEMZONE_SIZE_HINT_ONLY flag only defaults to an
17197f17497SC.J. Collier	 * available page size (i.e 1GB ) when 2MB pages are unavailable.
17297f17497SC.J. Collier	 */
17397f17497SC.J. Collier	if (hugepage_2MB_avail) {
17439157ec0SLuca Boccassi		mz = rte_memzone_reserve(TEST_MEMZONE_NAME("flag_zone_2M"),
17539157ec0SLuca Boccassi				size, SOCKET_ID_ANY, RTE_MEMZONE_2MB);
17697f17497SC.J. Collier		if (mz == NULL) {
17797f17497SC.J. Collier			printf("MEMZONE FLAG 2MB\n");
17897f17497SC.J. Collier			return -1;
17997f17497SC.J. Collier		}
18097f17497SC.J. Collier		if (mz->hugepage_sz != RTE_PGSIZE_2M) {
18197f17497SC.J. Collier			printf("hugepage_sz not equal 2M\n");
18297f17497SC.J. Collier			return -1;
18397f17497SC.J. Collier		}
18447d9763aSLuca Boccassi		if (rte_memzone_free(mz)) {
18547d9763aSLuca Boccassi			printf("Fail memzone free\n");
18647d9763aSLuca Boccassi			return -1;
18747d9763aSLuca Boccassi		}
18897f17497SC.J. Collier
18939157ec0SLuca Boccassi		mz = rte_memzone_reserve(TEST_MEMZONE_NAME("flag_zone_2M_HINT"),
19039157ec0SLuca Boccassi				size, SOCKET_ID_ANY,
19197f17497SC.J. Collier				RTE_MEMZONE_2MB|RTE_MEMZONE_SIZE_HINT_ONLY);
19297f17497SC.J. Collier		if (mz == NULL) {
19397f17497SC.J. Collier			printf("MEMZONE FLAG 2MB\n");
19497f17497SC.J. Collier			return -1;
19597f17497SC.J. Collier		}
19697f17497SC.J. Collier		if (mz->hugepage_sz != RTE_PGSIZE_2M) {
19797f17497SC.J. Collier			printf("hugepage_sz not equal 2M\n");
19897f17497SC.J. Collier			return -1;
19997f17497SC.J. Collier		}
20047d9763aSLuca Boccassi		if (rte_memzone_free(mz)) {
20147d9763aSLuca Boccassi			printf("Fail memzone free\n");
20247d9763aSLuca Boccassi			return -1;
20347d9763aSLuca Boccassi		}
20497f17497SC.J. Collier
20597f17497SC.J. Collier		/* Check if 1GB huge pages are unavailable, that function fails unless
20697f17497SC.J. Collier		 * HINT flag is indicated
20797f17497SC.J. Collier		 */
20897f17497SC.J. Collier		if (!hugepage_1GB_avail) {
20939157ec0SLuca Boccassi			mz = rte_memzone_reserve(
21039157ec0SLuca Boccassi					TEST_MEMZONE_NAME("flag_zone_1G_HINT"),
21139157ec0SLuca Boccassi					size, SOCKET_ID_ANY,
21297f17497SC.J. Collier					RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY);
21397f17497SC.J. Collier			if (mz == NULL) {
21497f17497SC.J. Collier				printf("MEMZONE FLAG 1GB & HINT\n");
21597f17497SC.J. Collier				return -1;
21697f17497SC.J. Collier			}
21797f17497SC.J. Collier			if (mz->hugepage_sz != RTE_PGSIZE_2M) {
21897f17497SC.J. Collier				printf("hugepage_sz not equal 2M\n");
21997f17497SC.J. Collier				return -1;
22097f17497SC.J. Collier			}
22147d9763aSLuca Boccassi			if (rte_memzone_free(mz)) {
22247d9763aSLuca Boccassi				printf("Fail memzone free\n");
22347d9763aSLuca Boccassi				return -1;
22447d9763aSLuca Boccassi			}
22597f17497SC.J. Collier
22639157ec0SLuca Boccassi			mz = rte_memzone_reserve(
22739157ec0SLuca Boccassi					TEST_MEMZONE_NAME("flag_zone_1G"), size,
22839157ec0SLuca Boccassi					SOCKET_ID_ANY, RTE_MEMZONE_1GB);
22997f17497SC.J. Collier			if (mz != NULL) {
23097f17497SC.J. Collier				printf("MEMZONE FLAG 1GB\n");
23197f17497SC.J. Collier				return -1;
23297f17497SC.J. Collier			}
23397f17497SC.J. Collier		}
23497f17497SC.J. Collier	}
23597f17497SC.J. Collier
23697f17497SC.J. Collier	/*As with 2MB tests above for 1GB huge page requests*/
23797f17497SC.J. Collier	if (hugepage_1GB_avail) {
23839157ec0SLuca Boccassi		mz = rte_memzone_reserve(TEST_MEMZONE_NAME("flag_zone_1G"),
23939157ec0SLuca Boccassi				size, SOCKET_ID_ANY, RTE_MEMZONE_1GB);
24097f17497SC.J. Collier		if (mz == NULL) {
24197f17497SC.J. Collier			printf("MEMZONE FLAG 1GB\n");
24297f17497SC.J. Collier			return -1;
24397f17497SC.J. Collier		}
24497f17497SC.J. Collier		if (mz->hugepage_sz != RTE_PGSIZE_1G) {
24597f17497SC.J. Collier			printf("hugepage_sz not equal 1G\n");
24697f17497SC.J. Collier			return -1;
24797f17497SC.J. Collier		}
24847d9763aSLuca Boccassi		if (rte_memzone_free(mz)) {
24947d9763aSLuca Boccassi			printf("Fail memzone free\n");
25047d9763aSLuca Boccassi			return -1;
25147d9763aSLuca Boccassi		}
25297f17497SC.J. Collier
25339157ec0SLuca Boccassi		mz = rte_memzone_reserve(TEST_MEMZONE_NAME("flag_zone_1G_HINT"),
25439157ec0SLuca Boccassi				size, SOCKET_ID_ANY,
25597f17497SC.J. Collier				RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY);
25697f17497SC.J. Collier		if (mz == NULL) {
25797f17497SC.J. Collier			printf("MEMZONE FLAG 1GB\n");
25897f17497SC.J. Collier			return -1;
25997f17497SC.J. Collier		}
26097f17497SC.J. Collier		if (mz->hugepage_sz != RTE_PGSIZE_1G) {
26197f17497SC.J. Collier			printf("hugepage_sz not equal 1G\n");
26297f17497SC.J. Collier			return -1;
26397f17497SC.J. Collier		}
26447d9763aSLuca Boccassi		if (rte_memzone_free(mz)) {
26547d9763aSLuca Boccassi			printf("Fail memzone free\n");
26647d9763aSLuca Boccassi			return -1;
26747d9763aSLuca Boccassi		}
26897f17497SC.J. Collier
26997f17497SC.J. Collier		/* Check if 1GB huge pages are unavailable, that function fails unless
27097f17497SC.J. Collier		 * HINT flag is indicated
27197f17497SC.J. Collier		 */
27297f17497SC.J. Collier		if (!hugepage_2MB_avail) {
27339157ec0SLuca Boccassi			mz = rte_memzone_reserve(
27439157ec0SLuca Boccassi					TEST_MEMZONE_NAME("flag_zone_2M_HINT"),
27539157ec0SLuca Boccassi					size, SOCKET_ID_ANY,
27697f17497SC.J. Collier					RTE_MEMZONE_2MB|RTE_MEMZONE_SIZE_HINT_ONLY);
27797f17497SC.J. Collier			if (mz == NULL){
27897f17497SC.J. Collier				printf("MEMZONE FLAG 2MB & HINT\n");
27997f17497SC.J. Collier				return -1;
28097f17497SC.J. Collier			}
28197f17497SC.J. Collier			if (mz->hugepage_sz != RTE_PGSIZE_1G) {
28297f17497SC.J. Collier				printf("hugepage_sz not equal 1G\n");
28397f17497SC.J. Collier				return -1;
28497f17497SC.J. Collier			}
28547d9763aSLuca Boccassi			if (rte_memzone_free(mz)) {
28647d9763aSLuca Boccassi				printf("Fail memzone free\n");
28747d9763aSLuca Boccassi				return -1;
28847d9763aSLuca Boccassi			}
28939157ec0SLuca Boccassi			mz = rte_memzone_reserve(
29039157ec0SLuca Boccassi					TEST_MEMZONE_NAME("flag_zone_2M"), size,
29139157ec0SLuca Boccassi					SOCKET_ID_ANY, RTE_MEMZONE_2MB);
29297f17497SC.J. Collier			if (mz != NULL) {
29397f17497SC.J. Collier				printf("MEMZONE FLAG 2MB\n");
29497f17497SC.J. Collier				return -1;
29597f17497SC.J. Collier			}
29697f17497SC.J. Collier		}
29797f17497SC.J. Collier
29897f17497SC.J. Collier		if (hugepage_2MB_avail && hugepage_1GB_avail) {
29939157ec0SLuca Boccassi			mz = rte_memzone_reserve(
30039157ec0SLuca Boccassi					TEST_MEMZONE_NAME("flag_zone_2M_HINT"),
30139157ec0SLuca Boccassi					size, SOCKET_ID_ANY,
30239157ec0SLuca Boccassi					RTE_MEMZONE_2MB|RTE_MEMZONE_1GB);
30339157ec0SLuca Boccassi			if (mz == NULL) {
30497f17497SC.J. Collier				printf("BOTH SIZES SET\n");
30597f17497SC.J. Collier				return -1;
30697f17497SC.J. Collier			}
30739157ec0SLuca Boccassi			if (mz->hugepage_sz != RTE_PGSIZE_1G &&
30839157ec0SLuca Boccassi					mz->hugepage_sz != RTE_PGSIZE_2M) {
30939157ec0SLuca Boccassi				printf("Wrong size when both sizes set\n");
31039157ec0SLuca Boccassi				return -1;
31139157ec0SLuca Boccassi			}
31239157ec0SLuca Boccassi			if (rte_memzone_free(mz)) {
31339157ec0SLuca Boccassi				printf("Fail memzone free\n");
31439157ec0SLuca Boccassi				return -1;
31539157ec0SLuca Boccassi			}
31697f17497SC.J. Collier		}
31797f17497SC.J. Collier	}
31897f17497SC.J. Collier	/*
31997f17497SC.J. Collier	 * This option is for IBM Power. If 16MB pages available, check
32097f17497SC.J. Collier	 * that a small memzone is correctly reserved from 16MB huge pages
32197f17497SC.J. Collier	 * when requested by the RTE_MEMZONE_16MB flag. Also check that
32297f17497SC.J. Collier	 * RTE_MEMZONE_SIZE_HINT_ONLY flag only defaults to an available
32397f17497SC.J. Collier	 * page size (i.e 16GB ) when 16MB pages are unavailable.
32497f17497SC.J. Collier	 */
32597f17497SC.J. Collier	if (hugepage_16MB_avail) {
32639157ec0SLuca Boccassi		mz = rte_memzone_reserve(TEST_MEMZONE_NAME("flag_zone_16M"),
32739157ec0SLuca Boccassi				size, SOCKET_ID_ANY, RTE_MEMZONE_16MB);
32897f17497SC.J. Collier		if (mz == NULL) {
32997f17497SC.J. Collier			printf("MEMZONE FLAG 16MB\n");
33097f17497SC.J. Collier			return -1;
33197f17497SC.J. Collier		}
33297f17497SC.J. Collier		if (mz->hugepage_sz != RTE_PGSIZE_16M) {
33397f17497SC.J. Collier			printf("hugepage_sz not equal 16M\n");
33497f17497SC.J. Collier			return -1;
33597f17497SC.J. Collier		}
33647d9763aSLuca Boccassi		if (rte_memzone_free(mz)) {
33747d9763aSLuca Boccassi			printf("Fail memzone free\n");
33847d9763aSLuca Boccassi			return -1;
33947d9763aSLuca Boccassi		}
34097f17497SC.J. Collier
34139157ec0SLuca Boccassi		mz = rte_memzone_reserve(
34239157ec0SLuca Boccassi				TEST_MEMZONE_NAME("flag_zone_16M_HINT"), size,
34339157ec0SLuca Boccassi				SOCKET_ID_ANY,
34439157ec0SLuca Boccassi				RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY);
34597f17497SC.J. Collier		if (mz == NULL) {
34697f17497SC.J. Collier			printf("MEMZONE FLAG 2MB\n");
34797f17497SC.J. Collier			return -1;
34897f17497SC.J. Collier		}
34997f17497SC.J. Collier		if (mz->hugepage_sz != RTE_PGSIZE_16M) {
35097f17497SC.J. Collier			printf("hugepage_sz not equal 16M\n");
35197f17497SC.J. Collier			return -1;
35297f17497SC.J. Collier		}
35347d9763aSLuca Boccassi		if (rte_memzone_free(mz)) {
35447d9763aSLuca Boccassi			printf("Fail memzone free\n");
35547d9763aSLuca Boccassi			return -1;
35647d9763aSLuca Boccassi		}
35797f17497SC.J. Collier
35897f17497SC.J. Collier		/* Check if 1GB huge pages are unavailable, that function fails
35997f17497SC.J. Collier		 * unless HINT flag is indicated
36097f17497SC.J. Collier		 */
36197f17497SC.J. Collier		if (!hugepage_16GB_avail) {
36239157ec0SLuca Boccassi			mz = rte_memzone_reserve(
36339157ec0SLuca Boccassi					TEST_MEMZONE_NAME("flag_zone_16G_HINT"),
36439157ec0SLuca Boccassi					size, SOCKET_ID_ANY,
36539157ec0SLuca Boccassi					RTE_MEMZONE_16GB |
36639157ec0SLuca Boccassi					RTE_MEMZONE_SIZE_HINT_ONLY);
36797f17497SC.J. Collier			if (mz == NULL) {
36897f17497SC.J. Collier				printf("MEMZONE FLAG 16GB & HINT\n");
36997f17497SC.J. Collier				return -1;
37097f17497SC.J. Collier			}
37197f17497SC.J. Collier			if (mz->hugepage_sz != RTE_PGSIZE_16M) {
37297f17497SC.J. Collier				printf("hugepage_sz not equal 16M\n");
37397f17497SC.J. Collier				return -1;
37497f17497SC.J. Collier			}
37547d9763aSLuca Boccassi			if (rte_memzone_free(mz)) {
37647d9763aSLuca Boccassi				printf("Fail memzone free\n");
37747d9763aSLuca Boccassi				return -1;
37847d9763aSLuca Boccassi			}
37997f17497SC.J. Collier
38039157ec0SLuca Boccassi			mz = rte_memzone_reserve(
38139157ec0SLuca Boccassi					TEST_MEMZONE_NAME("flag_zone_16G"),
38239157ec0SLuca Boccassi					size,
38339157ec0SLuca Boccassi					SOCKET_ID_ANY, RTE_MEMZONE_16GB);
38497f17497SC.J. Collier			if (mz != NULL) {
38597f17497SC.J. Collier				printf("MEMZONE FLAG 16GB\n");
38697f17497SC.J. Collier				return -1;
38797f17497SC.J. Collier			}
38897f17497SC.J. Collier		}
38997f17497SC.J. Collier	}
39097f17497SC.J. Collier	/*As with 16MB tests above for 16GB huge page requests*/
39197f17497SC.J. Collier	if (hugepage_16GB_avail) {
39239157ec0SLuca Boccassi		mz = rte_memzone_reserve(TEST_MEMZONE_NAME("flag_zone_16G"),
39339157ec0SLuca Boccassi				size, SOCKET_ID_ANY, RTE_MEMZONE_16GB);
39497f17497SC.J. Collier		if (mz == NULL) {
39597f17497SC.J. Collier			printf("MEMZONE FLAG 16GB\n");
39697f17497SC.J. Collier			return -1;
39797f17497SC.J. Collier		}
39897f17497SC.J. Collier		if (mz->hugepage_sz != RTE_PGSIZE_16G) {
39997f17497SC.J. Collier			printf("hugepage_sz not equal 16G\n");
40097f17497SC.J. Collier			return -1;
40197f17497SC.J. Collier		}
40247d9763aSLuca Boccassi		if (rte_memzone_free(mz)) {
40347d9763aSLuca Boccassi			printf("Fail memzone free\n");
40447d9763aSLuca Boccassi			return -1;
40547d9763aSLuca Boccassi		}
40697f17497SC.J. Collier
40739157ec0SLuca Boccassi		mz = rte_memzone_reserve(
40839157ec0SLuca Boccassi				TEST_MEMZONE_NAME("flag_zone_16G_HINT"), size,
40939157ec0SLuca Boccassi				SOCKET_ID_ANY,
41039157ec0SLuca Boccassi				RTE_MEMZONE_16GB|RTE_MEMZONE_SIZE_HINT_ONLY);
41197f17497SC.J. Collier		if (mz == NULL) {
41297f17497SC.J. Collier			printf("MEMZONE FLAG 16GB\n");
41397f17497SC.J. Collier			return -1;
41497f17497SC.J. Collier		}
41597f17497SC.J. Collier		if (mz->hugepage_sz != RTE_PGSIZE_16G) {
41697f17497SC.J. Collier			printf("hugepage_sz not equal 16G\n");
41797f17497SC.J. Collier			return -1;
41897f17497SC.J. Collier		}
41947d9763aSLuca Boccassi		if (rte_memzone_free(mz)) {
42047d9763aSLuca Boccassi			printf("Fail memzone free\n");
42147d9763aSLuca Boccassi			return -1;
42247d9763aSLuca Boccassi		}
42397f17497SC.J. Collier
42497f17497SC.J. Collier		/* Check if 1GB huge pages are unavailable, that function fails
42597f17497SC.J. Collier		 * unless HINT flag is indicated
42697f17497SC.J. Collier		 */
42797f17497SC.J. Collier		if (!hugepage_16MB_avail) {
42839157ec0SLuca Boccassi			mz = rte_memzone_reserve(
42939157ec0SLuca Boccassi					TEST_MEMZONE_NAME("flag_zone_16M_HINT"),
43039157ec0SLuca Boccassi					size, SOCKET_ID_ANY,
43139157ec0SLuca Boccassi					RTE_MEMZONE_16MB |
43239157ec0SLuca Boccassi					RTE_MEMZONE_SIZE_HINT_ONLY);
43397f17497SC.J. Collier			if (mz == NULL) {
43497f17497SC.J. Collier				printf("MEMZONE FLAG 16MB & HINT\n");
43597f17497SC.J. Collier				return -1;
43697f17497SC.J. Collier			}
43797f17497SC.J. Collier			if (mz->hugepage_sz != RTE_PGSIZE_16G) {
43897f17497SC.J. Collier				printf("hugepage_sz not equal 16G\n");
43997f17497SC.J. Collier				return -1;
44097f17497SC.J. Collier			}
44147d9763aSLuca Boccassi			if (rte_memzone_free(mz)) {
44247d9763aSLuca Boccassi				printf("Fail memzone free\n");
44347d9763aSLuca Boccassi				return -1;
44447d9763aSLuca Boccassi			}
44539157ec0SLuca Boccassi			mz = rte_memzone_reserve(
44639157ec0SLuca Boccassi					TEST_MEMZONE_NAME("flag_zone_16M"),
44739157ec0SLuca Boccassi					size, SOCKET_ID_ANY, RTE_MEMZONE_16MB);
44897f17497SC.J. Collier			if (mz != NULL) {
44997f17497SC.J. Collier				printf("MEMZONE FLAG 16MB\n");
45097f17497SC.J. Collier				return -1;
45197f17497SC.J. Collier			}
45297f17497SC.J. Collier		}
45397f17497SC.J. Collier
45497f17497SC.J. Collier		if (hugepage_16MB_avail && hugepage_16GB_avail) {
45539157ec0SLuca Boccassi			mz = rte_memzone_reserve(
45639157ec0SLuca Boccassi					TEST_MEMZONE_NAME("flag_zone_16M_HINT"),
45739157ec0SLuca Boccassi					size, SOCKET_ID_ANY,
45839157ec0SLuca Boccassi					RTE_MEMZONE_16MB|RTE_MEMZONE_16GB);
45939157ec0SLuca Boccassi			if (mz == NULL) {
46097f17497SC.J. Collier				printf("BOTH SIZES SET\n");
46197f17497SC.J. Collier				return -1;
46297f17497SC.J. Collier			}
46339157ec0SLuca Boccassi			if (mz->hugepage_sz != RTE_PGSIZE_16G &&
46439157ec0SLuca Boccassi					mz->hugepage_sz != RTE_PGSIZE_16M) {
46539157ec0SLuca Boccassi				printf("Wrong size when both sizes set\n");
46639157ec0SLuca Boccassi				return -1;
46739157ec0SLuca Boccassi			}
46839157ec0SLuca Boccassi			if (rte_memzone_free(mz)) {
46939157ec0SLuca Boccassi				printf("Fail memzone free\n");
47039157ec0SLuca Boccassi				return -1;
47139157ec0SLuca Boccassi			}
47297f17497SC.J. Collier		}
47397f17497SC.J. Collier	}
47497f17497SC.J. Collier	return 0;
47597f17497SC.J. Collier}
47697f17497SC.J. Collier
47797f17497SC.J. Collier
47897f17497SC.J. Collier/* Find the heap with the greatest free block size */
47997f17497SC.J. Collierstatic size_t
48097f17497SC.J. Collierfind_max_block_free_size(const unsigned _align)
48197f17497SC.J. Collier{
48297f17497SC.J. Collier	struct rte_malloc_socket_stats stats;
48397f17497SC.J. Collier	unsigned i, align = _align;
48497f17497SC.J. Collier	size_t len = 0;
48597f17497SC.J. Collier
48697f17497SC.J. Collier	for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
48797f17497SC.J. Collier		rte_malloc_get_socket_stats(i, &stats);
48897f17497SC.J. Collier		if (stats.greatest_free_size > len)
48997f17497SC.J. Collier			len = stats.greatest_free_size;
49097f17497SC.J. Collier	}
49197f17497SC.J. Collier
49297f17497SC.J. Collier	if (align < RTE_CACHE_LINE_SIZE)
49397f17497SC.J. Collier		align = RTE_CACHE_LINE_ROUNDUP(align+1);
49497f17497SC.J. Collier
49597f17497SC.J. Collier	if (len <= MALLOC_ELEM_OVERHEAD + align)
49697f17497SC.J. Collier		return 0;
49797f17497SC.J. Collier
49897f17497SC.J. Collier	return len - MALLOC_ELEM_OVERHEAD - align;
49997f17497SC.J. Collier}
50097f17497SC.J. Collier
50197f17497SC.J. Collierstatic int
50297f17497SC.J. Colliertest_memzone_reserve_max(void)
50397f17497SC.J. Collier{
50497f17497SC.J. Collier	const struct rte_memzone *mz;
50597f17497SC.J. Collier	size_t maxlen;
50697f17497SC.J. Collier
50797f17497SC.J. Collier	maxlen = find_max_block_free_size(0);
50897f17497SC.J. Collier
50997f17497SC.J. Collier	if (maxlen == 0) {
51097f17497SC.J. Collier		printf("There is no space left!\n");
51197f17497SC.J. Collier		return 0;
51297f17497SC.J. Collier	}
51397f17497SC.J. Collier
51439157ec0SLuca Boccassi	mz = rte_memzone_reserve(TEST_MEMZONE_NAME("max_zone"), 0,
51539157ec0SLuca Boccassi			SOCKET_ID_ANY, 0);
51697f17497SC.J. Collier	if (mz == NULL){
51797f17497SC.J. Collier		printf("Failed to reserve a big chunk of memory - %s\n",
51897f17497SC.J. Collier				rte_strerror(rte_errno));
51997f17497SC.J. Collier		rte_dump_physmem_layout(stdout);
52097f17497SC.J. Collier		rte_memzone_dump(stdout);
52197f17497SC.J. Collier		return -1;
52297f17497SC.J. Collier	}
52397f17497SC.J. Collier
52497f17497SC.J. Collier	if (mz->len != maxlen) {
52597f17497SC.J. Collier		printf("Memzone reserve with 0 size did not return bigest block\n");
52697f17497SC.J. Collier		printf("Expected size = %zu, actual size = %zu\n", maxlen, mz->len);
52797f17497SC.J. Collier		rte_dump_physmem_layout(stdout);
52897f17497SC.J. Collier		rte_memzone_dump(stdout);
52997f17497SC.J. Collier		return -1;
53097f17497SC.J. Collier	}
53147d9763aSLuca Boccassi
53247d9763aSLuca Boccassi	if (rte_memzone_free(mz)) {
53347d9763aSLuca Boccassi		printf("Fail memzone free\n");
53447d9763aSLuca Boccassi		return -1;
53547d9763aSLuca Boccassi	}
53647d9763aSLuca Boccassi
53797f17497SC.J. Collier	return 0;
53897f17497SC.J. Collier}
53997f17497SC.J. Collier
54097f17497SC.J. Collierstatic int
54197f17497SC.J. Colliertest_memzone_reserve_max_aligned(void)
54297f17497SC.J. Collier{
54397f17497SC.J. Collier	const struct rte_memzone *mz;
54497f17497SC.J. Collier	size_t maxlen = 0;
54597f17497SC.J. Collier
54697f17497SC.J. Collier	/* random alignment */
54797f17497SC.J. Collier	rte_srand((unsigned)rte_rdtsc());
54897f17497SC.J. Collier	const unsigned align = 1 << ((rte_rand() % 8) + 5); /* from 128 up to 4k alignment */
54997f17497SC.J. Collier
55097f17497SC.J. Collier	maxlen = find_max_block_free_size(align);
55197f17497SC.J. Collier
55297f17497SC.J. Collier	if (maxlen == 0) {
55397f17497SC.J. Collier		printf("There is no space left for biggest %u-aligned memzone!\n", align);
55497f17497SC.J. Collier		return 0;
55597f17497SC.J. Collier	}
55697f17497SC.J. Collier
55739157ec0SLuca Boccassi	mz = rte_memzone_reserve_aligned(TEST_MEMZONE_NAME("max_zone_aligned"),
55839157ec0SLuca Boccassi			0, SOCKET_ID_ANY, 0, align);
55997f17497SC.J. Collier	if (mz == NULL){
56097f17497SC.J. Collier		printf("Failed to reserve a big chunk of memory - %s\n",
56197f17497SC.J. Collier				rte_strerror(rte_errno));
56297f17497SC.J. Collier		rte_dump_physmem_layout(stdout);
56397f17497SC.J. Collier		rte_memzone_dump(stdout);
56497f17497SC.J. Collier		return -1;
56597f17497SC.J. Collier	}
56697f17497SC.J. Collier
56797f17497SC.J. Collier	if (mz->len != maxlen) {
56897f17497SC.J. Collier		printf("Memzone reserve with 0 size and alignment %u did not return"
56997f17497SC.J. Collier				" bigest block\n", align);
57097f17497SC.J. Collier		printf("Expected size = %zu, actual size = %zu\n",
57197f17497SC.J. Collier				maxlen, mz->len);
57297f17497SC.J. Collier		rte_dump_physmem_layout(stdout);
57397f17497SC.J. Collier		rte_memzone_dump(stdout);
57497f17497SC.J. Collier		return -1;
57597f17497SC.J. Collier	}
57647d9763aSLuca Boccassi
57747d9763aSLuca Boccassi	if (rte_memzone_free(mz)) {
57847d9763aSLuca Boccassi		printf("Fail memzone free\n");
57947d9763aSLuca Boccassi		return -1;
58047d9763aSLuca Boccassi	}
58147d9763aSLuca Boccassi
58297f17497SC.J. Collier	return 0;
58397f17497SC.J. Collier}
58497f17497SC.J. Collier
58597f17497SC.J. Collierstatic int
58697f17497SC.J. Colliertest_memzone_aligned(void)
58797f17497SC.J. Collier{
58897f17497SC.J. Collier	const struct rte_memzone *memzone_aligned_32;
58997f17497SC.J. Collier	const struct rte_memzone *memzone_aligned_128;
59097f17497SC.J. Collier	const struct rte_memzone *memzone_aligned_256;
59197f17497SC.J. Collier	const struct rte_memzone *memzone_aligned_512;
59297f17497SC.J. Collier	const struct rte_memzone *memzone_aligned_1024;
59397f17497SC.J. Collier
59497f17497SC.J. Collier	/* memzone that should automatically be adjusted to align on 64 bytes */
59539157ec0SLuca Boccassi	memzone_aligned_32 = rte_memzone_reserve_aligned(
59639157ec0SLuca Boccassi			TEST_MEMZONE_NAME("aligned_32"), 100, SOCKET_ID_ANY, 0,
59739157ec0SLuca Boccassi			32);
59897f17497SC.J. Collier
59997f17497SC.J. Collier	/* memzone that is supposed to be aligned on a 128 byte boundary */
60039157ec0SLuca Boccassi	memzone_aligned_128 = rte_memzone_reserve_aligned(
60139157ec0SLuca Boccassi			TEST_MEMZONE_NAME("aligned_128"), 100, SOCKET_ID_ANY, 0,
60239157ec0SLuca Boccassi			128);
60397f17497SC.J. Collier
60497f17497SC.J. Collier	/* memzone that is supposed to be aligned on a 256 byte boundary */
60539157ec0SLuca Boccassi	memzone_aligned_256 = rte_memzone_reserve_aligned(
60639157ec0SLuca Boccassi			TEST_MEMZONE_NAME("aligned_256"), 100, SOCKET_ID_ANY, 0,
60739157ec0SLuca Boccassi			256);
60897f17497SC.J. Collier
60997f17497SC.J. Collier	/* memzone that is supposed to be aligned on a 512 byte boundary */
61039157ec0SLuca Boccassi	memzone_aligned_512 = rte_memzone_reserve_aligned(
61139157ec0SLuca Boccassi			TEST_MEMZONE_NAME("aligned_512"), 100, SOCKET_ID_ANY, 0,
61239157ec0SLuca Boccassi			512);
61397f17497SC.J. Collier
61497f17497SC.J. Collier	/* memzone that is supposed to be aligned on a 1024 byte boundary */
61539157ec0SLuca Boccassi	memzone_aligned_1024 = rte_memzone_reserve_aligned(
61639157ec0SLuca Boccassi			TEST_MEMZONE_NAME("aligned_1024"), 100, SOCKET_ID_ANY,
61739157ec0SLuca Boccassi			0, 1024);
61897f17497SC.J. Collier
61997f17497SC.J. Collier	printf("check alignments and lengths\n");
62097f17497SC.J. Collier	if (memzone_aligned_32 == NULL) {
62197f17497SC.J. Collier		printf("Unable to reserve 64-byte aligned memzone!\n");
62297f17497SC.J. Collier		return -1;
62397f17497SC.J. Collier	}
62497f17497SC.J. Collier	if ((memzone_aligned_32->phys_addr & RTE_CACHE_LINE_MASK) != 0)
62597f17497SC.J. Collier		return -1;
62697f17497SC.J. Collier	if (((uintptr_t) memzone_aligned_32->addr & RTE_CACHE_LINE_MASK) != 0)
62797f17497SC.J. Collier		return -1;
62897f17497SC.J. Collier	if ((memzone_aligned_32->len & RTE_CACHE_LINE_MASK) != 0)
62997f17497SC.J. Collier		return -1;
63097f17497SC.J. Collier
63197f17497SC.J. Collier	if (memzone_aligned_128 == NULL) {
63297f17497SC.J. Collier		printf("Unable to reserve 128-byte aligned memzone!\n");
63397f17497SC.J. Collier		return -1;
63497f17497SC.J. Collier	}
63597f17497SC.J. Collier	if ((memzone_aligned_128->phys_addr & 127) != 0)
63697f17497SC.J. Collier		return -1;
63797f17497SC.J. Collier	if (((uintptr_t) memzone_aligned_128->addr & 127) != 0)
63897f17497SC.J. Collier		return -1;
63997f17497SC.J. Collier	if ((memzone_aligned_128->len & RTE_CACHE_LINE_MASK) != 0)
64097f17497SC.J. Collier		return -1;
64197f17497SC.J. Collier
64297f17497SC.J. Collier	if (memzone_aligned_256 == NULL) {
64397f17497SC.J. Collier		printf("Unable to reserve 256-byte aligned memzone!\n");
64497f17497SC.J. Collier		return -1;
64597f17497SC.J. Collier	}
64697f17497SC.J. Collier	if ((memzone_aligned_256->phys_addr & 255) != 0)
64797f17497SC.J. Collier		return -1;
64897f17497SC.J. Collier	if (((uintptr_t) memzone_aligned_256->addr & 255) != 0)
64997f17497SC.J. Collier		return -1;
65097f17497SC.J. Collier	if ((memzone_aligned_256->len & RTE_CACHE_LINE_MASK) != 0)
65197f17497SC.J. Collier		return -1;
65297f17497SC.J. Collier
65397f17497SC.J. Collier	if (memzone_aligned_512 == NULL) {
65497f17497SC.J. Collier		printf("Unable to reserve 512-byte aligned memzone!\n");
65597f17497SC.J. Collier		return -1;
65697f17497SC.J. Collier	}
65797f17497SC.J. Collier	if ((memzone_aligned_512->phys_addr & 511) != 0)
65897f17497SC.J. Collier		return -1;
65997f17497SC.J. Collier	if (((uintptr_t) memzone_aligned_512->addr & 511) != 0)
66097f17497SC.J. Collier		return -1;
66197f17497SC.J. Collier	if ((memzone_aligned_512->len & RTE_CACHE_LINE_MASK) != 0)
66297f17497SC.J. Collier		return -1;
66397f17497SC.J. Collier
66497f17497SC.J. Collier	if (memzone_aligned_1024 == NULL) {
66597f17497SC.J. Collier		printf("Unable to reserve 1024-byte aligned memzone!\n");
66697f17497SC.J. Collier		return -1;
66797f17497SC.J. Collier	}
66897f17497SC.J. Collier	if ((memzone_aligned_1024->phys_addr & 1023) != 0)
66997f17497SC.J. Collier		return -1;
67097f17497SC.J. Collier	if (((uintptr_t) memzone_aligned_1024->addr & 1023) != 0)
67197f17497SC.J. Collier		return -1;
67297f17497SC.J. Collier	if ((memzone_aligned_1024->len & RTE_CACHE_LINE_MASK) != 0)
67397f17497SC.J. Collier		return -1;
67497f17497SC.J. Collier
67597f17497SC.J. Collier	/* check that zones don't overlap */
67697f17497SC.J. Collier	printf("check overlapping\n");
67797f17497SC.J. Collier	if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len,
67897f17497SC.J. Collier					memzone_aligned_128->phys_addr, memzone_aligned_128->len))
67997f17497SC.J. Collier		return -1;
68097f17497SC.J. Collier	if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len,
68197f17497SC.J. Collier					memzone_aligned_256->phys_addr, memzone_aligned_256->len))
68297f17497SC.J. Collier		return -1;
68397f17497SC.J. Collier	if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len,
68497f17497SC.J. Collier					memzone_aligned_512->phys_addr, memzone_aligned_512->len))
68597f17497SC.J. Collier		return -1;
68697f17497SC.J. Collier	if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len,
68797f17497SC.J. Collier					memzone_aligned_1024->phys_addr, memzone_aligned_1024->len))
68897f17497SC.J. Collier		return -1;
68997f17497SC.J. Collier	if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len,
69097f17497SC.J. Collier					memzone_aligned_256->phys_addr, memzone_aligned_256->len))
69197f17497SC.J. Collier		return -1;
69297f17497SC.J. Collier	if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len,
69397f17497SC.J. Collier					memzone_aligned_512->phys_addr, memzone_aligned_512->len))
69497f17497SC.J. Collier		return -1;
69597f17497SC.J. Collier	if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len,
69697f17497SC.J. Collier					memzone_aligned_1024->phys_addr, memzone_aligned_1024->len))
69797f17497SC.J. Collier		return -1;
69897f17497SC.J. Collier	if (is_memory_overlap(memzone_aligned_256->phys_addr, memzone_aligned_256->len,
69997f17497SC.J. Collier					memzone_aligned_512->phys_addr, memzone_aligned_512->len))
70097f17497SC.J. Collier		return -1;
70197f17497SC.J. Collier	if (is_memory_overlap(memzone_aligned_256->phys_addr, memzone_aligned_256->len,
70297f17497SC.J. Collier					memzone_aligned_1024->phys_addr, memzone_aligned_1024->len))
70397f17497SC.J. Collier		return -1;
70497f17497SC.J. Collier	if (is_memory_overlap(memzone_aligned_512->phys_addr, memzone_aligned_512->len,
70597f17497SC.J. Collier					memzone_aligned_1024->phys_addr, memzone_aligned_1024->len))
70697f17497SC.J. Collier		return -1;
70747d9763aSLuca Boccassi
70847d9763aSLuca Boccassi	/* free all used zones */
70947d9763aSLuca Boccassi	if (rte_memzone_free(memzone_aligned_32)) {
71047d9763aSLuca Boccassi		printf("Fail memzone free\n");
71147d9763aSLuca Boccassi		return -1;
71247d9763aSLuca Boccassi	}
71347d9763aSLuca Boccassi	if (rte_memzone_free(memzone_aligned_128)) {
71447d9763aSLuca Boccassi		printf("Fail memzone free\n");
71547d9763aSLuca Boccassi		return -1;
71647d9763aSLuca Boccassi	}
71747d9763aSLuca Boccassi	if (rte_memzone_free(memzone_aligned_256)) {
71847d9763aSLuca Boccassi		printf("Fail memzone free\n");
71947d9763aSLuca Boccassi		return -1;
72047d9763aSLuca Boccassi	}
72147d9763aSLuca Boccassi	if (rte_memzone_free(memzone_aligned_512)) {
72247d9763aSLuca Boccassi		printf("Fail memzone free\n");
72347d9763aSLuca Boccassi		return -1;
72447d9763aSLuca Boccassi	}
72547d9763aSLuca Boccassi	if (rte_memzone_free(memzone_aligned_1024)) {
72647d9763aSLuca Boccassi		printf("Fail memzone free\n");
72747d9763aSLuca Boccassi		return -1;
72847d9763aSLuca Boccassi	}
72997f17497SC.J. Collier	return 0;
73097f17497SC.J. Collier}
73197f17497SC.J. Collier
73297f17497SC.J. Collierstatic int
73397f17497SC.J. Colliercheck_memzone_bounded(const char *name, uint32_t len,  uint32_t align,
73497f17497SC.J. Collier	uint32_t bound)
73597f17497SC.J. Collier{
73697f17497SC.J. Collier	const struct rte_memzone *mz;
73797f17497SC.J. Collier	phys_addr_t bmask;
73897f17497SC.J. Collier
73997f17497SC.J. Collier	bmask = ~((phys_addr_t)bound - 1);
74097f17497SC.J. Collier
74197f17497SC.J. Collier	if ((mz = rte_memzone_reserve_bounded(name, len, SOCKET_ID_ANY, 0,
74297f17497SC.J. Collier			align, bound)) == NULL) {
74397f17497SC.J. Collier		printf("%s(%s): memzone creation failed\n",
74497f17497SC.J. Collier			__func__, name);
74597f17497SC.J. Collier		return -1;
74697f17497SC.J. Collier	}
74797f17497SC.J. Collier
74897f17497SC.J. Collier	if ((mz->phys_addr & ((phys_addr_t)align - 1)) != 0) {
74997f17497SC.J. Collier		printf("%s(%s): invalid phys addr alignment\n",
75097f17497SC.J. Collier			__func__, mz->name);
75197f17497SC.J. Collier		return -1;
75297f17497SC.J. Collier	}
75397f17497SC.J. Collier
75497f17497SC.J. Collier	if (((uintptr_t) mz->addr & ((uintptr_t)align - 1)) != 0) {
75597f17497SC.J. Collier		printf("%s(%s): invalid virtual addr alignment\n",
75697f17497SC.J. Collier			__func__, mz->name);
75797f17497SC.J. Collier		return -1;
75897f17497SC.J. Collier	}
75997f17497SC.J. Collier
76097f17497SC.J. Collier	if ((mz->len & RTE_CACHE_LINE_MASK) != 0 || mz->len < len ||
76197f17497SC.J. Collier			mz->len < RTE_CACHE_LINE_SIZE) {
76297f17497SC.J. Collier		printf("%s(%s): invalid length\n",
76397f17497SC.J. Collier			__func__, mz->name);
76497f17497SC.J. Collier		return -1;
76597f17497SC.J. Collier	}
76697f17497SC.J. Collier
76797f17497SC.J. Collier	if ((mz->phys_addr & bmask) !=
76897f17497SC.J. Collier			((mz->phys_addr + mz->len - 1) & bmask)) {
76997f17497SC.J. Collier		printf("%s(%s): invalid memzone boundary %u crossed\n",
77097f17497SC.J. Collier			__func__, mz->name, bound);
77197f17497SC.J. Collier		return -1;
77297f17497SC.J. Collier	}
77397f17497SC.J. Collier
77447d9763aSLuca Boccassi	if (rte_memzone_free(mz)) {
77547d9763aSLuca Boccassi		printf("Fail memzone free\n");
77647d9763aSLuca Boccassi		return -1;
77747d9763aSLuca Boccassi	}
77847d9763aSLuca Boccassi
77997f17497SC.J. Collier	return 0;
78097f17497SC.J. Collier}
78197f17497SC.J. Collier
78297f17497SC.J. Collierstatic int
78397f17497SC.J. Colliertest_memzone_bounded(void)
78497f17497SC.J. Collier{
78597f17497SC.J. Collier	const struct rte_memzone *memzone_err;
78697f17497SC.J. Collier	int rc;
78797f17497SC.J. Collier
78897f17497SC.J. Collier	/* should fail as boundary is not power of two */
78939157ec0SLuca Boccassi	memzone_err = rte_memzone_reserve_bounded(
79039157ec0SLuca Boccassi			TEST_MEMZONE_NAME("bounded_error_31"), 100,
79139157ec0SLuca Boccassi			SOCKET_ID_ANY, 0, 32, UINT32_MAX);
79239157ec0SLuca Boccassi	if (memzone_err != NULL) {
79397f17497SC.J. Collier		printf("%s(%s)created a memzone with invalid boundary "
79497f17497SC.J. Collier			"conditions\n", __func__, memzone_err->name);
79597f17497SC.J. Collier		return -1;
79697f17497SC.J. Collier	}
79797f17497SC.J. Collier
79897f17497SC.J. Collier	/* should fail as len is greater then boundary */
79939157ec0SLuca Boccassi	memzone_err = rte_memzone_reserve_bounded(
80039157ec0SLuca Boccassi			TEST_MEMZONE_NAME("bounded_error_32"), 100,
80139157ec0SLuca Boccassi			SOCKET_ID_ANY, 0, 32, 32);
80239157ec0SLuca Boccassi	if (memzone_err != NULL) {
80397f17497SC.J. Collier		printf("%s(%s)created a memzone with invalid boundary "
80497f17497SC.J. Collier			"conditions\n", __func__, memzone_err->name);
80597f17497SC.J. Collier		return -1;
80697f17497SC.J. Collier	}
80797f17497SC.J. Collier
80839157ec0SLuca Boccassi	rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_128"), 100, 128,
80939157ec0SLuca Boccassi			128);
81039157ec0SLuca Boccassi	if (rc != 0)
81197f17497SC.J. Collier		return rc;
81297f17497SC.J. Collier
81339157ec0SLuca Boccassi	rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_256"), 100, 256,
81439157ec0SLuca Boccassi			128);
81539157ec0SLuca Boccassi	if (rc != 0)
81697f17497SC.J. Collier		return rc;
81797f17497SC.J. Collier
81839157ec0SLuca Boccassi	rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_1K"), 100, 64,
81939157ec0SLuca Boccassi			1024);
82039157ec0SLuca Boccassi	if (rc != 0)
82197f17497SC.J. Collier		return rc;
82297f17497SC.J. Collier
82339157ec0SLuca Boccassi	rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_1K_MAX"), 0, 64,
82439157ec0SLuca Boccassi			1024);
82539157ec0SLuca Boccassi	if (rc != 0)
82697f17497SC.J. Collier		return rc;
82797f17497SC.J. Collier
82897f17497SC.J. Collier	return 0;
82997f17497SC.J. Collier}
83097f17497SC.J. Collier
83197f17497SC.J. Collierstatic int
83297f17497SC.J. Colliertest_memzone_free(void)
83397f17497SC.J. Collier{
83439157ec0SLuca Boccassi	const struct rte_memzone *mz[RTE_MAX_MEMZONE + 1];
83597f17497SC.J. Collier	int i;
83697f17497SC.J. Collier	char name[20];
83797f17497SC.J. Collier
83839157ec0SLuca Boccassi	mz[0] = rte_memzone_reserve(TEST_MEMZONE_NAME("tempzone0"), 2000,
83939157ec0SLuca Boccassi			SOCKET_ID_ANY, 0);
84039157ec0SLuca Boccassi	mz[1] = rte_memzone_reserve(TEST_MEMZONE_NAME("tempzone1"), 4000,
84139157ec0SLuca Boccassi			SOCKET_ID_ANY, 0);
84297f17497SC.J. Collier
84397f17497SC.J. Collier	if (mz[0] > mz[1])
84497f17497SC.J. Collier		return -1;
84539157ec0SLuca Boccassi	if (!rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone0")))
84697f17497SC.J. Collier		return -1;
84739157ec0SLuca Boccassi	if (!rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone1")))
84897f17497SC.J. Collier		return -1;
84997f17497SC.J. Collier
85097f17497SC.J. Collier	if (rte_memzone_free(mz[0])) {
85197f17497SC.J. Collier		printf("Fail memzone free - tempzone0\n");
85297f17497SC.J. Collier		return -1;
85397f17497SC.J. Collier	}
85439157ec0SLuca Boccassi	if (rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone0"))) {
85597f17497SC.J. Collier		printf("Found previously free memzone - tempzone0\n");
85697f17497SC.J. Collier		return -1;
85797f17497SC.J. Collier	}
85839157ec0SLuca Boccassi	mz[2] = rte_memzone_reserve(TEST_MEMZONE_NAME("tempzone2"), 2000,
85939157ec0SLuca Boccassi			SOCKET_ID_ANY, 0);
86097f17497SC.J. Collier
86197f17497SC.J. Collier	if (mz[2] > mz[1]) {
86297f17497SC.J. Collier		printf("tempzone2 should have gotten the free entry from tempzone0\n");
86397f17497SC.J. Collier		return -1;
86497f17497SC.J. Collier	}
86597f17497SC.J. Collier	if (rte_memzone_free(mz[2])) {
86697f17497SC.J. Collier		printf("Fail memzone free - tempzone2\n");
86797f17497SC.J. Collier		return -1;
86897f17497SC.J. Collier	}
86939157ec0SLuca Boccassi	if (rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone2"))) {
87097f17497SC.J. Collier		printf("Found previously free memzone - tempzone2\n");
87197f17497SC.J. Collier		return -1;
87297f17497SC.J. Collier	}
87397f17497SC.J. Collier	if (rte_memzone_free(mz[1])) {
87497f17497SC.J. Collier		printf("Fail memzone free - tempzone1\n");
87597f17497SC.J. Collier		return -1;
87697f17497SC.J. Collier	}
87739157ec0SLuca Boccassi	if (rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone1"))) {
87897f17497SC.J. Collier		printf("Found previously free memzone - tempzone1\n");
87997f17497SC.J. Collier		return -1;
88097f17497SC.J. Collier	}
88197f17497SC.J. Collier
88297f17497SC.J. Collier	i = 0;
88397f17497SC.J. Collier	do {
88439157ec0SLuca Boccassi		snprintf(name, sizeof(name), TEST_MEMZONE_NAME("tempzone%u"),
88539157ec0SLuca Boccassi				i);
88697f17497SC.J. Collier		mz[i] = rte_memzone_reserve(name, 1, SOCKET_ID_ANY, 0);
88797f17497SC.J. Collier	} while (mz[i++] != NULL);
88897f17497SC.J. Collier
88997f17497SC.J. Collier	if (rte_memzone_free(mz[0])) {
89097f17497SC.J. Collier		printf("Fail memzone free - tempzone0\n");
89197f17497SC.J. Collier		return -1;
89297f17497SC.J. Collier	}
89339157ec0SLuca Boccassi	mz[0] = rte_memzone_reserve(TEST_MEMZONE_NAME("tempzone0new"), 0,
89439157ec0SLuca Boccassi			SOCKET_ID_ANY, 0);
89597f17497SC.J. Collier
89697f17497SC.J. Collier	if (mz[0] == NULL) {
89797f17497SC.J. Collier		printf("Fail to create memzone - tempzone0new - when MAX memzones were "
89897f17497SC.J. Collier				"created and one was free\n");
89997f17497SC.J. Collier		return -1;
90097f17497SC.J. Collier	}
90197f17497SC.J. Collier
90297f17497SC.J. Collier	for (i = i - 2; i >= 0; i--) {
90397f17497SC.J. Collier		if (rte_memzone_free(mz[i])) {
90497f17497SC.J. Collier			printf("Fail memzone free - tempzone%d\n", i);
90597f17497SC.J. Collier			return -1;
90697f17497SC.J. Collier		}
90797f17497SC.J. Collier	}
90897f17497SC.J. Collier
90997f17497SC.J. Collier	return 0;
91097f17497SC.J. Collier}
91197f17497SC.J. Collier
91297f17497SC.J. Collierstatic int
91347d9763aSLuca Boccassitest_memzone_basic(void)
91497f17497SC.J. Collier{
91597f17497SC.J. Collier	const struct rte_memzone *memzone1;
91697f17497SC.J. Collier	const struct rte_memzone *memzone2;
91797f17497SC.J. Collier	const struct rte_memzone *memzone3;
91897f17497SC.J. Collier	const struct rte_memzone *memzone4;
91997f17497SC.J. Collier	const struct rte_memzone *mz;
92097f17497SC.J. Collier
92139157ec0SLuca Boccassi	memzone1 = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone1"), 100,
92297f17497SC.J. Collier				SOCKET_ID_ANY, 0);
92397f17497SC.J. Collier
92439157ec0SLuca Boccassi	memzone2 = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone2"), 1000,
92597f17497SC.J. Collier				0, 0);
92697f17497SC.J. Collier
92739157ec0SLuca Boccassi	memzone3 = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone3"), 1000,
92897f17497SC.J. Collier				1, 0);
92997f17497SC.J. Collier
93039157ec0SLuca Boccassi	memzone4 = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone4"), 1024,
93197f17497SC.J. Collier				SOCKET_ID_ANY, 0);
93297f17497SC.J. Collier
93397f17497SC.J. Collier	/* memzone3 may be NULL if we don't have NUMA */
93497f17497SC.J. Collier	if (memzone1 == NULL || memzone2 == NULL || memzone4 == NULL)
93597f17497SC.J. Collier		return -1;
93697f17497SC.J. Collier
93797f17497SC.J. Collier	rte_memzone_dump(stdout);
93897f17497SC.J. Collier
93997f17497SC.J. Collier	/* check cache-line alignments */
94097f17497SC.J. Collier	printf("check alignments and lengths\n");
94197f17497SC.J. Collier
94297f17497SC.J. Collier	if ((memzone1->phys_addr & RTE_CACHE_LINE_MASK) != 0)
94397f17497SC.J. Collier		return -1;
94497f17497SC.J. Collier	if ((memzone2->phys_addr & RTE_CACHE_LINE_MASK) != 0)
94597f17497SC.J. Collier		return -1;
94697f17497SC.J. Collier	if (memzone3 != NULL && (memzone3->phys_addr & RTE_CACHE_LINE_MASK) != 0)
94797f17497SC.J. Collier		return -1;
94897f17497SC.J. Collier	if ((memzone1->len & RTE_CACHE_LINE_MASK) != 0 || memzone1->len == 0)
94997f17497SC.J. Collier		return -1;
95097f17497SC.J. Collier	if ((memzone2->len & RTE_CACHE_LINE_MASK) != 0 || memzone2->len == 0)
95197f17497SC.J. Collier		return -1;
95297f17497SC.J. Collier	if (memzone3 != NULL && ((memzone3->len & RTE_CACHE_LINE_MASK) != 0 ||
95397f17497SC.J. Collier			memzone3->len == 0))
95497f17497SC.J. Collier		return -1;
95597f17497SC.J. Collier	if (memzone4->len != 1024)
95697f17497SC.J. Collier		return -1;
95797f17497SC.J. Collier
95897f17497SC.J. Collier	/* check that zones don't overlap */
95997f17497SC.J. Collier	printf("check overlapping\n");
96097f17497SC.J. Collier
96197f17497SC.J. Collier	if (is_memory_overlap(memzone1->phys_addr, memzone1->len,
96297f17497SC.J. Collier			memzone2->phys_addr, memzone2->len))
96397f17497SC.J. Collier		return -1;
96497f17497SC.J. Collier	if (memzone3 != NULL &&
96597f17497SC.J. Collier			is_memory_overlap(memzone1->phys_addr, memzone1->len,
96697f17497SC.J. Collier					memzone3->phys_addr, memzone3->len))
96797f17497SC.J. Collier		return -1;
96897f17497SC.J. Collier	if (memzone3 != NULL &&
96997f17497SC.J. Collier			is_memory_overlap(memzone2->phys_addr, memzone2->len,
97097f17497SC.J. Collier					memzone3->phys_addr, memzone3->len))
97197f17497SC.J. Collier		return -1;
97297f17497SC.J. Collier
97397f17497SC.J. Collier	printf("check socket ID\n");
97497f17497SC.J. Collier
97597f17497SC.J. Collier	/* memzone2 must be on socket id 0 and memzone3 on socket 1 */
97697f17497SC.J. Collier	if (memzone2->socket_id != 0)
97797f17497SC.J. Collier		return -1;
97897f17497SC.J. Collier	if (memzone3 != NULL && memzone3->socket_id != 1)
97997f17497SC.J. Collier		return -1;
98097f17497SC.J. Collier
98197f17497SC.J. Collier	printf("test zone lookup\n");
98239157ec0SLuca Boccassi	mz = rte_memzone_lookup(TEST_MEMZONE_NAME("testzone1"));
98397f17497SC.J. Collier	if (mz != memzone1)
98497f17497SC.J. Collier		return -1;
98597f17497SC.J. Collier
98697f17497SC.J. Collier	printf("test duplcate zone name\n");
98739157ec0SLuca Boccassi	mz = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone1"), 100,
98897f17497SC.J. Collier			SOCKET_ID_ANY, 0);
98997f17497SC.J. Collier	if (mz != NULL)
99097f17497SC.J. Collier		return -1;
99197f17497SC.J. Collier
99247d9763aSLuca Boccassi	if (rte_memzone_free(memzone1)) {
99347d9763aSLuca Boccassi		printf("Fail memzone free - memzone1\n");
99447d9763aSLuca Boccassi		return -1;
99547d9763aSLuca Boccassi	}
99647d9763aSLuca Boccassi	if (rte_memzone_free(memzone2)) {
99747d9763aSLuca Boccassi		printf("Fail memzone free - memzone2\n");
99847d9763aSLuca Boccassi		return -1;
99947d9763aSLuca Boccassi	}
100047d9763aSLuca Boccassi	if (memzone3 && rte_memzone_free(memzone3)) {
100147d9763aSLuca Boccassi		printf("Fail memzone free - memzone3\n");
100247d9763aSLuca Boccassi		return -1;
100347d9763aSLuca Boccassi	}
100447d9763aSLuca Boccassi	if (rte_memzone_free(memzone4)) {
100547d9763aSLuca Boccassi		printf("Fail memzone free - memzone4\n");
100647d9763aSLuca Boccassi		return -1;
100747d9763aSLuca Boccassi	}
100847d9763aSLuca Boccassi
100947d9763aSLuca Boccassi	return 0;
101047d9763aSLuca Boccassi}
101147d9763aSLuca Boccassi
101239157ec0SLuca Boccassistatic int test_memzones_left;
101339157ec0SLuca Boccassistatic int memzone_walk_cnt;
101439157ec0SLuca Boccassistatic void memzone_walk_clb(const struct rte_memzone *mz,
101547d9763aSLuca Boccassi			     void *arg __rte_unused)
101647d9763aSLuca Boccassi{
101739157ec0SLuca Boccassi	memzone_walk_cnt++;
101839157ec0SLuca Boccassi	if (!strncmp(TEST_MEMZONE_NAME(""), mz->name, RTE_MEMZONE_NAMESIZE))
101939157ec0SLuca Boccassi		test_memzones_left++;
102047d9763aSLuca Boccassi}
102147d9763aSLuca Boccassi
102247d9763aSLuca Boccassistatic int
102347d9763aSLuca Boccassitest_memzone(void)
102447d9763aSLuca Boccassi{
102539157ec0SLuca Boccassi	/* take note of how many memzones were allocated before running */
102639157ec0SLuca Boccassi	int memzone_cnt = rte_eal_get_configuration()->mem_config->memzone_cnt;
102739157ec0SLuca Boccassi
102847d9763aSLuca Boccassi	printf("test basic memzone API\n");
102947d9763aSLuca Boccassi	if (test_memzone_basic() < 0)
103047d9763aSLuca Boccassi		return -1;
103147d9763aSLuca Boccassi
103297f17497SC.J. Collier	printf("test free memzone\n");
103397f17497SC.J. Collier	if (test_memzone_free() < 0)
103497f17497SC.J. Collier		return -1;
103597f17497SC.J. Collier
103697f17497SC.J. Collier	printf("test reserving memzone with bigger size than the maximum\n");
103797f17497SC.J. Collier	if (test_memzone_reserving_zone_size_bigger_than_the_maximum() < 0)
103897f17497SC.J. Collier		return -1;
103997f17497SC.J. Collier
104097f17497SC.J. Collier	printf("test memzone_reserve flags\n");
104197f17497SC.J. Collier	if (test_memzone_reserve_flags() < 0)
104297f17497SC.J. Collier		return -1;
104397f17497SC.J. Collier
104497f17497SC.J. Collier	printf("test alignment for memzone_reserve\n");
104597f17497SC.J. Collier	if (test_memzone_aligned() < 0)
104697f17497SC.J. Collier		return -1;
104797f17497SC.J. Collier
104897f17497SC.J. Collier	printf("test boundary alignment for memzone_reserve\n");
104997f17497SC.J. Collier	if (test_memzone_bounded() < 0)
105097f17497SC.J. Collier		return -1;
105197f17497SC.J. Collier
105297f17497SC.J. Collier	printf("test invalid alignment for memzone_reserve\n");
105397f17497SC.J. Collier	if (test_memzone_invalid_alignment() < 0)
105497f17497SC.J. Collier		return -1;
105597f17497SC.J. Collier
105697f17497SC.J. Collier	printf("test reserving the largest size memzone possible\n");
105797f17497SC.J. Collier	if (test_memzone_reserve_max() < 0)
105897f17497SC.J. Collier		return -1;
105997f17497SC.J. Collier
106097f17497SC.J. Collier	printf("test reserving the largest size aligned memzone possible\n");
106197f17497SC.J. Collier	if (test_memzone_reserve_max_aligned() < 0)
106297f17497SC.J. Collier		return -1;
106397f17497SC.J. Collier
106447d9763aSLuca Boccassi	printf("check memzone cleanup\n");
106539157ec0SLuca Boccassi	memzone_walk_cnt = 0;
106639157ec0SLuca Boccassi	test_memzones_left = 0;
106747d9763aSLuca Boccassi	rte_memzone_walk(memzone_walk_clb, NULL);
106839157ec0SLuca Boccassi	if (memzone_walk_cnt != memzone_cnt || test_memzones_left > 0) {
106947d9763aSLuca Boccassi		printf("there are some memzones left after test\n");
107047d9763aSLuca Boccassi		rte_memzone_dump(stdout);
107147d9763aSLuca Boccassi		return -1;
107247d9763aSLuca Boccassi	}
107347d9763aSLuca Boccassi
107497f17497SC.J. Collier	return 0;
1075