0166bb45dee06192b8b5fb2fb02b5b78788104f6
[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. For SW based packet transfer, if the mbuf does not have a
16 timestamp set, the adapter adds a timestamp to the mbuf using
17 rte_get_tsc_cycles(), this provides a more accurate timestamp as compared to
18 if the application were to set the timestamp since it avoids event device
19 schedule latency.
20
21 The Event Ethernet Rx Adapter library is intended for the application code to
22 configure both transfer mechanisms using a common API. A capability API allows
23 the eventdev PMD to advertise features supported for a given ethdev and allows
24 the application to perform configuration as per supported features.
25
26 API Walk-through
27 ----------------
28
29 This section will introduce the reader to the adapter API. The
30 application has to first instantiate an adapter which is associated with
31 a single eventdev, next the adapter instance is configured with Rx queues
32 that are either polled by a SW thread or linked using hardware support. Finally
33 the adapter is started.
34
35 For SW based packet transfers from ethdev to eventdev, the adapter uses a
36 DPDK service function and the application is also required to assign a core to
37 the service function.
38
39 Creating an Adapter Instance
40 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41
42 An adapter instance is created using ``rte_event_eth_rx_adapter_create()``. This
43 function is passed the event device to be associated with the adapter and port
44 configuration for the adapter to setup an event port if the adapter needs to use
45 a service function.
46
47 .. code-block:: c
48
49         int err;
50         uint8_t dev_id;
51         struct rte_event_dev_info dev_info;
52         struct rte_event_port_conf rx_p_conf;
53
54         err = rte_event_dev_info_get(id, &dev_info);
55
56         rx_p_conf.new_event_threshold = dev_info.max_num_events;
57         rx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth;
58         rx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth;
59         err = rte_event_eth_rx_adapter_create(id, dev_id, &rx_p_conf);
60
61 If the application desires to have finer control of eventdev port allocation
62 and setup, it can use the ``rte_event_eth_rx_adapter_create_ext()`` function.
63 The ``rte_event_eth_rx_adapter_create_ext()`` function is passed a callback
64 function. The callback function is invoked if the adapter needs to use a
65 service function and needs to create an event port for it. The callback is
66 expected to fill the ``struct rte_event_eth_rx_adapter_conf structure``
67 passed to it.
68
69 Adding Rx Queues to the Adapter Instance
70 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71
72 Ethdev Rx queues are added to the instance using the
73 ``rte_event_eth_rx_adapter_queue_add()`` function. Configuration for the Rx
74 queue is passed in using a ``struct rte_event_eth_rx_adapter_queue_conf``
75 parameter. Event information for packets from this Rx queue is encoded in the
76 ``ev`` field of ``struct rte_event_eth_rx_adapter_queue_conf``. The
77 servicing_weight member of the struct  rte_event_eth_rx_adapter_queue_conf
78 is the relative polling frequency of the Rx queue and is applicable when the
79 adapter uses a service core function.
80
81 .. code-block:: c
82
83         ev.queue_id = 0;
84         ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
85         ev.priority = 0;
86
87         queue_config.rx_queue_flags = 0;
88         queue_config.ev = ev;
89         queue_config.servicing_weight = 1;
90
91         err = rte_event_eth_rx_adapter_queue_add(id,
92                                                 eth_dev_id,
93                                                 0, &queue_config);
94
95 Querying Adapter Capabilities
96 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97
98 The ``rte_event_eth_rx_adapter_caps_get()`` function allows
99 the application to query the adapter capabilities for an eventdev and ethdev
100 combination. For e.g, if the ``RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID``
101 is set, the application can override the adapter generated flow ID in the event
102 using ``rx_queue_flags`` field in ``struct rte_event_eth_rx_adapter_queue_conf``
103 which is passed as a parameter to the ``rte_event_eth_rx_adapter_queue_add()``
104 function.
105
106 .. code-block:: c
107
108         err = rte_event_eth_rx_adapter_caps_get(dev_id, eth_dev_id, &cap);
109
110         queue_config.rx_queue_flags = 0;
111         if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) {
112                 ev.flow_id = 1;
113                 queue_config.rx_queue_flags =
114                         RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID;
115         }
116
117 Configuring the Service Function
118 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119
120 If the adapter uses a service function, the application is required to assign
121 a service core to the service function as show below.
122
123 .. code-block:: c
124
125         uint32_t service_id;
126
127         if (rte_event_eth_rx_adapter_service_id_get(0, &service_id) == 0)
128                 rte_service_map_lcore_set(service_id, RX_CORE_ID);
129
130 Starting the Adapter Instance
131 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132
133 The application calls ``rte_event_eth_rx_adapter_start()`` to start the adapter.
134 This function calls the start callbacks of the eventdev PMDs for hardware based
135 eventdev-ethdev connections and ``rte_service_run_state_set()`` to enable the
136 service function if one exists.
137
138 Getting Adapter Statistics
139 ~~~~~~~~~~~~~~~~~~~~~~~~~~
140
141 The  ``rte_event_eth_rx_adapter_stats_get()`` function reports counters defined
142 in struct ``rte_event_eth_rx_adapter_stats``. The received packet and
143 enqueued event counts are a sum of the counts from the eventdev PMD callbacks
144 if the callback is supported, and the counts maintained by the service function,
145 if one exists. The service function also maintains a count of cycles for which
146 it was not able to enqueue to the event device.
147
148 Interrupt Based Rx Queues
149 ~~~~~~~~~~~~~~~~~~~~~~~~~~
150
151 The service core function is typically set up to poll ethernet Rx queues for
152 packets. Certain queues may have low packet rates and it would be more
153 efficient to enable the Rx queue interrupt and read packets after receiving
154 the interrupt.
155
156 The servicing_weight member of struct rte_event_eth_rx_adapter_queue_conf
157 is applicable when the adapter uses a service core function. The application
158 has to enable Rx queue interrupts when configuring the ethernet device
159 using the ``rte_eth_dev_configure()`` function and then use a servicing_weight
160 of zero when addding the Rx queue to the adapter.
161
162 The adapter creates a thread blocked on the interrupt, on an interrupt this
163 thread enqueues the port id and the queue id to a ring buffer. The adapter
164 service function dequeues the port id and queue id from the ring buffer,
165 invokes the ``rte_eth_rx_burst()`` to receive packets on the queue and
166 converts the received packets to events in the same manner as packets
167 received on a polled Rx queue. The interrupt thread is affinitized to the same
168 CPUs as the lcores of the Rx adapter service function, if the Rx adapter
169 service function has not been mapped to any lcores, the interrupt thread
170 is mapped to the master lcore.
171
172 Rx Callback for SW Rx Adapter
173 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
174
175 For SW based packet transfers, i.e., when the
176 ``RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT`` is not set in the adapter's
177 capabilities flags for a particular ethernet device, the service function
178 temporarily enqueues mbufs to an event buffer before batch enqueueing these
179 to the event device. If the buffer fills up, the service function stops
180 dequeueing packets from the ethernet device. The application may want to
181 monitor the buffer fill level and instruct the service function to selectively
182 enqueue packets to the event device. The application may also use some other
183 criteria to decide which packets should enter the event device even when
184 the event buffer fill level is low. The
185 ``rte_event_eth_rx_adapter_cb_register()`` function allow the application
186 to register a callback that selects which packets to enqueue to the event
187 device.