doc: fix build with sphinx 4.5
[dpdk.git] / doc / guides / prog_guide / event_ethernet_rx_adapter.rst
1 ..  SPDX-License-Identifier: BSD-3-Clause
2     Copyright(c) 2017 Intel Corporation.
3
4 Event Ethernet Rx Adapter Library
5 =================================
6
7 The DPDK Eventdev API allows the application to use an event driven programming
8 model for packet processing. In this model, the application polls an event
9 device port for receiving events that reference packets instead of polling Rx
10 queues of ethdev ports. Packet transfer between ethdev and the event device can
11 be supported in hardware or require a software thread to receive packets from
12 the ethdev port using ethdev poll mode APIs and enqueue these as events to the
13 event device using the eventdev API. Both transfer mechanisms may be present on
14 the same platform depending on the particular combination of the ethdev and
15 the event device.
16
17 The Event Ethernet Rx Adapter library is intended for the application code to
18 configure both transfer mechanisms using a common API. A capability API allows
19 the eventdev PMD to advertise features supported for a given ethdev and allows
20 the application to perform configuration as per supported features.
21
22 API Walk-through
23 ----------------
24
25 This section will introduce the reader to the adapter API. The
26 application has to first instantiate an adapter which is associated with
27 a single eventdev, next the adapter instance is configured with Rx queues
28 that are either polled by a SW thread or linked using hardware support. Finally
29 the adapter is started.
30
31 For SW based packet transfers from ethdev to eventdev, the adapter uses a
32 DPDK service function and the application is also required to assign a core to
33 the service function.
34
35 Creating an Adapter Instance
36 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37
38 An adapter instance is created using ``rte_event_eth_rx_adapter_create()``. This
39 function is passed the event device to be associated with the adapter and port
40 configuration for the adapter to setup an event port if the adapter needs to use
41 a service function.
42
43 .. code-block:: c
44
45         int err;
46         uint8_t dev_id;
47         struct rte_event_dev_info dev_info;
48         struct rte_event_port_conf rx_p_conf;
49
50         err = rte_event_dev_info_get(id, &dev_info);
51
52         rx_p_conf.new_event_threshold = dev_info.max_num_events;
53         rx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth;
54         rx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth;
55         err = rte_event_eth_rx_adapter_create(id, dev_id, &rx_p_conf);
56
57 If the application desires to have finer control of eventdev port allocation
58 and setup, it can use the ``rte_event_eth_rx_adapter_create_ext()`` function.
59 The ``rte_event_eth_rx_adapter_create_ext()`` function is passed a callback
60 function. The callback function is invoked if the adapter needs to use a
61 service function and needs to create an event port for it. The callback is
62 expected to fill the ``struct rte_event_eth_rx_adapter_conf structure``
63 passed to it.
64
65 If the application desires to control the event buffer size at adapter level,
66 it can use the ``rte_event_eth_rx_adapter_create_with_params()`` api. The event
67 buffer size is specified using ``struct rte_event_eth_rx_adapter_params::
68 event_buf_size``. To configure the event buffer size at queue level, the boolean
69 flag ``struct rte_event_eth_rx_adapter_params::use_queue_event_buf`` need to be
70 set to true. The function is passed the event device to be associated with
71 the adapter and port configuration for the adapter to setup an event port
72 if the adapter needs to use a service function.
73
74 Adding Rx Queues to the Adapter Instance
75 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
76
77 Ethdev Rx queues are added to the instance using the
78 ``rte_event_eth_rx_adapter_queue_add()`` function. Configuration for the Rx
79 queue is passed in using a ``struct rte_event_eth_rx_adapter_queue_conf``
80 parameter. Event information for packets from this Rx queue is encoded in the
81 ``ev`` field of ``struct rte_event_eth_rx_adapter_queue_conf``. The
82 servicing_weight member of the struct  rte_event_eth_rx_adapter_queue_conf
83 is the relative polling frequency of the Rx queue and is applicable when the
84 adapter uses a service core function. The applications can configure queue
85 event buffer size in ``struct rte_event_eth_rx_adapter_queue_conf::event_buf_size``
86 parameter.
87
88 .. code-block:: c
89
90         ev.queue_id = 0;
91         ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
92         ev.priority = 0;
93
94         queue_config.rx_queue_flags = 0;
95         queue_config.ev = ev;
96         queue_config.servicing_weight = 1;
97         queue_config.event_buf_size = 1024;
98
99         err = rte_event_eth_rx_adapter_queue_add(id,
100                                                 eth_dev_id,
101                                                 0, &queue_config);
102
103 Querying Adapter Capabilities
104 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105
106 The ``rte_event_eth_rx_adapter_caps_get()`` function allows
107 the application to query the adapter capabilities for an eventdev and ethdev
108 combination. For e.g, if the ``RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID``
109 is set, the application can override the adapter generated flow ID in the event
110 using ``rx_queue_flags`` field in ``struct rte_event_eth_rx_adapter_queue_conf``
111 which is passed as a parameter to the ``rte_event_eth_rx_adapter_queue_add()``
112 function.
113
114 .. code-block:: c
115
116         err = rte_event_eth_rx_adapter_caps_get(dev_id, eth_dev_id, &cap);
117
118         queue_config.rx_queue_flags = 0;
119         if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) {
120                 ev.flow_id = 1;
121                 queue_config.rx_queue_flags =
122                         RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID;
123         }
124
125 Configuring the Service Function
126 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
127
128 If the adapter uses a service function, the application is required to assign
129 a service core to the service function as show below.
130
131 .. code-block:: c
132
133         uint32_t service_id;
134
135         if (rte_event_eth_rx_adapter_service_id_get(0, &service_id) == 0)
136                 rte_service_map_lcore_set(service_id, RX_CORE_ID);
137
138 Starting the Adapter Instance
139 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
140
141 The application calls ``rte_event_eth_rx_adapter_start()`` to start the adapter.
142 This function calls the start callbacks of the eventdev PMDs for hardware based
143 eventdev-ethdev connections and ``rte_service_run_state_set()`` to enable the
144 service function if one exists.
145
146 .. Note::
147
148          The eventdev to which the event_eth_rx_adapter is connected needs to
149          be started before calling rte_event_eth_rx_adapter_start().
150
151 Getting Adapter Statistics
152 ~~~~~~~~~~~~~~~~~~~~~~~~~~
153
154 The  ``rte_event_eth_rx_adapter_stats_get()`` function reports counters defined
155 in struct ``rte_event_eth_rx_adapter_stats``. The received packet and
156 enqueued event counts are a sum of the counts from the eventdev PMD callbacks
157 if the callback is supported, and the counts maintained by the service function,
158 if one exists. The service function also maintains a count of cycles for which
159 it was not able to enqueue to the event device.
160
161 Getting Adapter queue config
162 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
163
164 The  ``rte_event_eth_rx_adapter_queue_conf_get()`` function reports
165 flags for handling received packets, event queue identifier, scheduler type,
166 event priority, polling frequency of the receive queue and flow identifier
167 in struct ``rte_event_eth_rx_adapter_queue_conf``.
168
169 Getting and resetting Adapter queue stats
170 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
171
172 The ``rte_event_eth_rx_adapter_queue_stats_get()`` function reports
173 adapter queue counters defined in struct ``rte_event_eth_rx_adapter_queue_stats``.
174 This function reports queue level stats only when queue level event buffer is
175 used otherwise it returns -EINVAL.
176
177 The ``rte_event_eth_rx_adapter_queue_stats_reset`` function can be used to
178 reset queue level stats when queue level event buffer is in use.
179
180 Interrupt Based Rx Queues
181 ~~~~~~~~~~~~~~~~~~~~~~~~~~
182
183 The service core function is typically set up to poll ethernet Rx queues for
184 packets. Certain queues may have low packet rates and it would be more
185 efficient to enable the Rx queue interrupt and read packets after receiving
186 the interrupt.
187
188 The servicing_weight member of struct rte_event_eth_rx_adapter_queue_conf
189 is applicable when the adapter uses a service core function. The application
190 has to enable Rx queue interrupts when configuring the ethernet device
191 using the ``rte_eth_dev_configure()`` function and then use a servicing_weight
192 of zero when adding the Rx queue to the adapter.
193
194 The adapter creates a thread blocked on the interrupt, on an interrupt this
195 thread enqueues the port id and the queue id to a ring buffer. The adapter
196 service function dequeues the port id and queue id from the ring buffer,
197 invokes the ``rte_eth_rx_burst()`` to receive packets on the queue and
198 converts the received packets to events in the same manner as packets
199 received on a polled Rx queue. The interrupt thread is affinitized to the same
200 CPUs as the lcores of the Rx adapter service function, if the Rx adapter
201 service function has not been mapped to any lcores, the interrupt thread
202 is mapped to the main lcore.
203
204 Rx Callback for SW Rx Adapter
205 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
206
207 For SW based packet transfers, i.e., when the
208 ``RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT`` is not set in the adapter's
209 capabilities flags for a particular ethernet device, the service function
210 temporarily enqueues mbufs to an event buffer before batch enqueuing these
211 to the event device. If the buffer fills up, the service function stops
212 dequeuing packets from the ethernet device. The application may want to
213 monitor the buffer fill level and instruct the service function to selectively
214 enqueue packets to the event device. The application may also use some other
215 criteria to decide which packets should enter the event device even when
216 the event buffer fill level is low. The
217 ``rte_event_eth_rx_adapter_cb_register()`` function allow the application
218 to register a callback that selects which packets to enqueue to the event
219 device.
220
221 Rx event vectorization
222 ~~~~~~~~~~~~~~~~~~~~~~
223
224 The event devices, ethernet device pairs which support the capability
225 ``RTE_EVENT_ETH_RX_ADAPTER_CAP_EVENT_VECTOR`` can aggregate packets based on
226 flow characteristics and generate a ``rte_event`` containing ``rte_event_vector``
227 whose event type is either ``RTE_EVENT_TYPE_ETHDEV_VECTOR`` or
228 ``RTE_EVENT_TYPE_ETH_RX_ADAPTER_VECTOR``.
229 The maximum, minimum vector sizes and timeouts vary based on the device
230 capability and can be queried using
231 ``rte_event_eth_rx_adapter_vector_limits_get``.
232 The Rx adapter additionally might include useful data such as ethernet device
233 port and queue identifier in the ``rte_event_vector::port`` and
234 ``rte_event_vector::queue`` and mark ``rte_event_vector::attr_valid`` as true.
235 The aggregation size and timeout are configurable at a queue level by setting
236 ``rte_event_eth_rx_adapter_queue_conf::vector_sz``,
237 ``rte_event_eth_rx_adapter_queue_conf::vector_timeout_ns`` and
238 ``rte_event_eth_rx_adapter_queue_conf::vector_mp`` when adding queues using
239 ``rte_event_eth_rx_adapter_queue_add``.
240
241 A loop processing ``rte_event_vector`` containing mbufs is shown below.
242
243 .. code-block:: c
244
245         event = rte_event_dequeue_burst(event_dev, event_port, &event,
246                                         1, 0);
247         if (!event)
248                 continue;
249
250         switch (ev.event_type) {
251         case RTE_EVENT_TYPE_ETH_RX_ADAPTER_VECTOR:
252         case RTE_EVENT_TYPE_ETHDEV_VECTOR:
253                 struct rte_mbufs **mbufs;
254
255                 mbufs = (struct rte_mbufs **)ev[i].vec->mbufs;
256                 for (i = 0; i < ev.vec->nb_elem; i++) {
257                         /* Process each mbuf. */
258                 }
259         break;
260         case default:
261                 /* Handle other event_types. */
262         }
263
264 Rx event vectorization for SW Rx adapter
265 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
266
267 For SW based event vectorization, i.e., when the
268 ``RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT`` is not set in the adapter's
269 capabilities flags for a particular ethernet device, the service function
270 creates a single event vector flow for all the mbufs arriving on the given
271 Rx queue.
272 The 20-bit event flow identifier is set to 12-bits of Rx queue identifier
273 and 8-bits of ethernet device identifier.
274 Flow identifier is formatted as follows:
275
276 .. code-block:: console
277
278     19      12,11            0
279     +---------+--------------+
280     | port_id |   queue_id   |
281     +---------+--------------+