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