1*70581c35SKonstantin Ananyev /* SPDX-License-Identifier: BSD-3-Clause 2*70581c35SKonstantin Ananyev */ 3*70581c35SKonstantin Ananyev 4*70581c35SKonstantin Ananyev #include <stdalign.h> 5*70581c35SKonstantin Ananyev 6*70581c35SKonstantin Ananyev #include "test_soring_stress.h" 7*70581c35SKonstantin Ananyev 8*70581c35SKonstantin Ananyev /** 9*70581c35SKonstantin Ananyev * Stress test for soring enqueue/dequeue/acquire/release operations. 10*70581c35SKonstantin Ananyev * Depending on the role, performs at least one of the following patterns 11*70581c35SKonstantin Ananyev * on each worker: 12*70581c35SKonstantin Ananyev * - dequeue/read-write data from/to the dequeued objects/enqueue. 13*70581c35SKonstantin Ananyev * - acquire/read-write data from/to the acquired objects/release. 14*70581c35SKonstantin Ananyev * Serves as both functional and performance test of soring 15*70581c35SKonstantin Ananyev * data-path API under high contention 16*70581c35SKonstantin Ananyev * (for both over committed and non-over committed scenarios). 17*70581c35SKonstantin Ananyev */ 18*70581c35SKonstantin Ananyev 19*70581c35SKonstantin Ananyev #define RING_NAME "SORING_STRESS" 20*70581c35SKonstantin Ananyev #define BULK_NUM 32 21*70581c35SKonstantin Ananyev #define RING_SIZE (2 * BULK_NUM * RTE_MAX_LCORE) 22*70581c35SKonstantin Ananyev 23*70581c35SKonstantin Ananyev #define MAX_STAGES 16 24*70581c35SKonstantin Ananyev 25*70581c35SKonstantin Ananyev enum { 26*70581c35SKonstantin Ananyev WRK_CMD_STOP, 27*70581c35SKonstantin Ananyev WRK_CMD_RUN, 28*70581c35SKonstantin Ananyev }; 29*70581c35SKonstantin Ananyev 30*70581c35SKonstantin Ananyev static alignas(RTE_CACHE_LINE_SIZE) RTE_ATOMIC(uint32_t) wrk_cmd = WRK_CMD_STOP; 31*70581c35SKonstantin Ananyev 32*70581c35SKonstantin Ananyev /* test run-time in seconds */ 33*70581c35SKonstantin Ananyev static const uint32_t run_time = 60; 34*70581c35SKonstantin Ananyev static const uint32_t verbose; 35*70581c35SKonstantin Ananyev 36*70581c35SKonstantin Ananyev static rte_spinlock_t dump_lock; 37*70581c35SKonstantin Ananyev 38*70581c35SKonstantin Ananyev struct lcore_op_stat { 39*70581c35SKonstantin Ananyev uint64_t nb_lcore; 40*70581c35SKonstantin Ananyev uint64_t nb_call; 41*70581c35SKonstantin Ananyev uint64_t nb_obj; 42*70581c35SKonstantin Ananyev uint64_t nb_cycle; 43*70581c35SKonstantin Ananyev uint64_t max_cycle; 44*70581c35SKonstantin Ananyev uint64_t min_cycle; 45*70581c35SKonstantin Ananyev }; 46*70581c35SKonstantin Ananyev 47*70581c35SKonstantin Ananyev struct lcore_stat { 48*70581c35SKonstantin Ananyev uint64_t nb_cycle; 49*70581c35SKonstantin Ananyev struct lcore_op_stat deqenq; 50*70581c35SKonstantin Ananyev uint32_t role_mask; 51*70581c35SKonstantin Ananyev uint32_t nb_stage; 52*70581c35SKonstantin Ananyev struct lcore_op_stat stage[MAX_STAGES]; 53*70581c35SKonstantin Ananyev }; 54*70581c35SKonstantin Ananyev 55*70581c35SKonstantin Ananyev #define ROLE_DEQENQ RTE_BIT32(0) 56*70581c35SKonstantin Ananyev #define ROLE_STAGE(n) RTE_BIT32(n + 1) 57*70581c35SKonstantin Ananyev 58*70581c35SKonstantin Ananyev struct __rte_cache_aligned lcore_arg { 59*70581c35SKonstantin Ananyev struct rte_soring *rng; 60*70581c35SKonstantin Ananyev struct lcore_stat stats; 61*70581c35SKonstantin Ananyev }; 62*70581c35SKonstantin Ananyev 63*70581c35SKonstantin Ananyev struct __rte_cache_aligned ring_elem { 64*70581c35SKonstantin Ananyev uint32_t cnt[RTE_CACHE_LINE_SIZE / sizeof(uint32_t)]; 65*70581c35SKonstantin Ananyev }; 66*70581c35SKonstantin Ananyev 67*70581c35SKonstantin Ananyev /* 68*70581c35SKonstantin Ananyev * redefinable functions 69*70581c35SKonstantin Ananyev */ 70*70581c35SKonstantin Ananyev 71*70581c35SKonstantin Ananyev static uint32_t 72*70581c35SKonstantin Ananyev _st_ring_dequeue_burst(struct rte_soring *r, void **obj, uint32_t n, 73*70581c35SKonstantin Ananyev uint32_t *avail); 74*70581c35SKonstantin Ananyev 75*70581c35SKonstantin Ananyev static uint32_t 76*70581c35SKonstantin Ananyev _st_ring_enqueue_bulk(struct rte_soring *r, void * const *obj, uint32_t n, 77*70581c35SKonstantin Ananyev uint32_t *free); 78*70581c35SKonstantin Ananyev 79*70581c35SKonstantin Ananyev static uint32_t 80*70581c35SKonstantin Ananyev _st_ring_acquire_burst(struct rte_soring *r, uint32_t stage, void **obj, 81*70581c35SKonstantin Ananyev uint32_t num, uint32_t *token, uint32_t *avail); 82*70581c35SKonstantin Ananyev 83*70581c35SKonstantin Ananyev static void 84*70581c35SKonstantin Ananyev _st_ring_release(struct rte_soring *r, uint32_t stage, uint32_t token, 85*70581c35SKonstantin Ananyev void * const *obj, uint32_t num); 86*70581c35SKonstantin Ananyev 87*70581c35SKonstantin Ananyev static void 88*70581c35SKonstantin Ananyev lcore_op_stat_update(struct lcore_op_stat *ls, uint64_t call, uint64_t obj, 89*70581c35SKonstantin Ananyev uint64_t tm, int32_t prcs) 90*70581c35SKonstantin Ananyev { 91*70581c35SKonstantin Ananyev ls->nb_call += call; 92*70581c35SKonstantin Ananyev ls->nb_obj += obj; 93*70581c35SKonstantin Ananyev ls->nb_cycle += tm; 94*70581c35SKonstantin Ananyev if (prcs) { 95*70581c35SKonstantin Ananyev ls->max_cycle = RTE_MAX(ls->max_cycle, tm); 96*70581c35SKonstantin Ananyev ls->min_cycle = RTE_MIN(ls->min_cycle, tm); 97*70581c35SKonstantin Ananyev } 98*70581c35SKonstantin Ananyev } 99*70581c35SKonstantin Ananyev 100*70581c35SKonstantin Ananyev static void 101*70581c35SKonstantin Ananyev lcore_stat_update(struct lcore_stat *ls, uint64_t call, uint64_t obj, 102*70581c35SKonstantin Ananyev uint64_t tm, int32_t prcs) 103*70581c35SKonstantin Ananyev { 104*70581c35SKonstantin Ananyev uint32_t i; 105*70581c35SKonstantin Ananyev 106*70581c35SKonstantin Ananyev ls->nb_cycle += tm; 107*70581c35SKonstantin Ananyev lcore_op_stat_update(&ls->deqenq, call, obj, tm, prcs); 108*70581c35SKonstantin Ananyev for (i = 0; i != ls->nb_stage; i++) 109*70581c35SKonstantin Ananyev lcore_op_stat_update(ls->stage + i, call, obj, tm, prcs); 110*70581c35SKonstantin Ananyev } 111*70581c35SKonstantin Ananyev 112*70581c35SKonstantin Ananyev static void 113*70581c35SKonstantin Ananyev lcore_op_stat_aggr(struct lcore_op_stat *ms, const struct lcore_op_stat *ls) 114*70581c35SKonstantin Ananyev { 115*70581c35SKonstantin Ananyev ms->nb_call += ls->nb_call; 116*70581c35SKonstantin Ananyev ms->nb_obj += ls->nb_obj; 117*70581c35SKonstantin Ananyev ms->nb_cycle += ls->nb_cycle; 118*70581c35SKonstantin Ananyev ms->max_cycle = RTE_MAX(ms->max_cycle, ls->max_cycle); 119*70581c35SKonstantin Ananyev ms->min_cycle = RTE_MIN(ms->min_cycle, ls->min_cycle); 120*70581c35SKonstantin Ananyev } 121*70581c35SKonstantin Ananyev 122*70581c35SKonstantin Ananyev static void 123*70581c35SKonstantin Ananyev lcore_stat_aggr(struct lcore_stat *ms, const struct lcore_stat *ls) 124*70581c35SKonstantin Ananyev { 125*70581c35SKonstantin Ananyev uint32_t i; 126*70581c35SKonstantin Ananyev 127*70581c35SKonstantin Ananyev ms->nb_cycle = RTE_MAX(ms->nb_cycle, ls->nb_cycle); 128*70581c35SKonstantin Ananyev lcore_op_stat_aggr(&ms->deqenq, &ls->deqenq); 129*70581c35SKonstantin Ananyev ms->deqenq.nb_lcore += ((ls->role_mask & ROLE_DEQENQ) != 0); 130*70581c35SKonstantin Ananyev for (i = 0; i != ms->nb_stage; i++) { 131*70581c35SKonstantin Ananyev lcore_op_stat_aggr(ms->stage + i, ls->stage + i); 132*70581c35SKonstantin Ananyev ms->stage[i].nb_lcore += ((ls->role_mask & ROLE_STAGE(i)) != 0); 133*70581c35SKonstantin Ananyev } 134*70581c35SKonstantin Ananyev } 135*70581c35SKonstantin Ananyev 136*70581c35SKonstantin Ananyev static void 137*70581c35SKonstantin Ananyev lcore_op_stat_dump(FILE *f, const struct lcore_op_stat *ls, const char *cap, 138*70581c35SKonstantin Ananyev long double st) 139*70581c35SKonstantin Ananyev { 140*70581c35SKonstantin Ananyev fprintf(f, "\t%s={\n", cap); 141*70581c35SKonstantin Ananyev 142*70581c35SKonstantin Ananyev fprintf(f, "\t\tnb_lcore=%" PRIu64 ",\n", ls->nb_lcore); 143*70581c35SKonstantin Ananyev fprintf(f, "\t\tnb_call=%" PRIu64 ",\n", ls->nb_call); 144*70581c35SKonstantin Ananyev fprintf(f, "\t\tnb_obj=%" PRIu64 ",\n", ls->nb_obj); 145*70581c35SKonstantin Ananyev fprintf(f, "\t\tnb_cycle=%" PRIu64 ",\n", ls->nb_cycle); 146*70581c35SKonstantin Ananyev fprintf(f, "\t\tobj/call(avg): %.2Lf\n", 147*70581c35SKonstantin Ananyev (long double)ls->nb_obj / ls->nb_call); 148*70581c35SKonstantin Ananyev fprintf(f, "\t\tcycles/obj(avg): %.2Lf\n", 149*70581c35SKonstantin Ananyev (long double)ls->nb_cycle / ls->nb_obj); 150*70581c35SKonstantin Ananyev fprintf(f, "\t\tcycles/call(avg): %.2Lf\n", 151*70581c35SKonstantin Ananyev (long double)ls->nb_cycle / ls->nb_call); 152*70581c35SKonstantin Ananyev 153*70581c35SKonstantin Ananyev /* if min/max cycles per call stats was collected */ 154*70581c35SKonstantin Ananyev if (ls->min_cycle != UINT64_MAX) { 155*70581c35SKonstantin Ananyev fprintf(f, "\t\tmax cycles/call=%" PRIu64 "(%.2Lf usec),\n", 156*70581c35SKonstantin Ananyev ls->max_cycle, 157*70581c35SKonstantin Ananyev (long double)ls->max_cycle / st); 158*70581c35SKonstantin Ananyev fprintf(f, "\t\tmin cycles/call=%" PRIu64 "(%.2Lf usec),\n", 159*70581c35SKonstantin Ananyev ls->min_cycle, 160*70581c35SKonstantin Ananyev (long double)ls->min_cycle / st); 161*70581c35SKonstantin Ananyev } 162*70581c35SKonstantin Ananyev 163*70581c35SKonstantin Ananyev fprintf(f, "\t},\n"); 164*70581c35SKonstantin Ananyev } 165*70581c35SKonstantin Ananyev 166*70581c35SKonstantin Ananyev static void 167*70581c35SKonstantin Ananyev lcore_stat_dump(FILE *f, uint32_t lc, const struct lcore_stat *ls) 168*70581c35SKonstantin Ananyev { 169*70581c35SKonstantin Ananyev uint32_t i; 170*70581c35SKonstantin Ananyev long double st; 171*70581c35SKonstantin Ananyev char cap[64]; 172*70581c35SKonstantin Ananyev 173*70581c35SKonstantin Ananyev st = (long double)rte_get_timer_hz() / US_PER_S; 174*70581c35SKonstantin Ananyev 175*70581c35SKonstantin Ananyev if (lc == UINT32_MAX) 176*70581c35SKonstantin Ananyev fprintf(f, "%s(AGGREGATE)={\n", __func__); 177*70581c35SKonstantin Ananyev else 178*70581c35SKonstantin Ananyev fprintf(f, "%s(lcore=%u)={\n", __func__, lc); 179*70581c35SKonstantin Ananyev 180*70581c35SKonstantin Ananyev fprintf(f, "\tnb_cycle=%" PRIu64 "(%.2Lf usec),\n", 181*70581c35SKonstantin Ananyev ls->nb_cycle, (long double)ls->nb_cycle / st); 182*70581c35SKonstantin Ananyev 183*70581c35SKonstantin Ananyev lcore_op_stat_dump(f, &ls->deqenq, "DEQ+ENQ", st); 184*70581c35SKonstantin Ananyev for (i = 0; i != ls->nb_stage; i++) { 185*70581c35SKonstantin Ananyev snprintf(cap, sizeof(cap), "%s#%u", "STAGE", i); 186*70581c35SKonstantin Ananyev lcore_op_stat_dump(f, ls->stage + i, cap, st); 187*70581c35SKonstantin Ananyev } 188*70581c35SKonstantin Ananyev 189*70581c35SKonstantin Ananyev fprintf(f, "};\n"); 190*70581c35SKonstantin Ananyev } 191*70581c35SKonstantin Ananyev 192*70581c35SKonstantin Ananyev static void 193*70581c35SKonstantin Ananyev fill_ring_elm(struct ring_elem *elm, uint32_t fill) 194*70581c35SKonstantin Ananyev { 195*70581c35SKonstantin Ananyev uint32_t i; 196*70581c35SKonstantin Ananyev 197*70581c35SKonstantin Ananyev for (i = 0; i != RTE_DIM(elm->cnt); i++) 198*70581c35SKonstantin Ananyev elm->cnt[i] = fill; 199*70581c35SKonstantin Ananyev } 200*70581c35SKonstantin Ananyev 201*70581c35SKonstantin Ananyev static int32_t 202*70581c35SKonstantin Ananyev check_updt_elem(struct ring_elem *elm[], uint32_t num, 203*70581c35SKonstantin Ananyev const struct ring_elem *check, const struct ring_elem *fill, 204*70581c35SKonstantin Ananyev const char *fname, const char *opname, const struct rte_soring *sor) 205*70581c35SKonstantin Ananyev { 206*70581c35SKonstantin Ananyev uint32_t i; 207*70581c35SKonstantin Ananyev 208*70581c35SKonstantin Ananyev for (i = 0; i != num; i++) { 209*70581c35SKonstantin Ananyev if (memcmp(check, elm[i], sizeof(*check)) != 0) { 210*70581c35SKonstantin Ananyev rte_spinlock_lock(&dump_lock); 211*70581c35SKonstantin Ananyev printf("%s:%s: %s(lc=%u, num=%u) failed at %u-th iter, " 212*70581c35SKonstantin Ananyev "offending object: %p\n", 213*70581c35SKonstantin Ananyev fname, opname, __func__, rte_lcore_id(), num, i, 214*70581c35SKonstantin Ananyev elm[i]); 215*70581c35SKonstantin Ananyev rte_memdump(stdout, "expected", check, sizeof(*check)); 216*70581c35SKonstantin Ananyev rte_memdump(stdout, "result", elm[i], sizeof(*elm[i])); 217*70581c35SKonstantin Ananyev rte_soring_dump(stdout, sor); 218*70581c35SKonstantin Ananyev rte_spinlock_unlock(&dump_lock); 219*70581c35SKonstantin Ananyev return -EINVAL; 220*70581c35SKonstantin Ananyev } 221*70581c35SKonstantin Ananyev memcpy(elm[i], fill, sizeof(*elm[i])); 222*70581c35SKonstantin Ananyev } 223*70581c35SKonstantin Ananyev 224*70581c35SKonstantin Ananyev return 0; 225*70581c35SKonstantin Ananyev } 226*70581c35SKonstantin Ananyev 227*70581c35SKonstantin Ananyev static int 228*70581c35SKonstantin Ananyev check_ring_op(uint32_t exp, uint32_t res, uint32_t lc, 229*70581c35SKonstantin Ananyev enum rte_ring_queue_behavior bhv, const char *fname, const char *opname, 230*70581c35SKonstantin Ananyev const struct rte_soring *sor) 231*70581c35SKonstantin Ananyev { 232*70581c35SKonstantin Ananyev if ((bhv == RTE_RING_QUEUE_FIXED && exp != res) || 233*70581c35SKonstantin Ananyev (bhv == RTE_RING_QUEUE_VARIABLE && exp < res)) { 234*70581c35SKonstantin Ananyev rte_spinlock_lock(&dump_lock); 235*70581c35SKonstantin Ananyev printf("%s(lc=%u) failure: %s expected: %u, returned %u\n", 236*70581c35SKonstantin Ananyev fname, lc, opname, exp, res); 237*70581c35SKonstantin Ananyev rte_soring_dump(stdout, sor); 238*70581c35SKonstantin Ananyev rte_spinlock_unlock(&dump_lock); 239*70581c35SKonstantin Ananyev return -ENOSPC; 240*70581c35SKonstantin Ananyev } 241*70581c35SKonstantin Ananyev return 0; 242*70581c35SKonstantin Ananyev } 243*70581c35SKonstantin Ananyev 244*70581c35SKonstantin Ananyev /* num in interval [7/8, 11/8] of BULK_NUM */ 245*70581c35SKonstantin Ananyev static inline uint32_t 246*70581c35SKonstantin Ananyev rand_elem_num(void) 247*70581c35SKonstantin Ananyev { 248*70581c35SKonstantin Ananyev uint32_t num; 249*70581c35SKonstantin Ananyev 250*70581c35SKonstantin Ananyev num = 7 * BULK_NUM / 8 + rte_rand() % (BULK_NUM / 2); 251*70581c35SKonstantin Ananyev return num; 252*70581c35SKonstantin Ananyev } 253*70581c35SKonstantin Ananyev 254*70581c35SKonstantin Ananyev /* 255*70581c35SKonstantin Ananyev * for each enabled stage do: 256*70581c35SKonstantin Ananyev * acquire burst of objects 257*70581c35SKonstantin Ananyev * read and check their contents 258*70581c35SKonstantin Ananyev * update and check their contents 259*70581c35SKonstantin Ananyev * release burst of objects 260*70581c35SKonstantin Ananyev * done 261*70581c35SKonstantin Ananyev */ 262*70581c35SKonstantin Ananyev static int32_t 263*70581c35SKonstantin Ananyev test_worker_stages(struct lcore_arg *la, uint32_t lc, const char *fname, 264*70581c35SKonstantin Ananyev struct ring_elem *obj[2 * BULK_NUM], 265*70581c35SKonstantin Ananyev const struct ring_elem *def_elm, const struct ring_elem *loc_elm, 266*70581c35SKonstantin Ananyev const struct ring_elem stg_elm[MAX_STAGES], int32_t prcs) 267*70581c35SKonstantin Ananyev { 268*70581c35SKonstantin Ananyev int32_t rc; 269*70581c35SKonstantin Ananyev uint32_t i, n, num, tkn; 270*70581c35SKonstantin Ananyev uint64_t tm0, tm1; 271*70581c35SKonstantin Ananyev const struct ring_elem *celm, *pelm; 272*70581c35SKonstantin Ananyev 273*70581c35SKonstantin Ananyev num = rand_elem_num(); 274*70581c35SKonstantin Ananyev 275*70581c35SKonstantin Ananyev rc = 0; 276*70581c35SKonstantin Ananyev tkn = 0; 277*70581c35SKonstantin Ananyev for (i = 0, pelm = def_elm; i != la->stats.nb_stage; pelm = celm, i++) { 278*70581c35SKonstantin Ananyev 279*70581c35SKonstantin Ananyev celm = stg_elm + i; 280*70581c35SKonstantin Ananyev 281*70581c35SKonstantin Ananyev /* given stage is not enabled on that lcore */ 282*70581c35SKonstantin Ananyev if ((la->stats.role_mask & ROLE_STAGE(i)) == 0) 283*70581c35SKonstantin Ananyev continue; 284*70581c35SKonstantin Ananyev 285*70581c35SKonstantin Ananyev /* reset all pointer values */ 286*70581c35SKonstantin Ananyev memset(obj, 0, sizeof(*obj) * num); 287*70581c35SKonstantin Ananyev 288*70581c35SKonstantin Ananyev /* acquire num elems */ 289*70581c35SKonstantin Ananyev tm0 = (prcs != 0) ? rte_rdtsc_precise() : 0; 290*70581c35SKonstantin Ananyev n = _st_ring_acquire_burst(la->rng, i, (void **)obj, num, 291*70581c35SKonstantin Ananyev &tkn, NULL); 292*70581c35SKonstantin Ananyev tm0 = (prcs != 0) ? rte_rdtsc_precise() - tm0 : 0; 293*70581c35SKonstantin Ananyev 294*70581c35SKonstantin Ananyev /* check return value and objects */ 295*70581c35SKonstantin Ananyev rc = check_ring_op(num, n, lc, RTE_RING_QUEUE_VARIABLE, fname, 296*70581c35SKonstantin Ananyev RTE_STR(_st_ring_stage_acquire), la->rng); 297*70581c35SKonstantin Ananyev if (rc == 0) 298*70581c35SKonstantin Ananyev rc = check_updt_elem(obj, n, pelm, loc_elm, fname, 299*70581c35SKonstantin Ananyev RTE_STR(_st_ring_stage_acquire), la->rng); 300*70581c35SKonstantin Ananyev if (rc != 0) 301*70581c35SKonstantin Ananyev break; 302*70581c35SKonstantin Ananyev 303*70581c35SKonstantin Ananyev /* release num elems */ 304*70581c35SKonstantin Ananyev rte_compiler_barrier(); 305*70581c35SKonstantin Ananyev rc = check_updt_elem(obj, n, loc_elm, celm, fname, 306*70581c35SKonstantin Ananyev RTE_STR(_st_ring_stage_release), la->rng); 307*70581c35SKonstantin Ananyev if (rc != 0) 308*70581c35SKonstantin Ananyev break; 309*70581c35SKonstantin Ananyev 310*70581c35SKonstantin Ananyev if (n == 0) 311*70581c35SKonstantin Ananyev tm1 = 0; 312*70581c35SKonstantin Ananyev else { 313*70581c35SKonstantin Ananyev tm1 = (prcs != 0) ? rte_rdtsc_precise() : 0; 314*70581c35SKonstantin Ananyev _st_ring_release(la->rng, i, tkn, 315*70581c35SKonstantin Ananyev (void **)obj, n); 316*70581c35SKonstantin Ananyev tm1 = (prcs != 0) ? rte_rdtsc_precise() - tm1 : 0; 317*70581c35SKonstantin Ananyev } 318*70581c35SKonstantin Ananyev lcore_op_stat_update(la->stats.stage + i, 1, n, tm0 + tm1, 319*70581c35SKonstantin Ananyev prcs); 320*70581c35SKonstantin Ananyev } 321*70581c35SKonstantin Ananyev 322*70581c35SKonstantin Ananyev return rc; 323*70581c35SKonstantin Ananyev } 324*70581c35SKonstantin Ananyev 325*70581c35SKonstantin Ananyev static int32_t 326*70581c35SKonstantin Ananyev test_worker_deqenq(struct lcore_arg *la, uint32_t lc, const char *fname, 327*70581c35SKonstantin Ananyev struct ring_elem *obj[2 * BULK_NUM], 328*70581c35SKonstantin Ananyev const struct ring_elem *def_elm, const struct ring_elem *loc_elm, 329*70581c35SKonstantin Ananyev const struct ring_elem *pelm, int32_t prcs) 330*70581c35SKonstantin Ananyev { 331*70581c35SKonstantin Ananyev int32_t rc; 332*70581c35SKonstantin Ananyev uint32_t k, n, num; 333*70581c35SKonstantin Ananyev uint64_t tm0, tm1; 334*70581c35SKonstantin Ananyev 335*70581c35SKonstantin Ananyev num = rand_elem_num(); 336*70581c35SKonstantin Ananyev 337*70581c35SKonstantin Ananyev /* reset all pointer values */ 338*70581c35SKonstantin Ananyev memset(obj, 0, sizeof(*obj) * num); 339*70581c35SKonstantin Ananyev 340*70581c35SKonstantin Ananyev /* dequeue num elems */ 341*70581c35SKonstantin Ananyev tm0 = (prcs != 0) ? rte_rdtsc_precise() : 0; 342*70581c35SKonstantin Ananyev n = _st_ring_dequeue_burst(la->rng, (void **)obj, num, NULL); 343*70581c35SKonstantin Ananyev 344*70581c35SKonstantin Ananyev tm0 = (prcs != 0) ? rte_rdtsc_precise() - tm0 : 0; 345*70581c35SKonstantin Ananyev 346*70581c35SKonstantin Ananyev /* check return value and objects */ 347*70581c35SKonstantin Ananyev rc = check_ring_op(num, n, lc, RTE_RING_QUEUE_VARIABLE, fname, 348*70581c35SKonstantin Ananyev RTE_STR(_st_ring_dequeue_bulk), la->rng); 349*70581c35SKonstantin Ananyev if (rc == 0) 350*70581c35SKonstantin Ananyev rc = check_updt_elem(obj, n, pelm, loc_elm, fname, 351*70581c35SKonstantin Ananyev RTE_STR(_st_ring_dequeue_bulk), la->rng); 352*70581c35SKonstantin Ananyev if (rc != 0) 353*70581c35SKonstantin Ananyev return rc; 354*70581c35SKonstantin Ananyev 355*70581c35SKonstantin Ananyev /* enqueue n elems */ 356*70581c35SKonstantin Ananyev rte_compiler_barrier(); 357*70581c35SKonstantin Ananyev rc = check_updt_elem(obj, n, loc_elm, def_elm, fname, 358*70581c35SKonstantin Ananyev RTE_STR(_st_ring_enqueue_bulk), la->rng); 359*70581c35SKonstantin Ananyev if (rc != 0) 360*70581c35SKonstantin Ananyev return rc; 361*70581c35SKonstantin Ananyev 362*70581c35SKonstantin Ananyev tm1 = (prcs != 0) ? rte_rdtsc_precise() : 0; 363*70581c35SKonstantin Ananyev k = _st_ring_enqueue_bulk(la->rng, (void **)obj, n, NULL); 364*70581c35SKonstantin Ananyev tm1 = (prcs != 0) ? rte_rdtsc_precise() - tm1 : 0; 365*70581c35SKonstantin Ananyev 366*70581c35SKonstantin Ananyev /* check return value */ 367*70581c35SKonstantin Ananyev rc = check_ring_op(n, k, lc, RTE_RING_QUEUE_FIXED, fname, 368*70581c35SKonstantin Ananyev RTE_STR(_st_ring_enqueue_bulk), la->rng); 369*70581c35SKonstantin Ananyev if (rc != 0) 370*70581c35SKonstantin Ananyev return rc; 371*70581c35SKonstantin Ananyev 372*70581c35SKonstantin Ananyev lcore_op_stat_update(&la->stats.deqenq, 1, n, tm0 + tm1, prcs); 373*70581c35SKonstantin Ananyev return 0; 374*70581c35SKonstantin Ananyev } 375*70581c35SKonstantin Ananyev 376*70581c35SKonstantin Ananyev static int 377*70581c35SKonstantin Ananyev test_worker(void *arg, const char *fname, int32_t prcs) 378*70581c35SKonstantin Ananyev { 379*70581c35SKonstantin Ananyev int32_t rc; 380*70581c35SKonstantin Ananyev uint32_t i, lc; 381*70581c35SKonstantin Ananyev uint64_t cl; 382*70581c35SKonstantin Ananyev struct lcore_arg *la; 383*70581c35SKonstantin Ananyev struct ring_elem *obj[2 * BULK_NUM]; 384*70581c35SKonstantin Ananyev struct ring_elem *pelm, def_elm, loc_elm, stg_elm[MAX_STAGES]; 385*70581c35SKonstantin Ananyev 386*70581c35SKonstantin Ananyev la = arg; 387*70581c35SKonstantin Ananyev lc = rte_lcore_id(); 388*70581c35SKonstantin Ananyev 389*70581c35SKonstantin Ananyev fill_ring_elm(&def_elm, UINT32_MAX); 390*70581c35SKonstantin Ananyev fill_ring_elm(&loc_elm, lc); 391*70581c35SKonstantin Ananyev 392*70581c35SKonstantin Ananyev for (i = 0; i != RTE_DIM(stg_elm); i++) 393*70581c35SKonstantin Ananyev fill_ring_elm(stg_elm + i, (i + 1) << 24); 394*70581c35SKonstantin Ananyev 395*70581c35SKonstantin Ananyev pelm = stg_elm + la->stats.nb_stage - 1; 396*70581c35SKonstantin Ananyev 397*70581c35SKonstantin Ananyev /* Acquire ordering is not required as the main is not 398*70581c35SKonstantin Ananyev * really releasing any data through 'wrk_cmd' to 399*70581c35SKonstantin Ananyev * the worker. 400*70581c35SKonstantin Ananyev */ 401*70581c35SKonstantin Ananyev while (rte_atomic_load_explicit(&wrk_cmd, rte_memory_order_relaxed) != 402*70581c35SKonstantin Ananyev WRK_CMD_RUN) 403*70581c35SKonstantin Ananyev rte_pause(); 404*70581c35SKonstantin Ananyev 405*70581c35SKonstantin Ananyev cl = rte_rdtsc_precise(); 406*70581c35SKonstantin Ananyev 407*70581c35SKonstantin Ananyev do { 408*70581c35SKonstantin Ananyev if ((la->stats.role_mask & ~ROLE_DEQENQ) != 0) { 409*70581c35SKonstantin Ananyev rc = test_worker_stages(la, lc, fname, obj, 410*70581c35SKonstantin Ananyev &def_elm, &loc_elm, stg_elm, prcs); 411*70581c35SKonstantin Ananyev if (rc != 0) 412*70581c35SKonstantin Ananyev break; 413*70581c35SKonstantin Ananyev } 414*70581c35SKonstantin Ananyev 415*70581c35SKonstantin Ananyev if ((la->stats.role_mask & ROLE_DEQENQ) != 0) { 416*70581c35SKonstantin Ananyev rc = test_worker_deqenq(la, lc, fname, obj, 417*70581c35SKonstantin Ananyev &def_elm, &loc_elm, pelm, prcs); 418*70581c35SKonstantin Ananyev if (rc != 0) 419*70581c35SKonstantin Ananyev break; 420*70581c35SKonstantin Ananyev } 421*70581c35SKonstantin Ananyev 422*70581c35SKonstantin Ananyev } while (rte_atomic_load_explicit(&wrk_cmd, 423*70581c35SKonstantin Ananyev rte_memory_order_relaxed) == WRK_CMD_RUN); 424*70581c35SKonstantin Ananyev 425*70581c35SKonstantin Ananyev cl = rte_rdtsc_precise() - cl; 426*70581c35SKonstantin Ananyev if (prcs == 0) 427*70581c35SKonstantin Ananyev lcore_stat_update(&la->stats, 0, 0, cl, 0); 428*70581c35SKonstantin Ananyev la->stats.nb_cycle = cl; 429*70581c35SKonstantin Ananyev return rc; 430*70581c35SKonstantin Ananyev } 431*70581c35SKonstantin Ananyev static int 432*70581c35SKonstantin Ananyev test_worker_prcs(void *arg) 433*70581c35SKonstantin Ananyev { 434*70581c35SKonstantin Ananyev return test_worker(arg, __func__, 1); 435*70581c35SKonstantin Ananyev } 436*70581c35SKonstantin Ananyev 437*70581c35SKonstantin Ananyev static int 438*70581c35SKonstantin Ananyev test_worker_avg(void *arg) 439*70581c35SKonstantin Ananyev { 440*70581c35SKonstantin Ananyev return test_worker(arg, __func__, 0); 441*70581c35SKonstantin Ananyev } 442*70581c35SKonstantin Ananyev 443*70581c35SKonstantin Ananyev static void 444*70581c35SKonstantin Ananyev mt1_fini(struct rte_soring *rng, void *data) 445*70581c35SKonstantin Ananyev { 446*70581c35SKonstantin Ananyev rte_free(rng); 447*70581c35SKonstantin Ananyev rte_free(data); 448*70581c35SKonstantin Ananyev } 449*70581c35SKonstantin Ananyev 450*70581c35SKonstantin Ananyev static int 451*70581c35SKonstantin Ananyev mt1_init(struct rte_soring **rng, void **data, uint32_t num, 452*70581c35SKonstantin Ananyev enum rte_ring_sync_type prod_synt, enum rte_ring_sync_type cons_synt, 453*70581c35SKonstantin Ananyev uint32_t nb_stages) 454*70581c35SKonstantin Ananyev { 455*70581c35SKonstantin Ananyev int32_t rc; 456*70581c35SKonstantin Ananyev size_t sz; 457*70581c35SKonstantin Ananyev uint32_t i; 458*70581c35SKonstantin Ananyev struct rte_soring *r; 459*70581c35SKonstantin Ananyev struct ring_elem *elm; 460*70581c35SKonstantin Ananyev void *p; 461*70581c35SKonstantin Ananyev struct rte_soring_param prm; 462*70581c35SKonstantin Ananyev 463*70581c35SKonstantin Ananyev *rng = NULL; 464*70581c35SKonstantin Ananyev *data = NULL; 465*70581c35SKonstantin Ananyev 466*70581c35SKonstantin Ananyev sz = num * sizeof(*elm); 467*70581c35SKonstantin Ananyev elm = rte_zmalloc(NULL, sz, alignof(typeof(*elm))); 468*70581c35SKonstantin Ananyev if (elm == NULL) { 469*70581c35SKonstantin Ananyev printf("%s: alloc(%zu) for %u elems data failed", 470*70581c35SKonstantin Ananyev __func__, sz, num); 471*70581c35SKonstantin Ananyev return -ENOMEM; 472*70581c35SKonstantin Ananyev } 473*70581c35SKonstantin Ananyev 474*70581c35SKonstantin Ananyev *data = elm; 475*70581c35SKonstantin Ananyev 476*70581c35SKonstantin Ananyev /* alloc soring */ 477*70581c35SKonstantin Ananyev memset(&prm, 0, sizeof(prm)); 478*70581c35SKonstantin Ananyev 479*70581c35SKonstantin Ananyev prm.name = __func__; 480*70581c35SKonstantin Ananyev prm.elems = num; 481*70581c35SKonstantin Ananyev prm.elem_size = sizeof(uintptr_t); 482*70581c35SKonstantin Ananyev prm.stages = nb_stages; 483*70581c35SKonstantin Ananyev prm.prod_synt = prod_synt; 484*70581c35SKonstantin Ananyev prm.cons_synt = cons_synt; 485*70581c35SKonstantin Ananyev 486*70581c35SKonstantin Ananyev sz = rte_soring_get_memsize(&prm); 487*70581c35SKonstantin Ananyev r = rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE); 488*70581c35SKonstantin Ananyev if (r == NULL) { 489*70581c35SKonstantin Ananyev printf("%s: alloc(%zu) for FIFO with %u elems failed", 490*70581c35SKonstantin Ananyev __func__, sz, prm.elems); 491*70581c35SKonstantin Ananyev return -ENOMEM; 492*70581c35SKonstantin Ananyev } 493*70581c35SKonstantin Ananyev 494*70581c35SKonstantin Ananyev *rng = r; 495*70581c35SKonstantin Ananyev 496*70581c35SKonstantin Ananyev rc = rte_soring_init(r, &prm); 497*70581c35SKonstantin Ananyev if (rc != 0) { 498*70581c35SKonstantin Ananyev printf("%s: rte_soring_init(r=%p,elems=%u,stages=%u) failed, " 499*70581c35SKonstantin Ananyev "error: %d(%s)\n", 500*70581c35SKonstantin Ananyev __func__, r, prm.elems, prm.stages, rc, strerror(-rc)); 501*70581c35SKonstantin Ananyev return rc; 502*70581c35SKonstantin Ananyev } 503*70581c35SKonstantin Ananyev 504*70581c35SKonstantin Ananyev for (i = 0; i != num; i++) { 505*70581c35SKonstantin Ananyev fill_ring_elm(elm + i, UINT32_MAX); 506*70581c35SKonstantin Ananyev p = elm + i; 507*70581c35SKonstantin Ananyev if (_st_ring_enqueue_bulk(r, &p, 1, NULL) != 1) 508*70581c35SKonstantin Ananyev break; 509*70581c35SKonstantin Ananyev } 510*70581c35SKonstantin Ananyev 511*70581c35SKonstantin Ananyev if (i != num) { 512*70581c35SKonstantin Ananyev printf("%s: _st_ring_enqueue(%p, %u) returned %u\n", 513*70581c35SKonstantin Ananyev __func__, r, num, i); 514*70581c35SKonstantin Ananyev return -ENOSPC; 515*70581c35SKonstantin Ananyev } 516*70581c35SKonstantin Ananyev 517*70581c35SKonstantin Ananyev return 0; 518*70581c35SKonstantin Ananyev } 519*70581c35SKonstantin Ananyev 520*70581c35SKonstantin Ananyev static int 521*70581c35SKonstantin Ananyev test_mt(int (*test)(void *), enum rte_ring_sync_type prod_synt, 522*70581c35SKonstantin Ananyev enum rte_ring_sync_type cons_synt, uint32_t nb_stage, 523*70581c35SKonstantin Ananyev const uint32_t role_mask[RTE_MAX_LCORE]) 524*70581c35SKonstantin Ananyev { 525*70581c35SKonstantin Ananyev int32_t rc; 526*70581c35SKonstantin Ananyev uint32_t i, lc, mc; 527*70581c35SKonstantin Ananyev struct rte_soring *r; 528*70581c35SKonstantin Ananyev void *data; 529*70581c35SKonstantin Ananyev struct lcore_arg arg[RTE_MAX_LCORE]; 530*70581c35SKonstantin Ananyev 531*70581c35SKonstantin Ananyev static const struct lcore_op_stat init_stat = { 532*70581c35SKonstantin Ananyev .min_cycle = UINT64_MAX, 533*70581c35SKonstantin Ananyev }; 534*70581c35SKonstantin Ananyev 535*70581c35SKonstantin Ananyev rc = mt1_init(&r, &data, RING_SIZE, prod_synt, cons_synt, nb_stage); 536*70581c35SKonstantin Ananyev 537*70581c35SKonstantin Ananyev if (rc != 0) { 538*70581c35SKonstantin Ananyev mt1_fini(r, data); 539*70581c35SKonstantin Ananyev return rc; 540*70581c35SKonstantin Ananyev } 541*70581c35SKonstantin Ananyev 542*70581c35SKonstantin Ananyev memset(arg, 0, sizeof(arg)); 543*70581c35SKonstantin Ananyev 544*70581c35SKonstantin Ananyev /* launch on all workers */ 545*70581c35SKonstantin Ananyev RTE_LCORE_FOREACH_WORKER(lc) { 546*70581c35SKonstantin Ananyev arg[lc].rng = r; 547*70581c35SKonstantin Ananyev arg[lc].stats.deqenq = init_stat; 548*70581c35SKonstantin Ananyev arg[lc].stats.nb_stage = nb_stage; 549*70581c35SKonstantin Ananyev arg[lc].stats.role_mask = role_mask[lc]; 550*70581c35SKonstantin Ananyev for (i = 0; i != arg[lc].stats.nb_stage; i++) 551*70581c35SKonstantin Ananyev arg[lc].stats.stage[i] = init_stat; 552*70581c35SKonstantin Ananyev rte_eal_remote_launch(test, &arg[lc], lc); 553*70581c35SKonstantin Ananyev } 554*70581c35SKonstantin Ananyev 555*70581c35SKonstantin Ananyev /* signal workers to start test */ 556*70581c35SKonstantin Ananyev rte_atomic_store_explicit(&wrk_cmd, WRK_CMD_RUN, 557*70581c35SKonstantin Ananyev rte_memory_order_release); 558*70581c35SKonstantin Ananyev 559*70581c35SKonstantin Ananyev rte_delay_us(run_time * US_PER_S); 560*70581c35SKonstantin Ananyev 561*70581c35SKonstantin Ananyev /* signal workers to stop test */ 562*70581c35SKonstantin Ananyev rte_atomic_store_explicit(&wrk_cmd, WRK_CMD_STOP, 563*70581c35SKonstantin Ananyev rte_memory_order_release); 564*70581c35SKonstantin Ananyev 565*70581c35SKonstantin Ananyev /* wait for workers and collect stats. */ 566*70581c35SKonstantin Ananyev mc = rte_lcore_id(); 567*70581c35SKonstantin Ananyev arg[mc].stats.deqenq = init_stat; 568*70581c35SKonstantin Ananyev arg[mc].stats.nb_stage = nb_stage; 569*70581c35SKonstantin Ananyev for (i = 0; i != arg[mc].stats.nb_stage; i++) 570*70581c35SKonstantin Ananyev arg[mc].stats.stage[i] = init_stat; 571*70581c35SKonstantin Ananyev 572*70581c35SKonstantin Ananyev rc = 0; 573*70581c35SKonstantin Ananyev RTE_LCORE_FOREACH_WORKER(lc) { 574*70581c35SKonstantin Ananyev rc |= rte_eal_wait_lcore(lc); 575*70581c35SKonstantin Ananyev lcore_stat_aggr(&arg[mc].stats, &arg[lc].stats); 576*70581c35SKonstantin Ananyev if (verbose != 0) 577*70581c35SKonstantin Ananyev lcore_stat_dump(stdout, lc, &arg[lc].stats); 578*70581c35SKonstantin Ananyev } 579*70581c35SKonstantin Ananyev 580*70581c35SKonstantin Ananyev lcore_stat_dump(stdout, UINT32_MAX, &arg[mc].stats); 581*70581c35SKonstantin Ananyev rte_soring_dump(stdout, r); 582*70581c35SKonstantin Ananyev mt1_fini(r, data); 583*70581c35SKonstantin Ananyev return rc; 584*70581c35SKonstantin Ananyev } 585*70581c35SKonstantin Ananyev 586*70581c35SKonstantin Ananyev /* 587*70581c35SKonstantin Ananyev * launch all stages and deq+enq on all worker lcores 588*70581c35SKonstantin Ananyev */ 589*70581c35SKonstantin Ananyev static void 590*70581c35SKonstantin Ananyev role_mask_sym(uint32_t nb_stage, uint32_t role_mask[RTE_MAX_LCORE]) 591*70581c35SKonstantin Ananyev { 592*70581c35SKonstantin Ananyev uint32_t lc; 593*70581c35SKonstantin Ananyev const uint32_t msk = RTE_BIT32(nb_stage + 2) - 1; 594*70581c35SKonstantin Ananyev 595*70581c35SKonstantin Ananyev memset(role_mask, 0, sizeof(role_mask[0]) * RTE_MAX_LCORE); 596*70581c35SKonstantin Ananyev RTE_LCORE_FOREACH_WORKER(lc) 597*70581c35SKonstantin Ananyev role_mask[lc] = msk; 598*70581c35SKonstantin Ananyev } 599*70581c35SKonstantin Ananyev 600*70581c35SKonstantin Ananyev /* 601*70581c35SKonstantin Ananyev * Divide all workers in two (nearly) equal groups: 602*70581c35SKonstantin Ananyev * - workers from 'even' group do deque+enque 603*70581c35SKonstantin Ananyev * - workers from 'odd' group do acquire/release (for all stages) 604*70581c35SKonstantin Ananyev */ 605*70581c35SKonstantin Ananyev static void 606*70581c35SKonstantin Ananyev role_mask_even_odd(uint32_t nb_stage, uint32_t role_mask[RTE_MAX_LCORE]) 607*70581c35SKonstantin Ananyev { 608*70581c35SKonstantin Ananyev uint32_t i, lc; 609*70581c35SKonstantin Ananyev const uint32_t msk[2] = { 610*70581c35SKonstantin Ananyev [0] = ROLE_DEQENQ, 611*70581c35SKonstantin Ananyev [1] = RTE_GENMASK32(nb_stage + 1, 1), 612*70581c35SKonstantin Ananyev }; 613*70581c35SKonstantin Ananyev 614*70581c35SKonstantin Ananyev memset(role_mask, 0, sizeof(role_mask[0]) * RTE_MAX_LCORE); 615*70581c35SKonstantin Ananyev 616*70581c35SKonstantin Ananyev i = 0; 617*70581c35SKonstantin Ananyev RTE_LCORE_FOREACH_WORKER(lc) { 618*70581c35SKonstantin Ananyev role_mask[lc] = msk[i & 1]; 619*70581c35SKonstantin Ananyev i++; 620*70581c35SKonstantin Ananyev } 621*70581c35SKonstantin Ananyev if (i == 1) { 622*70581c35SKonstantin Ananyev lc = rte_get_next_lcore(-1, 1, 0); 623*70581c35SKonstantin Ananyev role_mask[lc] |= msk[i & 1]; 624*70581c35SKonstantin Ananyev } 625*70581c35SKonstantin Ananyev } 626*70581c35SKonstantin Ananyev 627*70581c35SKonstantin Ananyev /* 628*70581c35SKonstantin Ananyev * Divide all workers (nearly) evenly among all possible stages 629*70581c35SKonstantin Ananyev */ 630*70581c35SKonstantin Ananyev static void 631*70581c35SKonstantin Ananyev role_mask_div(uint32_t nb_stage, uint32_t role_mask[RTE_MAX_LCORE]) 632*70581c35SKonstantin Ananyev { 633*70581c35SKonstantin Ananyev uint32_t i, lc; 634*70581c35SKonstantin Ananyev uint32_t msk[nb_stage + 1]; 635*70581c35SKonstantin Ananyev 636*70581c35SKonstantin Ananyev memset(role_mask, 0, sizeof(role_mask[0]) * RTE_MAX_LCORE); 637*70581c35SKonstantin Ananyev 638*70581c35SKonstantin Ananyev for (i = 0; i != RTE_DIM(msk); i++) { 639*70581c35SKonstantin Ananyev msk[i] = RTE_BIT32(i); 640*70581c35SKonstantin Ananyev }; 641*70581c35SKonstantin Ananyev 642*70581c35SKonstantin Ananyev i = 0; 643*70581c35SKonstantin Ananyev RTE_LCORE_FOREACH_WORKER(lc) { 644*70581c35SKonstantin Ananyev role_mask[lc] = msk[i % RTE_DIM(msk)]; 645*70581c35SKonstantin Ananyev i++; 646*70581c35SKonstantin Ananyev } 647*70581c35SKonstantin Ananyev if (i < RTE_DIM(msk)) { 648*70581c35SKonstantin Ananyev lc = rte_get_next_lcore(-1, 1, 0); 649*70581c35SKonstantin Ananyev for (; i != RTE_DIM(msk); i++) 650*70581c35SKonstantin Ananyev role_mask[lc] |= msk[i % RTE_DIM(msk)]; 651*70581c35SKonstantin Ananyev } 652*70581c35SKonstantin Ananyev } 653*70581c35SKonstantin Ananyev 654*70581c35SKonstantin Ananyev /* 655*70581c35SKonstantin Ananyev * one worker does ST enqueue+dequeue, while all others - stages processing. 656*70581c35SKonstantin Ananyev */ 657*70581c35SKonstantin Ananyev static void 658*70581c35SKonstantin Ananyev role_mask_denq_st(uint32_t nb_stage, uint32_t role_mask[RTE_MAX_LCORE]) 659*70581c35SKonstantin Ananyev { 660*70581c35SKonstantin Ananyev uint32_t i, lc; 661*70581c35SKonstantin Ananyev const uint32_t msk[2] = { 662*70581c35SKonstantin Ananyev [0] = ROLE_DEQENQ, 663*70581c35SKonstantin Ananyev [1] = RTE_GENMASK32(nb_stage + 1, 1), 664*70581c35SKonstantin Ananyev }; 665*70581c35SKonstantin Ananyev 666*70581c35SKonstantin Ananyev memset(role_mask, 0, sizeof(role_mask[0]) * RTE_MAX_LCORE); 667*70581c35SKonstantin Ananyev 668*70581c35SKonstantin Ananyev i = 0; 669*70581c35SKonstantin Ananyev RTE_LCORE_FOREACH_WORKER(lc) { 670*70581c35SKonstantin Ananyev if (i == 0) 671*70581c35SKonstantin Ananyev role_mask[lc] = msk[0]; 672*70581c35SKonstantin Ananyev else 673*70581c35SKonstantin Ananyev role_mask[lc] = msk[1]; 674*70581c35SKonstantin Ananyev i++; 675*70581c35SKonstantin Ananyev } 676*70581c35SKonstantin Ananyev if (i == 1) { 677*70581c35SKonstantin Ananyev lc = rte_get_next_lcore(-1, 1, 0); 678*70581c35SKonstantin Ananyev role_mask[lc] |= msk[1]; 679*70581c35SKonstantin Ananyev } 680*70581c35SKonstantin Ananyev } 681*70581c35SKonstantin Ananyev 682*70581c35SKonstantin Ananyev 683*70581c35SKonstantin Ananyev static int 684*70581c35SKonstantin Ananyev test_sym_mt1(int (*test)(void *)) 685*70581c35SKonstantin Ananyev { 686*70581c35SKonstantin Ananyev uint32_t role_mask[RTE_MAX_LCORE]; 687*70581c35SKonstantin Ananyev const uint32_t nb_stage = 1; 688*70581c35SKonstantin Ananyev 689*70581c35SKonstantin Ananyev role_mask_sym(nb_stage, role_mask); 690*70581c35SKonstantin Ananyev return test_mt(test, RTE_RING_SYNC_MT, RTE_RING_SYNC_MT, 691*70581c35SKonstantin Ananyev nb_stage, role_mask); 692*70581c35SKonstantin Ananyev } 693*70581c35SKonstantin Ananyev 694*70581c35SKonstantin Ananyev static int 695*70581c35SKonstantin Ananyev test_sym_mt4(int (*test)(void *)) 696*70581c35SKonstantin Ananyev { 697*70581c35SKonstantin Ananyev uint32_t role_mask[RTE_MAX_LCORE]; 698*70581c35SKonstantin Ananyev 699*70581c35SKonstantin Ananyev const uint32_t nb_stage = 4; 700*70581c35SKonstantin Ananyev 701*70581c35SKonstantin Ananyev role_mask_sym(nb_stage, role_mask); 702*70581c35SKonstantin Ananyev return test_mt(test, RTE_RING_SYNC_MT, RTE_RING_SYNC_MT, 703*70581c35SKonstantin Ananyev nb_stage, role_mask); 704*70581c35SKonstantin Ananyev } 705*70581c35SKonstantin Ananyev 706*70581c35SKonstantin Ananyev static int 707*70581c35SKonstantin Ananyev test_sym_mt_rts4(int (*test)(void *)) 708*70581c35SKonstantin Ananyev { 709*70581c35SKonstantin Ananyev uint32_t role_mask[RTE_MAX_LCORE]; 710*70581c35SKonstantin Ananyev 711*70581c35SKonstantin Ananyev const uint32_t nb_stage = 4; 712*70581c35SKonstantin Ananyev 713*70581c35SKonstantin Ananyev role_mask_sym(nb_stage, role_mask); 714*70581c35SKonstantin Ananyev return test_mt(test, RTE_RING_SYNC_MT_RTS, RTE_RING_SYNC_MT_RTS, 715*70581c35SKonstantin Ananyev nb_stage, role_mask); 716*70581c35SKonstantin Ananyev } 717*70581c35SKonstantin Ananyev 718*70581c35SKonstantin Ananyev static int 719*70581c35SKonstantin Ananyev test_sym_mt_hts4(int (*test)(void *)) 720*70581c35SKonstantin Ananyev { 721*70581c35SKonstantin Ananyev uint32_t role_mask[RTE_MAX_LCORE]; 722*70581c35SKonstantin Ananyev 723*70581c35SKonstantin Ananyev const uint32_t nb_stage = 4; 724*70581c35SKonstantin Ananyev 725*70581c35SKonstantin Ananyev role_mask_sym(nb_stage, role_mask); 726*70581c35SKonstantin Ananyev return test_mt(test, RTE_RING_SYNC_MT_HTS, RTE_RING_SYNC_MT_HTS, 727*70581c35SKonstantin Ananyev nb_stage, role_mask); 728*70581c35SKonstantin Ananyev } 729*70581c35SKonstantin Ananyev 730*70581c35SKonstantin Ananyev static int 731*70581c35SKonstantin Ananyev test_stdenq_stage4(int (*test)(void *)) 732*70581c35SKonstantin Ananyev { 733*70581c35SKonstantin Ananyev uint32_t role_mask[RTE_MAX_LCORE]; 734*70581c35SKonstantin Ananyev 735*70581c35SKonstantin Ananyev const uint32_t nb_stage = 4; 736*70581c35SKonstantin Ananyev 737*70581c35SKonstantin Ananyev role_mask_denq_st(nb_stage, role_mask); 738*70581c35SKonstantin Ananyev return test_mt(test, RTE_RING_SYNC_ST, RTE_RING_SYNC_ST, 739*70581c35SKonstantin Ananyev nb_stage, role_mask); 740*70581c35SKonstantin Ananyev } 741*70581c35SKonstantin Ananyev 742*70581c35SKonstantin Ananyev 743*70581c35SKonstantin Ananyev static int 744*70581c35SKonstantin Ananyev test_even_odd_mt5(int (*test)(void *)) 745*70581c35SKonstantin Ananyev { 746*70581c35SKonstantin Ananyev uint32_t role_mask[RTE_MAX_LCORE]; 747*70581c35SKonstantin Ananyev 748*70581c35SKonstantin Ananyev const uint32_t nb_stage = 5; 749*70581c35SKonstantin Ananyev 750*70581c35SKonstantin Ananyev role_mask_even_odd(nb_stage, role_mask); 751*70581c35SKonstantin Ananyev return test_mt(test, RTE_RING_SYNC_MT, RTE_RING_SYNC_MT, 752*70581c35SKonstantin Ananyev nb_stage, role_mask); 753*70581c35SKonstantin Ananyev } 754*70581c35SKonstantin Ananyev 755*70581c35SKonstantin Ananyev static int 756*70581c35SKonstantin Ananyev test_div_mt3(int (*test)(void *)) 757*70581c35SKonstantin Ananyev { 758*70581c35SKonstantin Ananyev uint32_t role_mask[RTE_MAX_LCORE]; 759*70581c35SKonstantin Ananyev 760*70581c35SKonstantin Ananyev const uint32_t nb_stage = 3; 761*70581c35SKonstantin Ananyev 762*70581c35SKonstantin Ananyev role_mask_div(nb_stage, role_mask); 763*70581c35SKonstantin Ananyev return test_mt(test, RTE_RING_SYNC_MT, RTE_RING_SYNC_MT, 764*70581c35SKonstantin Ananyev nb_stage, role_mask); 765*70581c35SKonstantin Ananyev } 766*70581c35SKonstantin Ananyev 767*70581c35SKonstantin Ananyev static const struct test_case tests[] = { 768*70581c35SKonstantin Ananyev { 769*70581c35SKonstantin Ananyev .name = "MT_DEQENQ-MT_STG1-PRCS", 770*70581c35SKonstantin Ananyev .func = test_sym_mt1, 771*70581c35SKonstantin Ananyev .wfunc = test_worker_prcs, 772*70581c35SKonstantin Ananyev }, 773*70581c35SKonstantin Ananyev { 774*70581c35SKonstantin Ananyev .name = "MT_DEQENQ-MT_STG1-AVG", 775*70581c35SKonstantin Ananyev .func = test_sym_mt1, 776*70581c35SKonstantin Ananyev .wfunc = test_worker_avg, 777*70581c35SKonstantin Ananyev }, 778*70581c35SKonstantin Ananyev { 779*70581c35SKonstantin Ananyev .name = "MT_DEQENQ-MT_STG4-PRCS", 780*70581c35SKonstantin Ananyev .func = test_sym_mt4, 781*70581c35SKonstantin Ananyev .wfunc = test_worker_prcs, 782*70581c35SKonstantin Ananyev }, 783*70581c35SKonstantin Ananyev { 784*70581c35SKonstantin Ananyev .name = "MT_DEQENQ-MT_STG4-AVG", 785*70581c35SKonstantin Ananyev .func = test_sym_mt4, 786*70581c35SKonstantin Ananyev .wfunc = test_worker_avg, 787*70581c35SKonstantin Ananyev }, 788*70581c35SKonstantin Ananyev { 789*70581c35SKonstantin Ananyev .name = "MTRTS_DEQENQ-MT_STG4-PRCS", 790*70581c35SKonstantin Ananyev .func = test_sym_mt_rts4, 791*70581c35SKonstantin Ananyev .wfunc = test_worker_prcs, 792*70581c35SKonstantin Ananyev }, 793*70581c35SKonstantin Ananyev { 794*70581c35SKonstantin Ananyev .name = "MTRTS_DEQENQ-MT_STG4-AVG", 795*70581c35SKonstantin Ananyev .func = test_sym_mt_rts4, 796*70581c35SKonstantin Ananyev .wfunc = test_worker_avg, 797*70581c35SKonstantin Ananyev }, 798*70581c35SKonstantin Ananyev { 799*70581c35SKonstantin Ananyev .name = "MTHTS_DEQENQ-MT_STG4-PRCS", 800*70581c35SKonstantin Ananyev .func = test_sym_mt_hts4, 801*70581c35SKonstantin Ananyev .wfunc = test_worker_prcs, 802*70581c35SKonstantin Ananyev }, 803*70581c35SKonstantin Ananyev { 804*70581c35SKonstantin Ananyev .name = "MTHTS_DEQENQ-MT_STG4-AVG", 805*70581c35SKonstantin Ananyev .func = test_sym_mt_hts4, 806*70581c35SKonstantin Ananyev .wfunc = test_worker_avg, 807*70581c35SKonstantin Ananyev }, 808*70581c35SKonstantin Ananyev { 809*70581c35SKonstantin Ananyev .name = "MT_DEQENQ-MT_STG5-1:1-PRCS", 810*70581c35SKonstantin Ananyev .func = test_even_odd_mt5, 811*70581c35SKonstantin Ananyev .wfunc = test_worker_prcs, 812*70581c35SKonstantin Ananyev }, 813*70581c35SKonstantin Ananyev { 814*70581c35SKonstantin Ananyev .name = "MT_DEQENQ-MT_STG5-1:1-AVG", 815*70581c35SKonstantin Ananyev .func = test_even_odd_mt5, 816*70581c35SKonstantin Ananyev .wfunc = test_worker_avg, 817*70581c35SKonstantin Ananyev }, 818*70581c35SKonstantin Ananyev { 819*70581c35SKonstantin Ananyev .name = "MT_DEQENQ-MT_STG3-1:3-PRCS", 820*70581c35SKonstantin Ananyev .func = test_div_mt3, 821*70581c35SKonstantin Ananyev .wfunc = test_worker_prcs, 822*70581c35SKonstantin Ananyev }, 823*70581c35SKonstantin Ananyev { 824*70581c35SKonstantin Ananyev .name = "MT_DEQENQ_MT_STG3-1:3-AVG", 825*70581c35SKonstantin Ananyev .func = test_div_mt3, 826*70581c35SKonstantin Ananyev .wfunc = test_worker_avg, 827*70581c35SKonstantin Ananyev }, 828*70581c35SKonstantin Ananyev { 829*70581c35SKonstantin Ananyev .name = "ST_DEQENQ-MT_STG4-PRCS", 830*70581c35SKonstantin Ananyev .func = test_stdenq_stage4, 831*70581c35SKonstantin Ananyev .wfunc = test_worker_prcs, 832*70581c35SKonstantin Ananyev }, 833*70581c35SKonstantin Ananyev { 834*70581c35SKonstantin Ananyev .name = "ST_DEQENQ-MT_STG4-AVG", 835*70581c35SKonstantin Ananyev .func = test_stdenq_stage4, 836*70581c35SKonstantin Ananyev .wfunc = test_worker_avg, 837*70581c35SKonstantin Ananyev }, 838*70581c35SKonstantin Ananyev }; 839