app/eventdev: add pipeline ethport setup and destroy
[dpdk.git] / app / test-eventdev / test_pipeline_common.c
1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * Copyright 2017 Cavium, Inc.
4  */
5
6 #include "test_pipeline_common.h"
7
8 int
9 pipeline_test_result(struct evt_test *test, struct evt_options *opt)
10 {
11         RTE_SET_USED(opt);
12         int i;
13         uint64_t total = 0;
14         struct test_pipeline *t = evt_test_priv(test);
15
16         printf("Packet distribution across worker cores :\n");
17         for (i = 0; i < t->nb_workers; i++)
18                 total += t->worker[i].processed_pkts;
19         for (i = 0; i < t->nb_workers; i++)
20                 printf("Worker %d packets: "CLGRN"%"PRIx64" "CLNRM"percentage:"
21                                 CLGRN" %3.2f\n"CLNRM, i,
22                                 t->worker[i].processed_pkts,
23                                 (((double)t->worker[i].processed_pkts)/total)
24                                 * 100);
25         return t->result;
26 }
27
28 void
29 pipeline_opt_dump(struct evt_options *opt, uint8_t nb_queues)
30 {
31         evt_dump("nb_worker_lcores", "%d", evt_nr_active_lcores(opt->wlcores));
32         evt_dump_worker_lcores(opt);
33         evt_dump_nb_stages(opt);
34         evt_dump("nb_evdev_ports", "%d", pipeline_nb_event_ports(opt));
35         evt_dump("nb_evdev_queues", "%d", nb_queues);
36         evt_dump_queue_priority(opt);
37         evt_dump_sched_type_list(opt);
38         evt_dump_producer_type(opt);
39 }
40
41 int
42 pipeline_opt_check(struct evt_options *opt, uint64_t nb_queues)
43 {
44         unsigned int lcores;
45         /*
46          * N worker + 1 master
47          */
48         lcores = 2;
49
50         if (!rte_eth_dev_count()) {
51                 evt_err("test needs minimum 1 ethernet dev");
52                 return -1;
53         }
54
55         if (rte_lcore_count() < lcores) {
56                 evt_err("test need minimum %d lcores", lcores);
57                 return -1;
58         }
59
60         /* Validate worker lcores */
61         if (evt_lcores_has_overlap(opt->wlcores, rte_get_master_lcore())) {
62                 evt_err("worker lcores overlaps with master lcore");
63                 return -1;
64         }
65         if (evt_has_disabled_lcore(opt->wlcores)) {
66                 evt_err("one or more workers lcores are not enabled");
67                 return -1;
68         }
69         if (!evt_has_active_lcore(opt->wlcores)) {
70                 evt_err("minimum one worker is required");
71                 return -1;
72         }
73
74         if (nb_queues > EVT_MAX_QUEUES) {
75                 evt_err("number of queues exceeds %d", EVT_MAX_QUEUES);
76                 return -1;
77         }
78         if (pipeline_nb_event_ports(opt) > EVT_MAX_PORTS) {
79                 evt_err("number of ports exceeds %d", EVT_MAX_PORTS);
80                 return -1;
81         }
82
83         if (evt_has_invalid_stage(opt))
84                 return -1;
85
86         if (evt_has_invalid_sched_type(opt))
87                 return -1;
88
89         return 0;
90 }
91
92 #define NB_RX_DESC                      128
93 #define NB_TX_DESC                      512
94 int
95 pipeline_ethdev_setup(struct evt_test *test, struct evt_options *opt)
96 {
97         int i;
98         uint8_t nb_queues = 1;
99         uint8_t mt_state = 0;
100         struct test_pipeline *t = evt_test_priv(test);
101         struct rte_eth_rxconf rx_conf;
102         struct rte_eth_conf port_conf = {
103                 .rxmode = {
104                         .mq_mode = ETH_MQ_RX_RSS,
105                         .max_rx_pkt_len = ETHER_MAX_LEN,
106                         .offloads = DEV_RX_OFFLOAD_CRC_STRIP,
107                         .ignore_offload_bitfield = 1,
108                 },
109                 .rx_adv_conf = {
110                         .rss_conf = {
111                                 .rss_key = NULL,
112                                 .rss_hf = ETH_RSS_IP,
113                         },
114                 },
115         };
116
117         RTE_SET_USED(opt);
118         if (!rte_eth_dev_count()) {
119                 evt_err("No ethernet ports found.\n");
120                 return -ENODEV;
121         }
122
123         for (i = 0; i < rte_eth_dev_count(); i++) {
124                 struct rte_eth_dev_info dev_info;
125
126                 memset(&dev_info, 0, sizeof(struct rte_eth_dev_info));
127                 rte_eth_dev_info_get(i, &dev_info);
128                 mt_state = !(dev_info.tx_offload_capa &
129                                 DEV_TX_OFFLOAD_MT_LOCKFREE);
130                 rx_conf = dev_info.default_rxconf;
131                 rx_conf.offloads = port_conf.rxmode.offloads;
132
133                 if (rte_eth_dev_configure(i, nb_queues, nb_queues,
134                                         &port_conf)
135                                 < 0) {
136                         evt_err("Failed to configure eth port [%d]\n", i);
137                         return -EINVAL;
138                 }
139
140                 if (rte_eth_rx_queue_setup(i, 0, NB_RX_DESC,
141                                 rte_socket_id(), &rx_conf, t->pool) < 0) {
142                         evt_err("Failed to setup eth port [%d] rx_queue: %d.\n",
143                                         i, 0);
144                         return -EINVAL;
145                 }
146                 if (rte_eth_tx_queue_setup(i, 0, NB_TX_DESC,
147                                         rte_socket_id(), NULL) < 0) {
148                         evt_err("Failed to setup eth port [%d] tx_queue: %d.\n",
149                                         i, 0);
150                         return -EINVAL;
151                 }
152
153                 t->mt_unsafe |= mt_state;
154                 rte_eth_promiscuous_enable(i);
155         }
156
157         return 0;
158 }
159
160 void
161 pipeline_ethdev_destroy(struct evt_test *test, struct evt_options *opt)
162 {
163         int i;
164         RTE_SET_USED(test);
165         RTE_SET_USED(opt);
166
167         for (i = 0; i < rte_eth_dev_count(); i++) {
168                 rte_event_eth_rx_adapter_stop(i);
169                 rte_eth_dev_stop(i);
170                 rte_eth_dev_close(i);
171         }
172 }
173
174 void
175 pipeline_eventdev_destroy(struct evt_test *test, struct evt_options *opt)
176 {
177         RTE_SET_USED(test);
178
179         rte_event_dev_stop(opt->dev_id);
180         rte_event_dev_close(opt->dev_id);
181 }
182
183 int
184 pipeline_mempool_setup(struct evt_test *test, struct evt_options *opt)
185 {
186         struct test_pipeline *t = evt_test_priv(test);
187
188         t->pool = rte_pktmbuf_pool_create(test->name, /* mempool name */
189                         opt->pool_sz, /* number of elements*/
190                         512, /* cache size*/
191                         0,
192                         RTE_MBUF_DEFAULT_BUF_SIZE,
193                         opt->socket_id); /* flags */
194
195         if (t->pool == NULL) {
196                 evt_err("failed to create mempool");
197                 return -ENOMEM;
198         }
199
200         return 0;
201 }
202
203 void
204 pipeline_mempool_destroy(struct evt_test *test, struct evt_options *opt)
205 {
206         RTE_SET_USED(opt);
207         struct test_pipeline *t = evt_test_priv(test);
208
209         rte_mempool_free(t->pool);
210 }
211
212 int
213 pipeline_test_setup(struct evt_test *test, struct evt_options *opt)
214 {
215         void *test_pipeline;
216
217         test_pipeline = rte_zmalloc_socket(test->name,
218                         sizeof(struct test_pipeline), RTE_CACHE_LINE_SIZE,
219                         opt->socket_id);
220         if (test_pipeline  == NULL) {
221                 evt_err("failed to allocate test_pipeline memory");
222                 goto nomem;
223         }
224         test->test_priv = test_pipeline;
225
226         struct test_pipeline *t = evt_test_priv(test);
227
228         t->nb_workers = evt_nr_active_lcores(opt->wlcores);
229         t->outstand_pkts = opt->nb_pkts * evt_nr_active_lcores(opt->wlcores);
230         t->done = false;
231         t->nb_flows = opt->nb_flows;
232         t->result = EVT_TEST_FAILED;
233         t->opt = opt;
234         opt->prod_type = EVT_PROD_TYPE_ETH_RX_ADPTR;
235         memcpy(t->sched_type_list, opt->sched_type_list,
236                         sizeof(opt->sched_type_list));
237         return 0;
238 nomem:
239         return -ENOMEM;
240 }
241
242 void
243 pipeline_test_destroy(struct evt_test *test, struct evt_options *opt)
244 {
245         RTE_SET_USED(opt);
246
247         rte_free(test->test_priv);
248 }