examples/eventdev: modify work cycles
[dpdk.git] / examples / eventdev_pipeline_sw_pmd / pipeline_common.h
1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * Copyright 2016 Intel Corporation.
4  * Copyright 2017 Cavium, Inc.
5  */
6
7 #include <stdbool.h>
8
9 #include <rte_eal.h>
10 #include <rte_mempool.h>
11 #include <rte_mbuf.h>
12 #include <rte_launch.h>
13 #include <rte_malloc.h>
14 #include <rte_random.h>
15 #include <rte_cycles.h>
16 #include <rte_ethdev.h>
17 #include <rte_eventdev.h>
18 #include <rte_event_eth_rx_adapter.h>
19 #include <rte_service.h>
20 #include <rte_service_component.h>
21
22 #define MAX_NUM_STAGES 8
23 #define BATCH_SIZE 16
24 #define MAX_NUM_CORE 64
25
26 struct cons_data {
27         uint8_t dev_id;
28         uint8_t port_id;
29         uint8_t release;
30 } __rte_cache_aligned;
31
32 struct worker_data {
33         uint8_t dev_id;
34         uint8_t port_id;
35 } __rte_cache_aligned;
36
37 typedef int (*worker_loop)(void *);
38 typedef int (*consumer_loop)(void);
39 typedef void (*schedule_loop)(unsigned int);
40 typedef int (*eventdev_setup)(struct cons_data *, struct worker_data *);
41 typedef void (*rx_adapter_setup)(uint16_t nb_ports);
42 typedef void (*opt_check)(void);
43
44 struct setup_data {
45         worker_loop worker;
46         consumer_loop consumer;
47         schedule_loop scheduler;
48         eventdev_setup evdev_setup;
49         rx_adapter_setup adptr_setup;
50         opt_check check_opt;
51 };
52
53 struct fastpath_data {
54         volatile int done;
55         uint32_t tx_lock;
56         uint32_t evdev_service_id;
57         uint32_t rxadptr_service_id;
58         bool rx_single;
59         bool tx_single;
60         bool sched_single;
61         unsigned int rx_core[MAX_NUM_CORE];
62         unsigned int tx_core[MAX_NUM_CORE];
63         unsigned int sched_core[MAX_NUM_CORE];
64         unsigned int worker_core[MAX_NUM_CORE];
65         struct rte_eth_dev_tx_buffer *tx_buf[RTE_MAX_ETHPORTS];
66         struct setup_data cap;
67 } __rte_cache_aligned;
68
69 struct config_data {
70         unsigned int active_cores;
71         unsigned int num_workers;
72         int64_t num_packets;
73         unsigned int num_fids;
74         int queue_type;
75         int worker_cycles;
76         int enable_queue_priorities;
77         int quiet;
78         int dump_dev;
79         int dump_dev_signal;
80         unsigned int num_stages;
81         unsigned int worker_cq_depth;
82         int16_t next_qid[MAX_NUM_STAGES+2];
83         int16_t qid[MAX_NUM_STAGES];
84         uint8_t rx_adapter_id;
85         uint64_t worker_lcore_mask;
86         uint64_t rx_lcore_mask;
87         uint64_t tx_lcore_mask;
88         uint64_t sched_lcore_mask;
89 };
90
91 struct port_link {
92         uint8_t queue_id;
93         uint8_t priority;
94 };
95
96 struct cons_data cons_data;
97
98 struct fastpath_data *fdata;
99 struct config_data cdata;
100
101 static __rte_always_inline void
102 exchange_mac(struct rte_mbuf *m)
103 {
104         struct ether_hdr *eth;
105         struct ether_addr addr;
106
107         /* change mac addresses on packet (to use mbuf data) */
108         eth = rte_pktmbuf_mtod(m, struct ether_hdr *);
109         ether_addr_copy(&eth->d_addr, &addr);
110         ether_addr_copy(&addr, &eth->d_addr);
111 }
112
113 static __rte_always_inline void
114 work(void)
115 {
116         /* do a number of cycles of work per packet */
117         volatile uint64_t start_tsc = rte_rdtsc();
118         while (rte_rdtsc() < start_tsc + cdata.worker_cycles)
119                 rte_pause();
120 }
121
122 static __rte_always_inline void
123 schedule_devices(unsigned int lcore_id)
124 {
125         if (fdata->rx_core[lcore_id]) {
126                 rte_service_run_iter_on_app_lcore(fdata->rxadptr_service_id,
127                                 !fdata->rx_single);
128         }
129
130         if (fdata->sched_core[lcore_id]) {
131                 rte_service_run_iter_on_app_lcore(fdata->evdev_service_id,
132                                 !fdata->sched_single);
133                 if (cdata.dump_dev_signal) {
134                         rte_event_dev_dump(0, stdout);
135                         cdata.dump_dev_signal = 0;
136                 }
137         }
138
139         if (fdata->tx_core[lcore_id] && (fdata->tx_single ||
140                          rte_atomic32_cmpset(&(fdata->tx_lock), 0, 1))) {
141                 fdata->cap.consumer();
142                 rte_atomic32_clear((rte_atomic32_t *)&(fdata->tx_lock));
143         }
144 }
145
146 void set_worker_generic_setup_data(struct setup_data *caps, bool burst);