xref: /dpdk/app/test-eventdev/test_perf_common.c (revision 272de06723b0159134bf44a11d40f2ad092169df)
1ffbae86fSJerin Jacob /*
2ffbae86fSJerin Jacob  *   BSD LICENSE
3ffbae86fSJerin Jacob  *
4ffbae86fSJerin Jacob  *   Copyright (C) Cavium 2017.
5ffbae86fSJerin Jacob  *
6ffbae86fSJerin Jacob  *   Redistribution and use in source and binary forms, with or without
7ffbae86fSJerin Jacob  *   modification, are permitted provided that the following conditions
8ffbae86fSJerin Jacob  *   are met:
9ffbae86fSJerin Jacob  *
10ffbae86fSJerin Jacob  *     * Redistributions of source code must retain the above copyright
11ffbae86fSJerin Jacob  *       notice, this list of conditions and the following disclaimer.
12ffbae86fSJerin Jacob  *     * Redistributions in binary form must reproduce the above copyright
13ffbae86fSJerin Jacob  *       notice, this list of conditions and the following disclaimer in
14ffbae86fSJerin Jacob  *       the documentation and/or other materials provided with the
15ffbae86fSJerin Jacob  *       distribution.
16ffbae86fSJerin Jacob  *     * Neither the name of Cavium networks nor the names of its
17ffbae86fSJerin Jacob  *       contributors may be used to endorse or promote products derived
18ffbae86fSJerin Jacob  *       from this software without specific prior written permission.
19ffbae86fSJerin Jacob  *
20ffbae86fSJerin Jacob  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21ffbae86fSJerin Jacob  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22ffbae86fSJerin Jacob  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23ffbae86fSJerin Jacob  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24ffbae86fSJerin Jacob  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25ffbae86fSJerin Jacob  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26ffbae86fSJerin Jacob  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27ffbae86fSJerin Jacob  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28ffbae86fSJerin Jacob  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29ffbae86fSJerin Jacob  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30ffbae86fSJerin Jacob  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31ffbae86fSJerin Jacob  */
32ffbae86fSJerin Jacob 
33ffbae86fSJerin Jacob #include "test_perf_common.h"
34ffbae86fSJerin Jacob 
3541c219e6SJerin Jacob int
3641c219e6SJerin Jacob perf_test_result(struct evt_test *test, struct evt_options *opt)
3741c219e6SJerin Jacob {
3841c219e6SJerin Jacob 	RTE_SET_USED(opt);
3941c219e6SJerin Jacob 	struct test_perf *t = evt_test_priv(test);
4041c219e6SJerin Jacob 
4141c219e6SJerin Jacob 	return t->result;
4241c219e6SJerin Jacob }
4341c219e6SJerin Jacob 
44*272de067SJerin Jacob int
45*272de067SJerin Jacob perf_opt_check(struct evt_options *opt, uint64_t nb_queues)
46*272de067SJerin Jacob {
47*272de067SJerin Jacob 	unsigned int lcores;
48*272de067SJerin Jacob 	bool need_slcore = !evt_has_distributed_sched(opt->dev_id);
49*272de067SJerin Jacob 
50*272de067SJerin Jacob 	/* N producer + N worker + 1 scheduler(based on dev capa) + 1 master */
51*272de067SJerin Jacob 	lcores = need_slcore ? 4 : 3;
52*272de067SJerin Jacob 
53*272de067SJerin Jacob 	if (rte_lcore_count() < lcores) {
54*272de067SJerin Jacob 		evt_err("test need minimum %d lcores", lcores);
55*272de067SJerin Jacob 		return -1;
56*272de067SJerin Jacob 	}
57*272de067SJerin Jacob 
58*272de067SJerin Jacob 	/* Validate worker lcores */
59*272de067SJerin Jacob 	if (evt_lcores_has_overlap(opt->wlcores, rte_get_master_lcore())) {
60*272de067SJerin Jacob 		evt_err("worker lcores overlaps with master lcore");
61*272de067SJerin Jacob 		return -1;
62*272de067SJerin Jacob 	}
63*272de067SJerin Jacob 	if (need_slcore && evt_lcores_has_overlap(opt->wlcores, opt->slcore)) {
64*272de067SJerin Jacob 		evt_err("worker lcores overlaps with scheduler lcore");
65*272de067SJerin Jacob 		return -1;
66*272de067SJerin Jacob 	}
67*272de067SJerin Jacob 	if (evt_lcores_has_overlap_multi(opt->wlcores, opt->plcores)) {
68*272de067SJerin Jacob 		evt_err("worker lcores overlaps producer lcores");
69*272de067SJerin Jacob 		return -1;
70*272de067SJerin Jacob 	}
71*272de067SJerin Jacob 	if (evt_has_disabled_lcore(opt->wlcores)) {
72*272de067SJerin Jacob 		evt_err("one or more workers lcores are not enabled");
73*272de067SJerin Jacob 		return -1;
74*272de067SJerin Jacob 	}
75*272de067SJerin Jacob 	if (!evt_has_active_lcore(opt->wlcores)) {
76*272de067SJerin Jacob 		evt_err("minimum one worker is required");
77*272de067SJerin Jacob 		return -1;
78*272de067SJerin Jacob 	}
79*272de067SJerin Jacob 
80*272de067SJerin Jacob 	/* Validate producer lcores */
81*272de067SJerin Jacob 	if (evt_lcores_has_overlap(opt->plcores, rte_get_master_lcore())) {
82*272de067SJerin Jacob 		evt_err("producer lcores overlaps with master lcore");
83*272de067SJerin Jacob 		return -1;
84*272de067SJerin Jacob 	}
85*272de067SJerin Jacob 	if (need_slcore && evt_lcores_has_overlap(opt->plcores, opt->slcore)) {
86*272de067SJerin Jacob 		evt_err("producer lcores overlaps with scheduler lcore");
87*272de067SJerin Jacob 		return -1;
88*272de067SJerin Jacob 	}
89*272de067SJerin Jacob 	if (evt_has_disabled_lcore(opt->plcores)) {
90*272de067SJerin Jacob 		evt_err("one or more producer lcores are not enabled");
91*272de067SJerin Jacob 		return -1;
92*272de067SJerin Jacob 	}
93*272de067SJerin Jacob 	if (!evt_has_active_lcore(opt->plcores)) {
94*272de067SJerin Jacob 		evt_err("minimum one producer is required");
95*272de067SJerin Jacob 		return -1;
96*272de067SJerin Jacob 	}
97*272de067SJerin Jacob 
98*272de067SJerin Jacob 	/* Validate scheduler lcore */
99*272de067SJerin Jacob 	if (!evt_has_distributed_sched(opt->dev_id) &&
100*272de067SJerin Jacob 			opt->slcore == (int)rte_get_master_lcore()) {
101*272de067SJerin Jacob 		evt_err("scheduler lcore and master lcore should be different");
102*272de067SJerin Jacob 		return -1;
103*272de067SJerin Jacob 	}
104*272de067SJerin Jacob 	if (need_slcore && !rte_lcore_is_enabled(opt->slcore)) {
105*272de067SJerin Jacob 		evt_err("scheduler lcore is not enabled");
106*272de067SJerin Jacob 		return -1;
107*272de067SJerin Jacob 	}
108*272de067SJerin Jacob 
109*272de067SJerin Jacob 	if (evt_has_invalid_stage(opt))
110*272de067SJerin Jacob 		return -1;
111*272de067SJerin Jacob 
112*272de067SJerin Jacob 	if (evt_has_invalid_sched_type(opt))
113*272de067SJerin Jacob 		return -1;
114*272de067SJerin Jacob 
115*272de067SJerin Jacob 	if (nb_queues > EVT_MAX_QUEUES) {
116*272de067SJerin Jacob 		evt_err("number of queues exceeds %d", EVT_MAX_QUEUES);
117*272de067SJerin Jacob 		return -1;
118*272de067SJerin Jacob 	}
119*272de067SJerin Jacob 	if (perf_nb_event_ports(opt) > EVT_MAX_PORTS) {
120*272de067SJerin Jacob 		evt_err("number of ports exceeds %d", EVT_MAX_PORTS);
121*272de067SJerin Jacob 		return -1;
122*272de067SJerin Jacob 	}
123*272de067SJerin Jacob 
124*272de067SJerin Jacob 	/* Fixups */
125*272de067SJerin Jacob 	if (opt->nb_stages == 1 && opt->fwd_latency) {
126*272de067SJerin Jacob 		evt_info("fwd_latency is valid when nb_stages > 1, disabling");
127*272de067SJerin Jacob 		opt->fwd_latency = 0;
128*272de067SJerin Jacob 	}
129*272de067SJerin Jacob 	if (opt->fwd_latency && !opt->q_priority) {
130*272de067SJerin Jacob 		evt_info("enabled queue priority for latency measurement");
131*272de067SJerin Jacob 		opt->q_priority = 1;
132*272de067SJerin Jacob 	}
133*272de067SJerin Jacob 
134*272de067SJerin Jacob 	return 0;
135*272de067SJerin Jacob }
136*272de067SJerin Jacob 
137*272de067SJerin Jacob void
138*272de067SJerin Jacob perf_opt_dump(struct evt_options *opt, uint8_t nb_queues)
139*272de067SJerin Jacob {
140*272de067SJerin Jacob 	evt_dump("nb_prod_lcores", "%d", evt_nr_active_lcores(opt->plcores));
141*272de067SJerin Jacob 	evt_dump_producer_lcores(opt);
142*272de067SJerin Jacob 	evt_dump("nb_worker_lcores", "%d", evt_nr_active_lcores(opt->wlcores));
143*272de067SJerin Jacob 	evt_dump_worker_lcores(opt);
144*272de067SJerin Jacob 	if (!evt_has_distributed_sched(opt->dev_id))
145*272de067SJerin Jacob 		evt_dump_scheduler_lcore(opt);
146*272de067SJerin Jacob 	evt_dump_nb_stages(opt);
147*272de067SJerin Jacob 	evt_dump("nb_evdev_ports", "%d", perf_nb_event_ports(opt));
148*272de067SJerin Jacob 	evt_dump("nb_evdev_queues", "%d", nb_queues);
149*272de067SJerin Jacob 	evt_dump_queue_priority(opt);
150*272de067SJerin Jacob 	evt_dump_sched_type_list(opt);
151*272de067SJerin Jacob }
152*272de067SJerin Jacob 
15341c219e6SJerin Jacob void
15441c219e6SJerin Jacob perf_eventdev_destroy(struct evt_test *test, struct evt_options *opt)
15541c219e6SJerin Jacob {
15641c219e6SJerin Jacob 	RTE_SET_USED(test);
15741c219e6SJerin Jacob 
15841c219e6SJerin Jacob 	rte_event_dev_stop(opt->dev_id);
15941c219e6SJerin Jacob 	rte_event_dev_close(opt->dev_id);
16041c219e6SJerin Jacob }
16141c219e6SJerin Jacob 
16241c219e6SJerin Jacob static inline void
16341c219e6SJerin Jacob perf_elt_init(struct rte_mempool *mp, void *arg __rte_unused,
16441c219e6SJerin Jacob 	    void *obj, unsigned i __rte_unused)
16541c219e6SJerin Jacob {
16641c219e6SJerin Jacob 	memset(obj, 0, mp->elt_size);
16741c219e6SJerin Jacob }
16841c219e6SJerin Jacob 
16941c219e6SJerin Jacob int
17041c219e6SJerin Jacob perf_mempool_setup(struct evt_test *test, struct evt_options *opt)
17141c219e6SJerin Jacob {
17241c219e6SJerin Jacob 	struct test_perf *t = evt_test_priv(test);
17341c219e6SJerin Jacob 
17441c219e6SJerin Jacob 	t->pool = rte_mempool_create(test->name, /* mempool name */
17541c219e6SJerin Jacob 				opt->pool_sz, /* number of elements*/
17641c219e6SJerin Jacob 				sizeof(struct perf_elt), /* element size*/
17741c219e6SJerin Jacob 				512, /* cache size*/
17841c219e6SJerin Jacob 				0, NULL, NULL,
17941c219e6SJerin Jacob 				perf_elt_init, /* obj constructor */
18041c219e6SJerin Jacob 				NULL, opt->socket_id, 0); /* flags */
18141c219e6SJerin Jacob 	if (t->pool == NULL) {
18241c219e6SJerin Jacob 		evt_err("failed to create mempool");
18341c219e6SJerin Jacob 		return -ENOMEM;
18441c219e6SJerin Jacob 	}
18541c219e6SJerin Jacob 
18641c219e6SJerin Jacob 	return 0;
18741c219e6SJerin Jacob }
18841c219e6SJerin Jacob 
18941c219e6SJerin Jacob void
19041c219e6SJerin Jacob perf_mempool_destroy(struct evt_test *test, struct evt_options *opt)
19141c219e6SJerin Jacob {
19241c219e6SJerin Jacob 	RTE_SET_USED(opt);
19341c219e6SJerin Jacob 	struct test_perf *t = evt_test_priv(test);
19441c219e6SJerin Jacob 
19541c219e6SJerin Jacob 	rte_mempool_free(t->pool);
19641c219e6SJerin Jacob }
197ffbae86fSJerin Jacob 
198ffbae86fSJerin Jacob int
199ffbae86fSJerin Jacob perf_test_setup(struct evt_test *test, struct evt_options *opt)
200ffbae86fSJerin Jacob {
201ffbae86fSJerin Jacob 	void *test_perf;
202ffbae86fSJerin Jacob 
203ffbae86fSJerin Jacob 	test_perf = rte_zmalloc_socket(test->name, sizeof(struct test_perf),
204ffbae86fSJerin Jacob 				RTE_CACHE_LINE_SIZE, opt->socket_id);
205ffbae86fSJerin Jacob 	if (test_perf  == NULL) {
206ffbae86fSJerin Jacob 		evt_err("failed to allocate test_perf memory");
207ffbae86fSJerin Jacob 		goto nomem;
208ffbae86fSJerin Jacob 	}
209ffbae86fSJerin Jacob 	test->test_priv = test_perf;
210ffbae86fSJerin Jacob 
211ffbae86fSJerin Jacob 	struct test_perf *t = evt_test_priv(test);
212ffbae86fSJerin Jacob 
213ffbae86fSJerin Jacob 	t->outstand_pkts = opt->nb_pkts * evt_nr_active_lcores(opt->plcores);
214ffbae86fSJerin Jacob 	t->nb_workers = evt_nr_active_lcores(opt->wlcores);
215ffbae86fSJerin Jacob 	t->done = false;
216ffbae86fSJerin Jacob 	t->nb_pkts = opt->nb_pkts;
217ffbae86fSJerin Jacob 	t->nb_flows = opt->nb_flows;
218ffbae86fSJerin Jacob 	t->result = EVT_TEST_FAILED;
219ffbae86fSJerin Jacob 	t->opt = opt;
220ffbae86fSJerin Jacob 	memcpy(t->sched_type_list, opt->sched_type_list,
221ffbae86fSJerin Jacob 			sizeof(opt->sched_type_list));
222ffbae86fSJerin Jacob 	return 0;
223ffbae86fSJerin Jacob nomem:
224ffbae86fSJerin Jacob 	return -ENOMEM;
225ffbae86fSJerin Jacob }
226ffbae86fSJerin Jacob 
227ffbae86fSJerin Jacob void
228ffbae86fSJerin Jacob perf_test_destroy(struct evt_test *test, struct evt_options *opt)
229ffbae86fSJerin Jacob {
230ffbae86fSJerin Jacob 	RTE_SET_USED(opt);
231ffbae86fSJerin Jacob 
232ffbae86fSJerin Jacob 	rte_free(test->test_priv);
233ffbae86fSJerin Jacob }
234