xref: /f-stack/dpdk/app/test/test_mempool.c (revision 2d9fd380)
14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang  * Copyright(c) 2010-2014 Intel Corporation
34418919fSjohnjiang  */
44418919fSjohnjiang 
54418919fSjohnjiang #include <string.h>
64418919fSjohnjiang #include <stdio.h>
74418919fSjohnjiang #include <stdlib.h>
84418919fSjohnjiang #include <stdint.h>
94418919fSjohnjiang #include <inttypes.h>
104418919fSjohnjiang #include <stdarg.h>
114418919fSjohnjiang #include <errno.h>
124418919fSjohnjiang #include <sys/queue.h>
134418919fSjohnjiang 
144418919fSjohnjiang #include <rte_common.h>
154418919fSjohnjiang #include <rte_log.h>
164418919fSjohnjiang #include <rte_debug.h>
174418919fSjohnjiang #include <rte_memory.h>
184418919fSjohnjiang #include <rte_launch.h>
194418919fSjohnjiang #include <rte_cycles.h>
204418919fSjohnjiang #include <rte_eal.h>
214418919fSjohnjiang #include <rte_per_lcore.h>
224418919fSjohnjiang #include <rte_lcore.h>
234418919fSjohnjiang #include <rte_atomic.h>
244418919fSjohnjiang #include <rte_branch_prediction.h>
254418919fSjohnjiang #include <rte_mempool.h>
264418919fSjohnjiang #include <rte_spinlock.h>
274418919fSjohnjiang #include <rte_malloc.h>
284418919fSjohnjiang #include <rte_mbuf_pool_ops.h>
294418919fSjohnjiang #include <rte_mbuf.h>
304418919fSjohnjiang 
314418919fSjohnjiang #include "test.h"
324418919fSjohnjiang 
334418919fSjohnjiang /*
344418919fSjohnjiang  * Mempool
354418919fSjohnjiang  * =======
364418919fSjohnjiang  *
374418919fSjohnjiang  * Basic tests: done on one core with and without cache:
384418919fSjohnjiang  *
394418919fSjohnjiang  *    - Get one object, put one object
404418919fSjohnjiang  *    - Get two objects, put two objects
414418919fSjohnjiang  *    - Get all objects, test that their content is not modified and
424418919fSjohnjiang  *      put them back in the pool.
434418919fSjohnjiang  */
444418919fSjohnjiang 
454418919fSjohnjiang #define MEMPOOL_ELT_SIZE 2048
464418919fSjohnjiang #define MAX_KEEP 16
474418919fSjohnjiang #define MEMPOOL_SIZE ((rte_lcore_count()*(MAX_KEEP+RTE_MEMPOOL_CACHE_MAX_SIZE))-1)
484418919fSjohnjiang 
494418919fSjohnjiang #define LOG_ERR() printf("test failed at %s():%d\n", __func__, __LINE__)
504418919fSjohnjiang #define RET_ERR() do {							\
514418919fSjohnjiang 		LOG_ERR();						\
524418919fSjohnjiang 		return -1;						\
534418919fSjohnjiang 	} while (0)
544418919fSjohnjiang #define GOTO_ERR(var, label) do {					\
554418919fSjohnjiang 		LOG_ERR();						\
564418919fSjohnjiang 		var = -1;						\
574418919fSjohnjiang 		goto label;						\
584418919fSjohnjiang 	} while (0)
594418919fSjohnjiang 
604418919fSjohnjiang static rte_atomic32_t synchro;
614418919fSjohnjiang 
624418919fSjohnjiang /*
634418919fSjohnjiang  * save the object number in the first 4 bytes of object data. All
644418919fSjohnjiang  * other bytes are set to 0.
654418919fSjohnjiang  */
664418919fSjohnjiang static void
my_obj_init(struct rte_mempool * mp,__rte_unused void * arg,void * obj,unsigned i)67*2d9fd380Sjfb8856606 my_obj_init(struct rte_mempool *mp, __rte_unused void *arg,
684418919fSjohnjiang 	    void *obj, unsigned i)
694418919fSjohnjiang {
704418919fSjohnjiang 	uint32_t *objnum = obj;
714418919fSjohnjiang 
724418919fSjohnjiang 	memset(obj, 0, mp->elt_size);
734418919fSjohnjiang 	*objnum = i;
744418919fSjohnjiang }
754418919fSjohnjiang 
764418919fSjohnjiang /* basic tests (done on one core) */
774418919fSjohnjiang static int
test_mempool_basic(struct rte_mempool * mp,int use_external_cache)784418919fSjohnjiang test_mempool_basic(struct rte_mempool *mp, int use_external_cache)
794418919fSjohnjiang {
804418919fSjohnjiang 	uint32_t *objnum;
814418919fSjohnjiang 	void **objtable;
824418919fSjohnjiang 	void *obj, *obj2;
834418919fSjohnjiang 	char *obj_data;
844418919fSjohnjiang 	int ret = 0;
854418919fSjohnjiang 	unsigned i, j;
864418919fSjohnjiang 	int offset;
874418919fSjohnjiang 	struct rte_mempool_cache *cache;
884418919fSjohnjiang 
894418919fSjohnjiang 	if (use_external_cache) {
904418919fSjohnjiang 		/* Create a user-owned mempool cache. */
914418919fSjohnjiang 		cache = rte_mempool_cache_create(RTE_MEMPOOL_CACHE_MAX_SIZE,
924418919fSjohnjiang 						 SOCKET_ID_ANY);
934418919fSjohnjiang 		if (cache == NULL)
944418919fSjohnjiang 			RET_ERR();
954418919fSjohnjiang 	} else {
964418919fSjohnjiang 		/* May be NULL if cache is disabled. */
974418919fSjohnjiang 		cache = rte_mempool_default_cache(mp, rte_lcore_id());
984418919fSjohnjiang 	}
994418919fSjohnjiang 
1004418919fSjohnjiang 	/* dump the mempool status */
1014418919fSjohnjiang 	rte_mempool_dump(stdout, mp);
1024418919fSjohnjiang 
1034418919fSjohnjiang 	printf("get an object\n");
1044418919fSjohnjiang 	if (rte_mempool_generic_get(mp, &obj, 1, cache) < 0)
1054418919fSjohnjiang 		GOTO_ERR(ret, out);
1064418919fSjohnjiang 	rte_mempool_dump(stdout, mp);
1074418919fSjohnjiang 
1084418919fSjohnjiang 	/* tests that improve coverage */
1094418919fSjohnjiang 	printf("get object count\n");
1104418919fSjohnjiang 	/* We have to count the extra caches, one in this case. */
1114418919fSjohnjiang 	offset = use_external_cache ? 1 * cache->len : 0;
1124418919fSjohnjiang 	if (rte_mempool_avail_count(mp) + offset != MEMPOOL_SIZE - 1)
1134418919fSjohnjiang 		GOTO_ERR(ret, out);
1144418919fSjohnjiang 
1154418919fSjohnjiang 	printf("get private data\n");
1164418919fSjohnjiang 	if (rte_mempool_get_priv(mp) != (char *)mp +
1174418919fSjohnjiang 			MEMPOOL_HEADER_SIZE(mp, mp->cache_size))
1184418919fSjohnjiang 		GOTO_ERR(ret, out);
1194418919fSjohnjiang 
1204418919fSjohnjiang #ifndef RTE_EXEC_ENV_FREEBSD /* rte_mem_virt2iova() not supported on bsd */
1214418919fSjohnjiang 	printf("get physical address of an object\n");
1224418919fSjohnjiang 	if (rte_mempool_virt2iova(obj) != rte_mem_virt2iova(obj))
1234418919fSjohnjiang 		GOTO_ERR(ret, out);
1244418919fSjohnjiang #endif
1254418919fSjohnjiang 
1264418919fSjohnjiang 	printf("put the object back\n");
1274418919fSjohnjiang 	rte_mempool_generic_put(mp, &obj, 1, cache);
1284418919fSjohnjiang 	rte_mempool_dump(stdout, mp);
1294418919fSjohnjiang 
1304418919fSjohnjiang 	printf("get 2 objects\n");
1314418919fSjohnjiang 	if (rte_mempool_generic_get(mp, &obj, 1, cache) < 0)
1324418919fSjohnjiang 		GOTO_ERR(ret, out);
1334418919fSjohnjiang 	if (rte_mempool_generic_get(mp, &obj2, 1, cache) < 0) {
1344418919fSjohnjiang 		rte_mempool_generic_put(mp, &obj, 1, cache);
1354418919fSjohnjiang 		GOTO_ERR(ret, out);
1364418919fSjohnjiang 	}
1374418919fSjohnjiang 	rte_mempool_dump(stdout, mp);
1384418919fSjohnjiang 
1394418919fSjohnjiang 	printf("put the objects back\n");
1404418919fSjohnjiang 	rte_mempool_generic_put(mp, &obj, 1, cache);
1414418919fSjohnjiang 	rte_mempool_generic_put(mp, &obj2, 1, cache);
1424418919fSjohnjiang 	rte_mempool_dump(stdout, mp);
1434418919fSjohnjiang 
1444418919fSjohnjiang 	/*
1454418919fSjohnjiang 	 * get many objects: we cannot get them all because the cache
1464418919fSjohnjiang 	 * on other cores may not be empty.
1474418919fSjohnjiang 	 */
1484418919fSjohnjiang 	objtable = malloc(MEMPOOL_SIZE * sizeof(void *));
1494418919fSjohnjiang 	if (objtable == NULL)
1504418919fSjohnjiang 		GOTO_ERR(ret, out);
1514418919fSjohnjiang 
1524418919fSjohnjiang 	for (i = 0; i < MEMPOOL_SIZE; i++) {
1534418919fSjohnjiang 		if (rte_mempool_generic_get(mp, &objtable[i], 1, cache) < 0)
1544418919fSjohnjiang 			break;
1554418919fSjohnjiang 	}
1564418919fSjohnjiang 
1574418919fSjohnjiang 	/*
1584418919fSjohnjiang 	 * for each object, check that its content was not modified,
1594418919fSjohnjiang 	 * and put objects back in pool
1604418919fSjohnjiang 	 */
1614418919fSjohnjiang 	while (i--) {
1624418919fSjohnjiang 		obj = objtable[i];
1634418919fSjohnjiang 		obj_data = obj;
1644418919fSjohnjiang 		objnum = obj;
1654418919fSjohnjiang 		if (*objnum > MEMPOOL_SIZE) {
1664418919fSjohnjiang 			printf("bad object number(%d)\n", *objnum);
1674418919fSjohnjiang 			ret = -1;
1684418919fSjohnjiang 			break;
1694418919fSjohnjiang 		}
1704418919fSjohnjiang 		for (j = sizeof(*objnum); j < mp->elt_size; j++) {
1714418919fSjohnjiang 			if (obj_data[j] != 0)
1724418919fSjohnjiang 				ret = -1;
1734418919fSjohnjiang 		}
1744418919fSjohnjiang 
1754418919fSjohnjiang 		rte_mempool_generic_put(mp, &objtable[i], 1, cache);
1764418919fSjohnjiang 	}
1774418919fSjohnjiang 
1784418919fSjohnjiang 	free(objtable);
1794418919fSjohnjiang 	if (ret == -1)
1804418919fSjohnjiang 		printf("objects were modified!\n");
1814418919fSjohnjiang 
1824418919fSjohnjiang out:
1834418919fSjohnjiang 	if (use_external_cache) {
1844418919fSjohnjiang 		rte_mempool_cache_flush(cache, mp);
1854418919fSjohnjiang 		rte_mempool_cache_free(cache);
1864418919fSjohnjiang 	}
1874418919fSjohnjiang 
1884418919fSjohnjiang 	return ret;
1894418919fSjohnjiang }
1904418919fSjohnjiang 
test_mempool_creation_with_exceeded_cache_size(void)1914418919fSjohnjiang static int test_mempool_creation_with_exceeded_cache_size(void)
1924418919fSjohnjiang {
1934418919fSjohnjiang 	struct rte_mempool *mp_cov;
1944418919fSjohnjiang 
1954418919fSjohnjiang 	mp_cov = rte_mempool_create("test_mempool_cache_too_big",
1964418919fSjohnjiang 		MEMPOOL_SIZE,
1974418919fSjohnjiang 		MEMPOOL_ELT_SIZE,
1984418919fSjohnjiang 		RTE_MEMPOOL_CACHE_MAX_SIZE + 32, 0,
1994418919fSjohnjiang 		NULL, NULL,
2004418919fSjohnjiang 		my_obj_init, NULL,
2014418919fSjohnjiang 		SOCKET_ID_ANY, 0);
2024418919fSjohnjiang 
2034418919fSjohnjiang 	if (mp_cov != NULL) {
2044418919fSjohnjiang 		rte_mempool_free(mp_cov);
2054418919fSjohnjiang 		RET_ERR();
2064418919fSjohnjiang 	}
2074418919fSjohnjiang 
2084418919fSjohnjiang 	return 0;
2094418919fSjohnjiang }
2104418919fSjohnjiang 
2114418919fSjohnjiang static struct rte_mempool *mp_spsc;
2124418919fSjohnjiang static rte_spinlock_t scsp_spinlock;
2134418919fSjohnjiang static void *scsp_obj_table[MAX_KEEP];
2144418919fSjohnjiang 
2154418919fSjohnjiang /*
2164418919fSjohnjiang  * single producer function
2174418919fSjohnjiang  */
test_mempool_single_producer(void)2184418919fSjohnjiang static int test_mempool_single_producer(void)
2194418919fSjohnjiang {
2204418919fSjohnjiang 	unsigned int i;
2214418919fSjohnjiang 	void *obj = NULL;
2224418919fSjohnjiang 	uint64_t start_cycles, end_cycles;
2234418919fSjohnjiang 	uint64_t duration = rte_get_timer_hz() / 4;
2244418919fSjohnjiang 
2254418919fSjohnjiang 	start_cycles = rte_get_timer_cycles();
2264418919fSjohnjiang 	while (1) {
2274418919fSjohnjiang 		end_cycles = rte_get_timer_cycles();
2284418919fSjohnjiang 		/* duration uses up, stop producing */
2294418919fSjohnjiang 		if (start_cycles + duration < end_cycles)
2304418919fSjohnjiang 			break;
2314418919fSjohnjiang 		rte_spinlock_lock(&scsp_spinlock);
2324418919fSjohnjiang 		for (i = 0; i < MAX_KEEP; i ++) {
2334418919fSjohnjiang 			if (NULL != scsp_obj_table[i]) {
2344418919fSjohnjiang 				obj = scsp_obj_table[i];
2354418919fSjohnjiang 				break;
2364418919fSjohnjiang 			}
2374418919fSjohnjiang 		}
2384418919fSjohnjiang 		rte_spinlock_unlock(&scsp_spinlock);
2394418919fSjohnjiang 		if (i >= MAX_KEEP) {
2404418919fSjohnjiang 			continue;
2414418919fSjohnjiang 		}
2424418919fSjohnjiang 		if (rte_mempool_from_obj(obj) != mp_spsc) {
2434418919fSjohnjiang 			printf("obj not owned by this mempool\n");
2444418919fSjohnjiang 			RET_ERR();
2454418919fSjohnjiang 		}
2464418919fSjohnjiang 		rte_mempool_put(mp_spsc, obj);
2474418919fSjohnjiang 		rte_spinlock_lock(&scsp_spinlock);
2484418919fSjohnjiang 		scsp_obj_table[i] = NULL;
2494418919fSjohnjiang 		rte_spinlock_unlock(&scsp_spinlock);
2504418919fSjohnjiang 	}
2514418919fSjohnjiang 
2524418919fSjohnjiang 	return 0;
2534418919fSjohnjiang }
2544418919fSjohnjiang 
2554418919fSjohnjiang /*
2564418919fSjohnjiang  * single consumer function
2574418919fSjohnjiang  */
test_mempool_single_consumer(void)2584418919fSjohnjiang static int test_mempool_single_consumer(void)
2594418919fSjohnjiang {
2604418919fSjohnjiang 	unsigned int i;
2614418919fSjohnjiang 	void * obj;
2624418919fSjohnjiang 	uint64_t start_cycles, end_cycles;
2634418919fSjohnjiang 	uint64_t duration = rte_get_timer_hz() / 8;
2644418919fSjohnjiang 
2654418919fSjohnjiang 	start_cycles = rte_get_timer_cycles();
2664418919fSjohnjiang 	while (1) {
2674418919fSjohnjiang 		end_cycles = rte_get_timer_cycles();
2684418919fSjohnjiang 		/* duration uses up, stop consuming */
2694418919fSjohnjiang 		if (start_cycles + duration < end_cycles)
2704418919fSjohnjiang 			break;
2714418919fSjohnjiang 		rte_spinlock_lock(&scsp_spinlock);
2724418919fSjohnjiang 		for (i = 0; i < MAX_KEEP; i ++) {
2734418919fSjohnjiang 			if (NULL == scsp_obj_table[i])
2744418919fSjohnjiang 				break;
2754418919fSjohnjiang 		}
2764418919fSjohnjiang 		rte_spinlock_unlock(&scsp_spinlock);
2774418919fSjohnjiang 		if (i >= MAX_KEEP)
2784418919fSjohnjiang 			continue;
2794418919fSjohnjiang 		if (rte_mempool_get(mp_spsc, &obj) < 0)
2804418919fSjohnjiang 			break;
2814418919fSjohnjiang 		rte_spinlock_lock(&scsp_spinlock);
2824418919fSjohnjiang 		scsp_obj_table[i] = obj;
2834418919fSjohnjiang 		rte_spinlock_unlock(&scsp_spinlock);
2844418919fSjohnjiang 	}
2854418919fSjohnjiang 
2864418919fSjohnjiang 	return 0;
2874418919fSjohnjiang }
2884418919fSjohnjiang 
2894418919fSjohnjiang /*
2904418919fSjohnjiang  * test function for mempool test based on singple consumer and single producer,
2914418919fSjohnjiang  * can run on one lcore only
2924418919fSjohnjiang  */
2934418919fSjohnjiang static int
test_mempool_launch_single_consumer(__rte_unused void * arg)294*2d9fd380Sjfb8856606 test_mempool_launch_single_consumer(__rte_unused void *arg)
2954418919fSjohnjiang {
2964418919fSjohnjiang 	return test_mempool_single_consumer();
2974418919fSjohnjiang }
2984418919fSjohnjiang 
2994418919fSjohnjiang static void
my_mp_init(struct rte_mempool * mp,__rte_unused void * arg)300*2d9fd380Sjfb8856606 my_mp_init(struct rte_mempool *mp, __rte_unused void *arg)
3014418919fSjohnjiang {
3024418919fSjohnjiang 	printf("mempool name is %s\n", mp->name);
3034418919fSjohnjiang 	/* nothing to be implemented here*/
3044418919fSjohnjiang 	return ;
3054418919fSjohnjiang }
3064418919fSjohnjiang 
3074418919fSjohnjiang /*
3084418919fSjohnjiang  * it tests the mempool operations based on singple producer and single consumer
3094418919fSjohnjiang  */
3104418919fSjohnjiang static int
test_mempool_sp_sc(void)3114418919fSjohnjiang test_mempool_sp_sc(void)
3124418919fSjohnjiang {
3134418919fSjohnjiang 	int ret = 0;
3144418919fSjohnjiang 	unsigned lcore_id = rte_lcore_id();
3154418919fSjohnjiang 	unsigned lcore_next;
3164418919fSjohnjiang 
3174418919fSjohnjiang 	/* create a mempool with single producer/consumer ring */
3184418919fSjohnjiang 	if (mp_spsc == NULL) {
3194418919fSjohnjiang 		mp_spsc = rte_mempool_create("test_mempool_sp_sc", MEMPOOL_SIZE,
3204418919fSjohnjiang 			MEMPOOL_ELT_SIZE, 0, 0,
3214418919fSjohnjiang 			my_mp_init, NULL,
3224418919fSjohnjiang 			my_obj_init, NULL,
3234418919fSjohnjiang 			SOCKET_ID_ANY,
3244418919fSjohnjiang 			MEMPOOL_F_NO_CACHE_ALIGN | MEMPOOL_F_SP_PUT |
3254418919fSjohnjiang 			MEMPOOL_F_SC_GET);
3264418919fSjohnjiang 		if (mp_spsc == NULL)
3274418919fSjohnjiang 			RET_ERR();
3284418919fSjohnjiang 	}
3294418919fSjohnjiang 	if (rte_mempool_lookup("test_mempool_sp_sc") != mp_spsc) {
3304418919fSjohnjiang 		printf("Cannot lookup mempool from its name\n");
3314418919fSjohnjiang 		ret = -1;
3324418919fSjohnjiang 		goto err;
3334418919fSjohnjiang 	}
3344418919fSjohnjiang 	lcore_next = rte_get_next_lcore(lcore_id, 0, 1);
3354418919fSjohnjiang 	if (lcore_next >= RTE_MAX_LCORE) {
3364418919fSjohnjiang 		ret = -1;
3374418919fSjohnjiang 		goto err;
3384418919fSjohnjiang 	}
3394418919fSjohnjiang 	if (rte_eal_lcore_role(lcore_next) != ROLE_RTE) {
3404418919fSjohnjiang 		ret = -1;
3414418919fSjohnjiang 		goto err;
3424418919fSjohnjiang 	}
3434418919fSjohnjiang 	rte_spinlock_init(&scsp_spinlock);
3444418919fSjohnjiang 	memset(scsp_obj_table, 0, sizeof(scsp_obj_table));
3454418919fSjohnjiang 	rte_eal_remote_launch(test_mempool_launch_single_consumer, NULL,
3464418919fSjohnjiang 		lcore_next);
3474418919fSjohnjiang 	if (test_mempool_single_producer() < 0)
3484418919fSjohnjiang 		ret = -1;
3494418919fSjohnjiang 
3504418919fSjohnjiang 	if (rte_eal_wait_lcore(lcore_next) < 0)
3514418919fSjohnjiang 		ret = -1;
3524418919fSjohnjiang 
3534418919fSjohnjiang err:
3544418919fSjohnjiang 	rte_mempool_free(mp_spsc);
3554418919fSjohnjiang 	mp_spsc = NULL;
3564418919fSjohnjiang 
3574418919fSjohnjiang 	return ret;
3584418919fSjohnjiang }
3594418919fSjohnjiang 
3604418919fSjohnjiang /*
3614418919fSjohnjiang  * it tests some more basic of mempool
3624418919fSjohnjiang  */
3634418919fSjohnjiang static int
test_mempool_basic_ex(struct rte_mempool * mp)3644418919fSjohnjiang test_mempool_basic_ex(struct rte_mempool *mp)
3654418919fSjohnjiang {
3664418919fSjohnjiang 	unsigned i;
3674418919fSjohnjiang 	void **obj;
3684418919fSjohnjiang 	void *err_obj;
3694418919fSjohnjiang 	int ret = -1;
3704418919fSjohnjiang 
3714418919fSjohnjiang 	if (mp == NULL)
3724418919fSjohnjiang 		return ret;
3734418919fSjohnjiang 
3744418919fSjohnjiang 	obj = rte_calloc("test_mempool_basic_ex", MEMPOOL_SIZE,
3754418919fSjohnjiang 		sizeof(void *), 0);
3764418919fSjohnjiang 	if (obj == NULL) {
3774418919fSjohnjiang 		printf("test_mempool_basic_ex fail to rte_malloc\n");
3784418919fSjohnjiang 		return ret;
3794418919fSjohnjiang 	}
3804418919fSjohnjiang 	printf("test_mempool_basic_ex now mempool (%s) has %u free entries\n",
3814418919fSjohnjiang 		mp->name, rte_mempool_in_use_count(mp));
3824418919fSjohnjiang 	if (rte_mempool_full(mp) != 1) {
3834418919fSjohnjiang 		printf("test_mempool_basic_ex the mempool should be full\n");
3844418919fSjohnjiang 		goto fail_mp_basic_ex;
3854418919fSjohnjiang 	}
3864418919fSjohnjiang 
3874418919fSjohnjiang 	for (i = 0; i < MEMPOOL_SIZE; i ++) {
3884418919fSjohnjiang 		if (rte_mempool_get(mp, &obj[i]) < 0) {
3894418919fSjohnjiang 			printf("test_mp_basic_ex fail to get object for [%u]\n",
3904418919fSjohnjiang 				i);
3914418919fSjohnjiang 			goto fail_mp_basic_ex;
3924418919fSjohnjiang 		}
3934418919fSjohnjiang 	}
3944418919fSjohnjiang 	if (rte_mempool_get(mp, &err_obj) == 0) {
3954418919fSjohnjiang 		printf("test_mempool_basic_ex get an impossible obj\n");
3964418919fSjohnjiang 		goto fail_mp_basic_ex;
3974418919fSjohnjiang 	}
3984418919fSjohnjiang 	printf("number: %u\n", i);
3994418919fSjohnjiang 	if (rte_mempool_empty(mp) != 1) {
4004418919fSjohnjiang 		printf("test_mempool_basic_ex the mempool should be empty\n");
4014418919fSjohnjiang 		goto fail_mp_basic_ex;
4024418919fSjohnjiang 	}
4034418919fSjohnjiang 
4044418919fSjohnjiang 	for (i = 0; i < MEMPOOL_SIZE; i++)
4054418919fSjohnjiang 		rte_mempool_put(mp, obj[i]);
4064418919fSjohnjiang 
4074418919fSjohnjiang 	if (rte_mempool_full(mp) != 1) {
4084418919fSjohnjiang 		printf("test_mempool_basic_ex the mempool should be full\n");
4094418919fSjohnjiang 		goto fail_mp_basic_ex;
4104418919fSjohnjiang 	}
4114418919fSjohnjiang 
4124418919fSjohnjiang 	ret = 0;
4134418919fSjohnjiang 
4144418919fSjohnjiang fail_mp_basic_ex:
4154418919fSjohnjiang 	if (obj != NULL)
4164418919fSjohnjiang 		rte_free((void *)obj);
4174418919fSjohnjiang 
4184418919fSjohnjiang 	return ret;
4194418919fSjohnjiang }
4204418919fSjohnjiang 
4214418919fSjohnjiang static int
test_mempool_same_name_twice_creation(void)4224418919fSjohnjiang test_mempool_same_name_twice_creation(void)
4234418919fSjohnjiang {
4244418919fSjohnjiang 	struct rte_mempool *mp_tc, *mp_tc2;
4254418919fSjohnjiang 
4264418919fSjohnjiang 	mp_tc = rte_mempool_create("test_mempool_same_name", MEMPOOL_SIZE,
4274418919fSjohnjiang 		MEMPOOL_ELT_SIZE, 0, 0,
4284418919fSjohnjiang 		NULL, NULL,
4294418919fSjohnjiang 		NULL, NULL,
4304418919fSjohnjiang 		SOCKET_ID_ANY, 0);
4314418919fSjohnjiang 
4324418919fSjohnjiang 	if (mp_tc == NULL)
4334418919fSjohnjiang 		RET_ERR();
4344418919fSjohnjiang 
4354418919fSjohnjiang 	mp_tc2 = rte_mempool_create("test_mempool_same_name", MEMPOOL_SIZE,
4364418919fSjohnjiang 		MEMPOOL_ELT_SIZE, 0, 0,
4374418919fSjohnjiang 		NULL, NULL,
4384418919fSjohnjiang 		NULL, NULL,
4394418919fSjohnjiang 		SOCKET_ID_ANY, 0);
4404418919fSjohnjiang 
4414418919fSjohnjiang 	if (mp_tc2 != NULL) {
4424418919fSjohnjiang 		rte_mempool_free(mp_tc);
4434418919fSjohnjiang 		rte_mempool_free(mp_tc2);
4444418919fSjohnjiang 		RET_ERR();
4454418919fSjohnjiang 	}
4464418919fSjohnjiang 
4474418919fSjohnjiang 	rte_mempool_free(mp_tc);
4484418919fSjohnjiang 	return 0;
4494418919fSjohnjiang }
4504418919fSjohnjiang 
4514418919fSjohnjiang static void
walk_cb(struct rte_mempool * mp,void * userdata __rte_unused)4524418919fSjohnjiang walk_cb(struct rte_mempool *mp, void *userdata __rte_unused)
4534418919fSjohnjiang {
4544418919fSjohnjiang 	printf("\t%s\n", mp->name);
4554418919fSjohnjiang }
4564418919fSjohnjiang 
4574418919fSjohnjiang struct mp_data {
4584418919fSjohnjiang 	int16_t ret;
4594418919fSjohnjiang };
4604418919fSjohnjiang 
4614418919fSjohnjiang static void
test_mp_mem_init(struct rte_mempool * mp,__rte_unused void * opaque,__rte_unused struct rte_mempool_memhdr * memhdr,__rte_unused unsigned int mem_idx)4624418919fSjohnjiang test_mp_mem_init(struct rte_mempool *mp,
4634418919fSjohnjiang 		__rte_unused void *opaque,
4644418919fSjohnjiang 		__rte_unused struct rte_mempool_memhdr *memhdr,
4654418919fSjohnjiang 		__rte_unused unsigned int mem_idx)
4664418919fSjohnjiang {
4674418919fSjohnjiang 	struct mp_data *data = opaque;
4684418919fSjohnjiang 
4694418919fSjohnjiang 	if (mp == NULL) {
4704418919fSjohnjiang 		data->ret = -1;
4714418919fSjohnjiang 		return;
4724418919fSjohnjiang 	}
4734418919fSjohnjiang 	/* nothing to be implemented here*/
4744418919fSjohnjiang 	data->ret = 0;
4754418919fSjohnjiang }
4764418919fSjohnjiang 
4774418919fSjohnjiang static int
test_mempool(void)4784418919fSjohnjiang test_mempool(void)
4794418919fSjohnjiang {
4804418919fSjohnjiang 	int ret = -1;
4814418919fSjohnjiang 	uint32_t nb_objs = 0;
4824418919fSjohnjiang 	uint32_t nb_mem_chunks = 0;
4834418919fSjohnjiang 	struct rte_mempool *mp_cache = NULL;
4844418919fSjohnjiang 	struct rte_mempool *mp_nocache = NULL;
4854418919fSjohnjiang 	struct rte_mempool *mp_stack_anon = NULL;
4864418919fSjohnjiang 	struct rte_mempool *mp_stack_mempool_iter = NULL;
4874418919fSjohnjiang 	struct rte_mempool *mp_stack = NULL;
4884418919fSjohnjiang 	struct rte_mempool *default_pool = NULL;
4894418919fSjohnjiang 	struct mp_data cb_arg = {
4904418919fSjohnjiang 		.ret = -1
4914418919fSjohnjiang 	};
4924418919fSjohnjiang 	const char *default_pool_ops = rte_mbuf_best_mempool_ops();
4934418919fSjohnjiang 
4944418919fSjohnjiang 	rte_atomic32_init(&synchro);
4954418919fSjohnjiang 
4964418919fSjohnjiang 	/* create a mempool (without cache) */
4974418919fSjohnjiang 	mp_nocache = rte_mempool_create("test_nocache", MEMPOOL_SIZE,
4984418919fSjohnjiang 		MEMPOOL_ELT_SIZE, 0, 0,
4994418919fSjohnjiang 		NULL, NULL,
5004418919fSjohnjiang 		my_obj_init, NULL,
5014418919fSjohnjiang 		SOCKET_ID_ANY, 0);
5024418919fSjohnjiang 
5034418919fSjohnjiang 	if (mp_nocache == NULL) {
5044418919fSjohnjiang 		printf("cannot allocate mp_nocache mempool\n");
5054418919fSjohnjiang 		GOTO_ERR(ret, err);
5064418919fSjohnjiang 	}
5074418919fSjohnjiang 
5084418919fSjohnjiang 	/* create a mempool (with cache) */
5094418919fSjohnjiang 	mp_cache = rte_mempool_create("test_cache", MEMPOOL_SIZE,
5104418919fSjohnjiang 		MEMPOOL_ELT_SIZE,
5114418919fSjohnjiang 		RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
5124418919fSjohnjiang 		NULL, NULL,
5134418919fSjohnjiang 		my_obj_init, NULL,
5144418919fSjohnjiang 		SOCKET_ID_ANY, 0);
5154418919fSjohnjiang 
5164418919fSjohnjiang 	if (mp_cache == NULL) {
5174418919fSjohnjiang 		printf("cannot allocate mp_cache mempool\n");
5184418919fSjohnjiang 		GOTO_ERR(ret, err);
5194418919fSjohnjiang 	}
5204418919fSjohnjiang 
5214418919fSjohnjiang 	/* create an empty mempool  */
5224418919fSjohnjiang 	mp_stack_anon = rte_mempool_create_empty("test_stack_anon",
5234418919fSjohnjiang 		MEMPOOL_SIZE,
5244418919fSjohnjiang 		MEMPOOL_ELT_SIZE,
5254418919fSjohnjiang 		RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
5264418919fSjohnjiang 		SOCKET_ID_ANY, 0);
5274418919fSjohnjiang 
5284418919fSjohnjiang 	if (mp_stack_anon == NULL)
5294418919fSjohnjiang 		GOTO_ERR(ret, err);
5304418919fSjohnjiang 
5314418919fSjohnjiang 	/* populate an empty mempool */
5324418919fSjohnjiang 	ret = rte_mempool_populate_anon(mp_stack_anon);
5334418919fSjohnjiang 	printf("%s ret = %d\n", __func__, ret);
5344418919fSjohnjiang 	if (ret < 0)
5354418919fSjohnjiang 		GOTO_ERR(ret, err);
5364418919fSjohnjiang 
5374418919fSjohnjiang 	/* Try to populate when already populated */
5384418919fSjohnjiang 	ret = rte_mempool_populate_anon(mp_stack_anon);
5394418919fSjohnjiang 	if (ret != 0)
5404418919fSjohnjiang 		GOTO_ERR(ret, err);
5414418919fSjohnjiang 
5424418919fSjohnjiang 	/* create a mempool  */
5434418919fSjohnjiang 	mp_stack_mempool_iter = rte_mempool_create("test_iter_obj",
5444418919fSjohnjiang 		MEMPOOL_SIZE,
5454418919fSjohnjiang 		MEMPOOL_ELT_SIZE,
5464418919fSjohnjiang 		RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
5474418919fSjohnjiang 		NULL, NULL,
5484418919fSjohnjiang 		my_obj_init, NULL,
5494418919fSjohnjiang 		SOCKET_ID_ANY, 0);
5504418919fSjohnjiang 
5514418919fSjohnjiang 	if (mp_stack_mempool_iter == NULL)
5524418919fSjohnjiang 		GOTO_ERR(ret, err);
5534418919fSjohnjiang 
5544418919fSjohnjiang 	/* test to initialize mempool objects and memory */
5554418919fSjohnjiang 	nb_objs = rte_mempool_obj_iter(mp_stack_mempool_iter, rte_pktmbuf_init,
5564418919fSjohnjiang 			NULL);
5574418919fSjohnjiang 	if (nb_objs == 0)
5584418919fSjohnjiang 		GOTO_ERR(ret, err);
5594418919fSjohnjiang 
5604418919fSjohnjiang 	nb_mem_chunks = rte_mempool_mem_iter(mp_stack_mempool_iter,
5614418919fSjohnjiang 			test_mp_mem_init, &cb_arg);
5624418919fSjohnjiang 	if (nb_mem_chunks == 0 || cb_arg.ret < 0)
5634418919fSjohnjiang 		GOTO_ERR(ret, err);
5644418919fSjohnjiang 
5654418919fSjohnjiang 	/* create a mempool with an external handler */
5664418919fSjohnjiang 	mp_stack = rte_mempool_create_empty("test_stack",
5674418919fSjohnjiang 		MEMPOOL_SIZE,
5684418919fSjohnjiang 		MEMPOOL_ELT_SIZE,
5694418919fSjohnjiang 		RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
5704418919fSjohnjiang 		SOCKET_ID_ANY, 0);
5714418919fSjohnjiang 
5724418919fSjohnjiang 	if (mp_stack == NULL) {
5734418919fSjohnjiang 		printf("cannot allocate mp_stack mempool\n");
5744418919fSjohnjiang 		GOTO_ERR(ret, err);
5754418919fSjohnjiang 	}
5764418919fSjohnjiang 	if (rte_mempool_set_ops_byname(mp_stack, "stack", NULL) < 0) {
5774418919fSjohnjiang 		printf("cannot set stack handler\n");
5784418919fSjohnjiang 		GOTO_ERR(ret, err);
5794418919fSjohnjiang 	}
5804418919fSjohnjiang 	if (rte_mempool_populate_default(mp_stack) < 0) {
5814418919fSjohnjiang 		printf("cannot populate mp_stack mempool\n");
5824418919fSjohnjiang 		GOTO_ERR(ret, err);
5834418919fSjohnjiang 	}
5844418919fSjohnjiang 	rte_mempool_obj_iter(mp_stack, my_obj_init, NULL);
5854418919fSjohnjiang 
5864418919fSjohnjiang 	/* Create a mempool based on Default handler */
5874418919fSjohnjiang 	printf("Testing %s mempool handler\n", default_pool_ops);
5884418919fSjohnjiang 	default_pool = rte_mempool_create_empty("default_pool",
5894418919fSjohnjiang 						MEMPOOL_SIZE,
5904418919fSjohnjiang 						MEMPOOL_ELT_SIZE,
5914418919fSjohnjiang 						RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
5924418919fSjohnjiang 						SOCKET_ID_ANY, 0);
5934418919fSjohnjiang 
5944418919fSjohnjiang 	if (default_pool == NULL) {
5954418919fSjohnjiang 		printf("cannot allocate default mempool\n");
5964418919fSjohnjiang 		GOTO_ERR(ret, err);
5974418919fSjohnjiang 	}
5984418919fSjohnjiang 	if (rte_mempool_set_ops_byname(default_pool,
5994418919fSjohnjiang 				default_pool_ops, NULL) < 0) {
6004418919fSjohnjiang 		printf("cannot set %s handler\n", default_pool_ops);
6014418919fSjohnjiang 		GOTO_ERR(ret, err);
6024418919fSjohnjiang 	}
6034418919fSjohnjiang 	if (rte_mempool_populate_default(default_pool) < 0) {
6044418919fSjohnjiang 		printf("cannot populate %s mempool\n", default_pool_ops);
6054418919fSjohnjiang 		GOTO_ERR(ret, err);
6064418919fSjohnjiang 	}
6074418919fSjohnjiang 	rte_mempool_obj_iter(default_pool, my_obj_init, NULL);
6084418919fSjohnjiang 
6094418919fSjohnjiang 	/* retrieve the mempool from its name */
6104418919fSjohnjiang 	if (rte_mempool_lookup("test_nocache") != mp_nocache) {
6114418919fSjohnjiang 		printf("Cannot lookup mempool from its name\n");
6124418919fSjohnjiang 		GOTO_ERR(ret, err);
6134418919fSjohnjiang 	}
6144418919fSjohnjiang 
6154418919fSjohnjiang 	printf("Walk into mempools:\n");
6164418919fSjohnjiang 	rte_mempool_walk(walk_cb, NULL);
6174418919fSjohnjiang 
6184418919fSjohnjiang 	rte_mempool_list_dump(stdout);
6194418919fSjohnjiang 
6204418919fSjohnjiang 	/* basic tests without cache */
6214418919fSjohnjiang 	if (test_mempool_basic(mp_nocache, 0) < 0)
6224418919fSjohnjiang 		GOTO_ERR(ret, err);
6234418919fSjohnjiang 
6244418919fSjohnjiang 	/* basic tests with cache */
6254418919fSjohnjiang 	if (test_mempool_basic(mp_cache, 0) < 0)
6264418919fSjohnjiang 		GOTO_ERR(ret, err);
6274418919fSjohnjiang 
6284418919fSjohnjiang 	/* basic tests with user-owned cache */
6294418919fSjohnjiang 	if (test_mempool_basic(mp_nocache, 1) < 0)
6304418919fSjohnjiang 		GOTO_ERR(ret, err);
6314418919fSjohnjiang 
6324418919fSjohnjiang 	/* more basic tests without cache */
6334418919fSjohnjiang 	if (test_mempool_basic_ex(mp_nocache) < 0)
6344418919fSjohnjiang 		GOTO_ERR(ret, err);
6354418919fSjohnjiang 
6364418919fSjohnjiang 	/* mempool operation test based on single producer and single comsumer */
6374418919fSjohnjiang 	if (test_mempool_sp_sc() < 0)
6384418919fSjohnjiang 		GOTO_ERR(ret, err);
6394418919fSjohnjiang 
6404418919fSjohnjiang 	if (test_mempool_creation_with_exceeded_cache_size() < 0)
6414418919fSjohnjiang 		GOTO_ERR(ret, err);
6424418919fSjohnjiang 
6434418919fSjohnjiang 	if (test_mempool_same_name_twice_creation() < 0)
6444418919fSjohnjiang 		GOTO_ERR(ret, err);
6454418919fSjohnjiang 
6464418919fSjohnjiang 	/* test the stack handler */
6474418919fSjohnjiang 	if (test_mempool_basic(mp_stack, 1) < 0)
6484418919fSjohnjiang 		GOTO_ERR(ret, err);
6494418919fSjohnjiang 
6504418919fSjohnjiang 	if (test_mempool_basic(default_pool, 1) < 0)
6514418919fSjohnjiang 		GOTO_ERR(ret, err);
6524418919fSjohnjiang 
6534418919fSjohnjiang 	rte_mempool_list_dump(stdout);
6544418919fSjohnjiang 
6554418919fSjohnjiang 	ret = 0;
6564418919fSjohnjiang 
6574418919fSjohnjiang err:
6584418919fSjohnjiang 	rte_mempool_free(mp_nocache);
6594418919fSjohnjiang 	rte_mempool_free(mp_cache);
6604418919fSjohnjiang 	rte_mempool_free(mp_stack_anon);
6614418919fSjohnjiang 	rte_mempool_free(mp_stack_mempool_iter);
6624418919fSjohnjiang 	rte_mempool_free(mp_stack);
6634418919fSjohnjiang 	rte_mempool_free(default_pool);
6644418919fSjohnjiang 
6654418919fSjohnjiang 	return ret;
6664418919fSjohnjiang }
6674418919fSjohnjiang 
6684418919fSjohnjiang REGISTER_TEST_COMMAND(mempool_autotest, test_mempool);
669