xref: /dpdk/app/test/test_mempool_perf.c (revision 7775adc618811cd3713403cae7d6acc5b296d558)
1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson  * Copyright(c) 2010-2014 Intel Corporation
3ed579e50SMorten Brørup  * Copyright(c) 2022 SmartShare Systems
4a9de470cSBruce Richardson  */
5a9de470cSBruce Richardson 
6a9de470cSBruce Richardson #include <string.h>
7a9de470cSBruce Richardson #include <stdio.h>
8a9de470cSBruce Richardson #include <stdlib.h>
9a9de470cSBruce Richardson #include <stdint.h>
10a9de470cSBruce Richardson #include <inttypes.h>
11a9de470cSBruce Richardson #include <stdarg.h>
12a9de470cSBruce Richardson #include <errno.h>
13a9de470cSBruce Richardson #include <sys/queue.h>
14a9de470cSBruce Richardson 
15a9de470cSBruce Richardson #include <rte_common.h>
16a9de470cSBruce Richardson #include <rte_log.h>
17a9de470cSBruce Richardson #include <rte_debug.h>
18a9de470cSBruce Richardson #include <rte_memory.h>
19a9de470cSBruce Richardson #include <rte_launch.h>
20a9de470cSBruce Richardson #include <rte_cycles.h>
21a9de470cSBruce Richardson #include <rte_eal.h>
22a9de470cSBruce Richardson #include <rte_per_lcore.h>
23a9de470cSBruce Richardson #include <rte_lcore.h>
24a9de470cSBruce Richardson #include <rte_branch_prediction.h>
25a9de470cSBruce Richardson #include <rte_mempool.h>
26a9de470cSBruce Richardson #include <rte_spinlock.h>
27a9de470cSBruce Richardson #include <rte_malloc.h>
28a9de470cSBruce Richardson #include <rte_mbuf_pool_ops.h>
29a9de470cSBruce Richardson 
30a9de470cSBruce Richardson #include "test.h"
31a9de470cSBruce Richardson 
32a9de470cSBruce Richardson /*
33a9de470cSBruce Richardson  * Mempool performance
34a9de470cSBruce Richardson  * =======
35a9de470cSBruce Richardson  *
36a9de470cSBruce Richardson  *    Each core get *n_keep* objects per bulk of *n_get_bulk*. Then,
37a9de470cSBruce Richardson  *    objects are put back in the pool per bulk of *n_put_bulk*.
38a9de470cSBruce Richardson  *
39a9de470cSBruce Richardson  *    This sequence is done during TIME_S seconds.
40a9de470cSBruce Richardson  *
41a9de470cSBruce Richardson  *    This test is done on the following configurations:
42a9de470cSBruce Richardson  *
43a9de470cSBruce Richardson  *    - Cores configuration (*cores*)
44a9de470cSBruce Richardson  *
45a9de470cSBruce Richardson  *      - One core with cache
46a9de470cSBruce Richardson  *      - Two cores with cache
47a9de470cSBruce Richardson  *      - Max. cores with cache
48a9de470cSBruce Richardson  *      - One core without cache
49a9de470cSBruce Richardson  *      - Two cores without cache
50a9de470cSBruce Richardson  *      - Max. cores without cache
51a9de470cSBruce Richardson  *      - One core with user-owned cache
52a9de470cSBruce Richardson  *      - Two cores with user-owned cache
53a9de470cSBruce Richardson  *      - Max. cores with user-owned cache
54a9de470cSBruce Richardson  *
55a9de470cSBruce Richardson  *    - Bulk size (*n_get_bulk*, *n_put_bulk*)
56a9de470cSBruce Richardson  *
57*7775adc6SMorten Brørup  *      - Bulk get from 1 to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE
58*7775adc6SMorten Brørup  *      - Bulk put from 1 to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE
59*7775adc6SMorten Brørup  *      - Bulk get and put from 1 to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE, compile time constant
60a9de470cSBruce Richardson  *
61a9de470cSBruce Richardson  *    - Number of kept objects (*n_keep*)
62a9de470cSBruce Richardson  *
63a9de470cSBruce Richardson  *      - 32
64a9de470cSBruce Richardson  *      - 128
65ed579e50SMorten Brørup  *      - 512
66*7775adc6SMorten Brørup  *      - 2048
67*7775adc6SMorten Brørup  *      - 8192
68*7775adc6SMorten Brørup  *      - 32768
69a9de470cSBruce Richardson  */
70a9de470cSBruce Richardson 
71*7775adc6SMorten Brørup #define TIME_S 1
72a9de470cSBruce Richardson #define MEMPOOL_ELT_SIZE 2048
73*7775adc6SMorten Brørup #define MAX_KEEP 32768
74*7775adc6SMorten Brørup #define N (128 * MAX_KEEP)
75*7775adc6SMorten Brørup #define MEMPOOL_SIZE ((rte_lcore_count()*(MAX_KEEP+RTE_MEMPOOL_CACHE_MAX_SIZE*2))-1)
76a9de470cSBruce Richardson 
77ed579e50SMorten Brørup /* Number of pointers fitting into one cache line. */
78ed579e50SMorten Brørup #define CACHE_LINE_BURST (RTE_CACHE_LINE_SIZE / sizeof(uintptr_t))
79ed579e50SMorten Brørup 
80a9de470cSBruce Richardson #define LOG_ERR() printf("test failed at %s():%d\n", __func__, __LINE__)
81a9de470cSBruce Richardson #define RET_ERR() do {							\
82a9de470cSBruce Richardson 		LOG_ERR();						\
83a9de470cSBruce Richardson 		return -1;						\
84a9de470cSBruce Richardson 	} while (0)
85a9de470cSBruce Richardson #define GOTO_ERR(var, label) do {					\
86a9de470cSBruce Richardson 		LOG_ERR();						\
87a9de470cSBruce Richardson 		var = -1;						\
88a9de470cSBruce Richardson 		goto label;						\
89a9de470cSBruce Richardson 	} while (0)
90a9de470cSBruce Richardson 
91a9de470cSBruce Richardson static int use_external_cache;
92a9de470cSBruce Richardson static unsigned external_cache_size = RTE_MEMPOOL_CACHE_MAX_SIZE;
93a9de470cSBruce Richardson 
94b6a7e685STyler Retzlaff static RTE_ATOMIC(uint32_t) synchro;
95a9de470cSBruce Richardson 
96a9de470cSBruce Richardson /* number of objects in one bulk operation (get or put) */
97a9de470cSBruce Richardson static unsigned n_get_bulk;
98a9de470cSBruce Richardson static unsigned n_put_bulk;
99a9de470cSBruce Richardson 
1004a6672c2SStephen Hemminger /* number of objects retrieved from mempool before putting them back */
101a9de470cSBruce Richardson static unsigned n_keep;
102a9de470cSBruce Richardson 
103ed579e50SMorten Brørup /* true if we want to test with constant n_get_bulk and n_put_bulk */
104ed579e50SMorten Brørup static int use_constant_values;
105ed579e50SMorten Brørup 
106*7775adc6SMorten Brørup /* number of enqueues / dequeues, and time used */
1070efea35aSTyler Retzlaff struct __rte_cache_aligned mempool_test_stats {
108a9de470cSBruce Richardson 	uint64_t enq_count;
109*7775adc6SMorten Brørup 	uint64_t duration_cycles;
110*7775adc6SMorten Brørup 	RTE_CACHE_GUARD;
1110efea35aSTyler Retzlaff };
112a9de470cSBruce Richardson 
113a9de470cSBruce Richardson static struct mempool_test_stats stats[RTE_MAX_LCORE];
114a9de470cSBruce Richardson 
115a9de470cSBruce Richardson /*
116a9de470cSBruce Richardson  * save the object number in the first 4 bytes of object data. All
117a9de470cSBruce Richardson  * other bytes are set to 0.
118a9de470cSBruce Richardson  */
119a9de470cSBruce Richardson static void
120f2fc83b4SThomas Monjalon my_obj_init(struct rte_mempool *mp, __rte_unused void *arg,
121a9de470cSBruce Richardson 	    void *obj, unsigned i)
122a9de470cSBruce Richardson {
123a9de470cSBruce Richardson 	uint32_t *objnum = obj;
124a9de470cSBruce Richardson 	memset(obj, 0, mp->elt_size);
125a9de470cSBruce Richardson 	*objnum = i;
126a9de470cSBruce Richardson }
127a9de470cSBruce Richardson 
128ed579e50SMorten Brørup static __rte_always_inline int
129ed579e50SMorten Brørup test_loop(struct rte_mempool *mp, struct rte_mempool_cache *cache,
130ed579e50SMorten Brørup 	  unsigned int x_keep, unsigned int x_get_bulk, unsigned int x_put_bulk)
131ed579e50SMorten Brørup {
1320efea35aSTyler Retzlaff 	alignas(RTE_CACHE_LINE_SIZE) void *obj_table[MAX_KEEP];
133ed579e50SMorten Brørup 	unsigned int idx;
134ed579e50SMorten Brørup 	unsigned int i;
135ed579e50SMorten Brørup 	int ret;
136ed579e50SMorten Brørup 
137ed579e50SMorten Brørup 	for (i = 0; likely(i < (N / x_keep)); i++) {
138ed579e50SMorten Brørup 		/* get x_keep objects by bulk of x_get_bulk */
139ed579e50SMorten Brørup 		for (idx = 0; idx < x_keep; idx += x_get_bulk) {
140ed579e50SMorten Brørup 			ret = rte_mempool_generic_get(mp,
141ed579e50SMorten Brørup 						      &obj_table[idx],
142ed579e50SMorten Brørup 						      x_get_bulk,
143ed579e50SMorten Brørup 						      cache);
144ed579e50SMorten Brørup 			if (unlikely(ret < 0)) {
145ed579e50SMorten Brørup 				rte_mempool_dump(stdout, mp);
146ed579e50SMorten Brørup 				return ret;
147ed579e50SMorten Brørup 			}
148ed579e50SMorten Brørup 		}
149ed579e50SMorten Brørup 
150ed579e50SMorten Brørup 		/* put the objects back by bulk of x_put_bulk */
151ed579e50SMorten Brørup 		for (idx = 0; idx < x_keep; idx += x_put_bulk) {
152ed579e50SMorten Brørup 			rte_mempool_generic_put(mp,
153ed579e50SMorten Brørup 						&obj_table[idx],
154ed579e50SMorten Brørup 						x_put_bulk,
155ed579e50SMorten Brørup 						cache);
156ed579e50SMorten Brørup 		}
157ed579e50SMorten Brørup 	}
158ed579e50SMorten Brørup 
159ed579e50SMorten Brørup 	return 0;
160ed579e50SMorten Brørup }
161ed579e50SMorten Brørup 
162a9de470cSBruce Richardson static int
163a9de470cSBruce Richardson per_lcore_mempool_test(void *arg)
164a9de470cSBruce Richardson {
165a9de470cSBruce Richardson 	struct rte_mempool *mp = arg;
166a9de470cSBruce Richardson 	unsigned lcore_id = rte_lcore_id();
167a9de470cSBruce Richardson 	int ret = 0;
168a9de470cSBruce Richardson 	uint64_t start_cycles, end_cycles;
169a9de470cSBruce Richardson 	uint64_t time_diff = 0, hz = rte_get_timer_hz();
170a9de470cSBruce Richardson 	struct rte_mempool_cache *cache;
171a9de470cSBruce Richardson 
172a9de470cSBruce Richardson 	if (use_external_cache) {
173a9de470cSBruce Richardson 		/* Create a user-owned mempool cache. */
174a9de470cSBruce Richardson 		cache = rte_mempool_cache_create(external_cache_size,
175a9de470cSBruce Richardson 						 SOCKET_ID_ANY);
176a9de470cSBruce Richardson 		if (cache == NULL)
177a9de470cSBruce Richardson 			RET_ERR();
178a9de470cSBruce Richardson 	} else {
179a9de470cSBruce Richardson 		/* May be NULL if cache is disabled. */
180a9de470cSBruce Richardson 		cache = rte_mempool_default_cache(mp, lcore_id);
181a9de470cSBruce Richardson 	}
182a9de470cSBruce Richardson 
183a9de470cSBruce Richardson 	/* n_get_bulk and n_put_bulk must be divisors of n_keep */
184a9de470cSBruce Richardson 	if (((n_keep / n_get_bulk) * n_get_bulk) != n_keep)
185a9de470cSBruce Richardson 		GOTO_ERR(ret, out);
186a9de470cSBruce Richardson 	if (((n_keep / n_put_bulk) * n_put_bulk) != n_keep)
187a9de470cSBruce Richardson 		GOTO_ERR(ret, out);
188ed579e50SMorten Brørup 	/* for constant n, n_get_bulk and n_put_bulk must be the same */
189ed579e50SMorten Brørup 	if (use_constant_values && n_put_bulk != n_get_bulk)
190ed579e50SMorten Brørup 		GOTO_ERR(ret, out);
191a9de470cSBruce Richardson 
192a9de470cSBruce Richardson 	stats[lcore_id].enq_count = 0;
193*7775adc6SMorten Brørup 	stats[lcore_id].duration_cycles = 0;
194a9de470cSBruce Richardson 
195cb056611SStephen Hemminger 	/* wait synchro for workers */
196cb056611SStephen Hemminger 	if (lcore_id != rte_get_main_lcore())
197b6a7e685STyler Retzlaff 		rte_wait_until_equal_32((uint32_t *)(uintptr_t)&synchro, 1,
198b6a7e685STyler Retzlaff 				rte_memory_order_relaxed);
199a9de470cSBruce Richardson 
200a9de470cSBruce Richardson 	start_cycles = rte_get_timer_cycles();
201a9de470cSBruce Richardson 
202a9de470cSBruce Richardson 	while (time_diff/hz < TIME_S) {
203ed579e50SMorten Brørup 		if (!use_constant_values)
204ed579e50SMorten Brørup 			ret = test_loop(mp, cache, n_keep, n_get_bulk, n_put_bulk);
205ed579e50SMorten Brørup 		else if (n_get_bulk == 1)
206ed579e50SMorten Brørup 			ret = test_loop(mp, cache, n_keep, 1, 1);
207ed579e50SMorten Brørup 		else if (n_get_bulk == 4)
208ed579e50SMorten Brørup 			ret = test_loop(mp, cache, n_keep, 4, 4);
209ed579e50SMorten Brørup 		else if (n_get_bulk == CACHE_LINE_BURST)
210ed579e50SMorten Brørup 			ret = test_loop(mp, cache, n_keep,
211ed579e50SMorten Brørup 					CACHE_LINE_BURST, CACHE_LINE_BURST);
212ed579e50SMorten Brørup 		else if (n_get_bulk == 32)
213ed579e50SMorten Brørup 			ret = test_loop(mp, cache, n_keep, 32, 32);
214*7775adc6SMorten Brørup 		else if (n_get_bulk == 64)
215*7775adc6SMorten Brørup 			ret = test_loop(mp, cache, n_keep, 64, 64);
216*7775adc6SMorten Brørup 		else if (n_get_bulk == 128)
217*7775adc6SMorten Brørup 			ret = test_loop(mp, cache, n_keep, 128, 128);
218*7775adc6SMorten Brørup 		else if (n_get_bulk == 256)
219*7775adc6SMorten Brørup 			ret = test_loop(mp, cache, n_keep, 256, 256);
220*7775adc6SMorten Brørup 		else if (n_get_bulk == RTE_MEMPOOL_CACHE_MAX_SIZE)
221*7775adc6SMorten Brørup 			ret = test_loop(mp, cache, n_keep,
222*7775adc6SMorten Brørup 					RTE_MEMPOOL_CACHE_MAX_SIZE, RTE_MEMPOOL_CACHE_MAX_SIZE);
223ed579e50SMorten Brørup 		else
224ed579e50SMorten Brørup 			ret = -1;
225a9de470cSBruce Richardson 
226ed579e50SMorten Brørup 		if (ret < 0)
227ed579e50SMorten Brørup 			GOTO_ERR(ret, out);
228ed579e50SMorten Brørup 
229a9de470cSBruce Richardson 		end_cycles = rte_get_timer_cycles();
230a9de470cSBruce Richardson 		time_diff = end_cycles - start_cycles;
231a9de470cSBruce Richardson 		stats[lcore_id].enq_count += N;
232a9de470cSBruce Richardson 	}
233a9de470cSBruce Richardson 
234*7775adc6SMorten Brørup 	stats[lcore_id].duration_cycles = time_diff;
235*7775adc6SMorten Brørup 
236a9de470cSBruce Richardson out:
237a9de470cSBruce Richardson 	if (use_external_cache) {
238a9de470cSBruce Richardson 		rte_mempool_cache_flush(cache, mp);
239a9de470cSBruce Richardson 		rte_mempool_cache_free(cache);
240a9de470cSBruce Richardson 	}
241a9de470cSBruce Richardson 
242a9de470cSBruce Richardson 	return ret;
243a9de470cSBruce Richardson }
244a9de470cSBruce Richardson 
245a9de470cSBruce Richardson /* launch all the per-lcore test, and display the result */
246a9de470cSBruce Richardson static int
247a9de470cSBruce Richardson launch_cores(struct rte_mempool *mp, unsigned int cores)
248a9de470cSBruce Richardson {
249a9de470cSBruce Richardson 	unsigned lcore_id;
250a9de470cSBruce Richardson 	uint64_t rate;
251a9de470cSBruce Richardson 	int ret;
252a9de470cSBruce Richardson 	unsigned cores_save = cores;
253*7775adc6SMorten Brørup 	double hz = rte_get_timer_hz();
254a9de470cSBruce Richardson 
255b6a7e685STyler Retzlaff 	rte_atomic_store_explicit(&synchro, 0, rte_memory_order_relaxed);
256a9de470cSBruce Richardson 
257a9de470cSBruce Richardson 	/* reset stats */
258a9de470cSBruce Richardson 	memset(stats, 0, sizeof(stats));
259a9de470cSBruce Richardson 
260a9de470cSBruce Richardson 	printf("mempool_autotest cache=%u cores=%u n_get_bulk=%u "
261ed579e50SMorten Brørup 	       "n_put_bulk=%u n_keep=%u constant_n=%u ",
262a9de470cSBruce Richardson 	       use_external_cache ?
263a9de470cSBruce Richardson 		   external_cache_size : (unsigned) mp->cache_size,
264ed579e50SMorten Brørup 	       cores, n_get_bulk, n_put_bulk, n_keep, use_constant_values);
265a9de470cSBruce Richardson 
266a9de470cSBruce Richardson 	if (rte_mempool_avail_count(mp) != MEMPOOL_SIZE) {
267a9de470cSBruce Richardson 		printf("mempool is not full\n");
268a9de470cSBruce Richardson 		return -1;
269a9de470cSBruce Richardson 	}
270a9de470cSBruce Richardson 
271cb056611SStephen Hemminger 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
272a9de470cSBruce Richardson 		if (cores == 1)
273a9de470cSBruce Richardson 			break;
274a9de470cSBruce Richardson 		cores--;
275a9de470cSBruce Richardson 		rte_eal_remote_launch(per_lcore_mempool_test,
276a9de470cSBruce Richardson 				      mp, lcore_id);
277a9de470cSBruce Richardson 	}
278a9de470cSBruce Richardson 
279cb056611SStephen Hemminger 	/* start synchro and launch test on main */
280b6a7e685STyler Retzlaff 	rte_atomic_store_explicit(&synchro, 1, rte_memory_order_relaxed);
281a9de470cSBruce Richardson 
282a9de470cSBruce Richardson 	ret = per_lcore_mempool_test(mp);
283a9de470cSBruce Richardson 
284a9de470cSBruce Richardson 	cores = cores_save;
285cb056611SStephen Hemminger 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
286a9de470cSBruce Richardson 		if (cores == 1)
287a9de470cSBruce Richardson 			break;
288a9de470cSBruce Richardson 		cores--;
289a9de470cSBruce Richardson 		if (rte_eal_wait_lcore(lcore_id) < 0)
290a9de470cSBruce Richardson 			ret = -1;
291a9de470cSBruce Richardson 	}
292a9de470cSBruce Richardson 
293a9de470cSBruce Richardson 	if (ret < 0) {
294a9de470cSBruce Richardson 		printf("per-lcore test returned -1\n");
295a9de470cSBruce Richardson 		return -1;
296a9de470cSBruce Richardson 	}
297a9de470cSBruce Richardson 
298a9de470cSBruce Richardson 	rate = 0;
299a9de470cSBruce Richardson 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
300*7775adc6SMorten Brørup 		if (stats[lcore_id].duration_cycles != 0)
301*7775adc6SMorten Brørup 			rate += (double)stats[lcore_id].enq_count * hz /
302*7775adc6SMorten Brørup 					(double)stats[lcore_id].duration_cycles;
303a9de470cSBruce Richardson 
304a9de470cSBruce Richardson 	printf("rate_persec=%" PRIu64 "\n", rate);
305a9de470cSBruce Richardson 
306a9de470cSBruce Richardson 	return 0;
307a9de470cSBruce Richardson }
308a9de470cSBruce Richardson 
309a9de470cSBruce Richardson /* for a given number of core, launch all test cases */
310a9de470cSBruce Richardson static int
311*7775adc6SMorten Brørup do_one_mempool_test(struct rte_mempool *mp, unsigned int cores, int external_cache)
312a9de470cSBruce Richardson {
313*7775adc6SMorten Brørup 	unsigned int bulk_tab_get[] = { 1, 4, CACHE_LINE_BURST, 32, 64, 128, 256,
314*7775adc6SMorten Brørup 			RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
315*7775adc6SMorten Brørup 	unsigned int bulk_tab_put[] = { 1, 4, CACHE_LINE_BURST, 32, 64, 128, 256,
316*7775adc6SMorten Brørup 			RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
317*7775adc6SMorten Brørup 	unsigned int keep_tab[] = { 32, 128, 512, 2048, 8192, 32768, 0 };
318a9de470cSBruce Richardson 	unsigned *get_bulk_ptr;
319a9de470cSBruce Richardson 	unsigned *put_bulk_ptr;
320a9de470cSBruce Richardson 	unsigned *keep_ptr;
321a9de470cSBruce Richardson 	int ret;
322a9de470cSBruce Richardson 
323a9de470cSBruce Richardson 	for (get_bulk_ptr = bulk_tab_get; *get_bulk_ptr; get_bulk_ptr++) {
324a9de470cSBruce Richardson 		for (put_bulk_ptr = bulk_tab_put; *put_bulk_ptr; put_bulk_ptr++) {
325a9de470cSBruce Richardson 			for (keep_ptr = keep_tab; *keep_ptr; keep_ptr++) {
326a9de470cSBruce Richardson 
327*7775adc6SMorten Brørup 				if (*keep_ptr < *get_bulk_ptr || *keep_ptr < *put_bulk_ptr)
328*7775adc6SMorten Brørup 					continue;
329*7775adc6SMorten Brørup 
330*7775adc6SMorten Brørup 				use_external_cache = external_cache;
331ed579e50SMorten Brørup 				use_constant_values = 0;
332a9de470cSBruce Richardson 				n_get_bulk = *get_bulk_ptr;
333a9de470cSBruce Richardson 				n_put_bulk = *put_bulk_ptr;
334a9de470cSBruce Richardson 				n_keep = *keep_ptr;
335a9de470cSBruce Richardson 				ret = launch_cores(mp, cores);
336a9de470cSBruce Richardson 				if (ret < 0)
337a9de470cSBruce Richardson 					return -1;
338ed579e50SMorten Brørup 
339ed579e50SMorten Brørup 				/* replay test with constant values */
340ed579e50SMorten Brørup 				if (n_get_bulk == n_put_bulk) {
341ed579e50SMorten Brørup 					use_constant_values = 1;
342ed579e50SMorten Brørup 					ret = launch_cores(mp, cores);
343ed579e50SMorten Brørup 					if (ret < 0)
344ed579e50SMorten Brørup 						return -1;
345ed579e50SMorten Brørup 				}
346a9de470cSBruce Richardson 			}
347a9de470cSBruce Richardson 		}
348a9de470cSBruce Richardson 	}
349a9de470cSBruce Richardson 	return 0;
350a9de470cSBruce Richardson }
351a9de470cSBruce Richardson 
352a9de470cSBruce Richardson static int
353*7775adc6SMorten Brørup do_all_mempool_perf_tests(unsigned int cores)
354a9de470cSBruce Richardson {
355a9de470cSBruce Richardson 	struct rte_mempool *mp_cache = NULL;
356a9de470cSBruce Richardson 	struct rte_mempool *mp_nocache = NULL;
357a9de470cSBruce Richardson 	struct rte_mempool *default_pool = NULL;
358a9de470cSBruce Richardson 	const char *default_pool_ops;
359a9de470cSBruce Richardson 	int ret = -1;
360a9de470cSBruce Richardson 
361a9de470cSBruce Richardson 	/* create a mempool (without cache) */
362a9de470cSBruce Richardson 	mp_nocache = rte_mempool_create("perf_test_nocache", MEMPOOL_SIZE,
363a9de470cSBruce Richardson 					MEMPOOL_ELT_SIZE, 0, 0,
364a9de470cSBruce Richardson 					NULL, NULL,
365a9de470cSBruce Richardson 					my_obj_init, NULL,
366a9de470cSBruce Richardson 					SOCKET_ID_ANY, 0);
367*7775adc6SMorten Brørup 	if (mp_nocache == NULL) {
368*7775adc6SMorten Brørup 		printf("cannot allocate mempool (without cache)\n");
369a9de470cSBruce Richardson 		goto err;
370*7775adc6SMorten Brørup 	}
371a9de470cSBruce Richardson 
372a9de470cSBruce Richardson 	/* create a mempool (with cache) */
373a9de470cSBruce Richardson 	mp_cache = rte_mempool_create("perf_test_cache", MEMPOOL_SIZE,
374a9de470cSBruce Richardson 				      MEMPOOL_ELT_SIZE,
375a9de470cSBruce Richardson 				      RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
376a9de470cSBruce Richardson 				      NULL, NULL,
377a9de470cSBruce Richardson 				      my_obj_init, NULL,
378a9de470cSBruce Richardson 				      SOCKET_ID_ANY, 0);
379*7775adc6SMorten Brørup 	if (mp_cache == NULL) {
380*7775adc6SMorten Brørup 		printf("cannot allocate mempool (with cache)\n");
381a9de470cSBruce Richardson 		goto err;
382*7775adc6SMorten Brørup 	}
383a9de470cSBruce Richardson 
384a9de470cSBruce Richardson 	default_pool_ops = rte_mbuf_best_mempool_ops();
385a9de470cSBruce Richardson 	/* Create a mempool based on Default handler */
386a9de470cSBruce Richardson 	default_pool = rte_mempool_create_empty("default_pool",
387a9de470cSBruce Richardson 						MEMPOOL_SIZE,
388a9de470cSBruce Richardson 						MEMPOOL_ELT_SIZE,
389a9de470cSBruce Richardson 						0, 0,
390a9de470cSBruce Richardson 						SOCKET_ID_ANY, 0);
391a9de470cSBruce Richardson 
392a9de470cSBruce Richardson 	if (default_pool == NULL) {
393a9de470cSBruce Richardson 		printf("cannot allocate %s mempool\n", default_pool_ops);
394a9de470cSBruce Richardson 		goto err;
395a9de470cSBruce Richardson 	}
396a9de470cSBruce Richardson 
397a9de470cSBruce Richardson 	if (rte_mempool_set_ops_byname(default_pool, default_pool_ops, NULL)
398a9de470cSBruce Richardson 				       < 0) {
399a9de470cSBruce Richardson 		printf("cannot set %s handler\n", default_pool_ops);
400a9de470cSBruce Richardson 		goto err;
401a9de470cSBruce Richardson 	}
402a9de470cSBruce Richardson 
403a9de470cSBruce Richardson 	if (rte_mempool_populate_default(default_pool) < 0) {
404a9de470cSBruce Richardson 		printf("cannot populate %s mempool\n", default_pool_ops);
405a9de470cSBruce Richardson 		goto err;
406a9de470cSBruce Richardson 	}
407a9de470cSBruce Richardson 
408a9de470cSBruce Richardson 	rte_mempool_obj_iter(default_pool, my_obj_init, NULL);
409a9de470cSBruce Richardson 
410a9de470cSBruce Richardson 	printf("start performance test (without cache)\n");
411*7775adc6SMorten Brørup 	if (do_one_mempool_test(mp_nocache, cores, 0) < 0)
412a9de470cSBruce Richardson 		goto err;
413a9de470cSBruce Richardson 
414a9de470cSBruce Richardson 	printf("start performance test for %s (without cache)\n",
415a9de470cSBruce Richardson 	       default_pool_ops);
416*7775adc6SMorten Brørup 	if (do_one_mempool_test(default_pool, cores, 0) < 0)
417a9de470cSBruce Richardson 		goto err;
418a9de470cSBruce Richardson 
419a9de470cSBruce Richardson 	printf("start performance test (with cache)\n");
420*7775adc6SMorten Brørup 	if (do_one_mempool_test(mp_cache, cores, 0) < 0)
421a9de470cSBruce Richardson 		goto err;
422a9de470cSBruce Richardson 
423a9de470cSBruce Richardson 	printf("start performance test (with user-owned cache)\n");
424*7775adc6SMorten Brørup 	if (do_one_mempool_test(mp_nocache, cores, 1) < 0)
425a9de470cSBruce Richardson 		goto err;
426a9de470cSBruce Richardson 
427a9de470cSBruce Richardson 	rte_mempool_list_dump(stdout);
428a9de470cSBruce Richardson 
429a9de470cSBruce Richardson 	ret = 0;
430a9de470cSBruce Richardson 
431a9de470cSBruce Richardson err:
432a9de470cSBruce Richardson 	rte_mempool_free(mp_cache);
433a9de470cSBruce Richardson 	rte_mempool_free(mp_nocache);
434a9de470cSBruce Richardson 	rte_mempool_free(default_pool);
435a9de470cSBruce Richardson 	return ret;
436a9de470cSBruce Richardson }
437a9de470cSBruce Richardson 
438*7775adc6SMorten Brørup static int
439*7775adc6SMorten Brørup test_mempool_perf_1core(void)
440*7775adc6SMorten Brørup {
441*7775adc6SMorten Brørup 	return do_all_mempool_perf_tests(1);
442*7775adc6SMorten Brørup }
443*7775adc6SMorten Brørup 
444*7775adc6SMorten Brørup static int
445*7775adc6SMorten Brørup test_mempool_perf_2cores(void)
446*7775adc6SMorten Brørup {
447*7775adc6SMorten Brørup 	if (rte_lcore_count() < 2) {
448*7775adc6SMorten Brørup 		printf("not enough lcores\n");
449*7775adc6SMorten Brørup 		return -1;
450*7775adc6SMorten Brørup 	}
451*7775adc6SMorten Brørup 	return do_all_mempool_perf_tests(2);
452*7775adc6SMorten Brørup }
453*7775adc6SMorten Brørup 
454*7775adc6SMorten Brørup static int
455*7775adc6SMorten Brørup test_mempool_perf_allcores(void)
456*7775adc6SMorten Brørup {
457*7775adc6SMorten Brørup 	return do_all_mempool_perf_tests(rte_lcore_count());
458*7775adc6SMorten Brørup }
459*7775adc6SMorten Brørup 
460*7775adc6SMorten Brørup static int
461*7775adc6SMorten Brørup test_mempool_perf(void)
462*7775adc6SMorten Brørup {
463*7775adc6SMorten Brørup 	int ret = -1;
464*7775adc6SMorten Brørup 
465*7775adc6SMorten Brørup 	/* performance test with 1, 2 and max cores */
466*7775adc6SMorten Brørup 	if (do_all_mempool_perf_tests(1) < 0)
467*7775adc6SMorten Brørup 		goto err;
468*7775adc6SMorten Brørup 	if (rte_lcore_count() == 1)
469*7775adc6SMorten Brørup 		goto done;
470*7775adc6SMorten Brørup 
471*7775adc6SMorten Brørup 	if (do_all_mempool_perf_tests(2) < 0)
472*7775adc6SMorten Brørup 		goto err;
473*7775adc6SMorten Brørup 	if (rte_lcore_count() == 2)
474*7775adc6SMorten Brørup 		goto done;
475*7775adc6SMorten Brørup 
476*7775adc6SMorten Brørup 	if (do_all_mempool_perf_tests(rte_lcore_count()) < 0)
477*7775adc6SMorten Brørup 		goto err;
478*7775adc6SMorten Brørup 
479*7775adc6SMorten Brørup done:
480*7775adc6SMorten Brørup 	ret = 0;
481*7775adc6SMorten Brørup 
482*7775adc6SMorten Brørup err:
483*7775adc6SMorten Brørup 	return ret;
484*7775adc6SMorten Brørup }
485*7775adc6SMorten Brørup 
486e0a8442cSBruce Richardson REGISTER_PERF_TEST(mempool_perf_autotest, test_mempool_perf);
487*7775adc6SMorten Brørup REGISTER_PERF_TEST(mempool_perf_autotest_1core, test_mempool_perf_1core);
488*7775adc6SMorten Brørup REGISTER_PERF_TEST(mempool_perf_autotest_2cores, test_mempool_perf_2cores);
489*7775adc6SMorten Brørup REGISTER_PERF_TEST(mempool_perf_autotest_allcores, test_mempool_perf_allcores);
490