xref: /dpdk/doc/guides/prog_guide/eventdev/event_dma_adapter.rst (revision 41dd9a6bc2d9c6e20e139ad713cc9d172572dd43)
1*41dd9a6bSDavid Young.. SPDX-License-Identifier: BSD-3-Clause
2*41dd9a6bSDavid Young   Copyright (c) 2023 Marvell.
3*41dd9a6bSDavid Young
4*41dd9a6bSDavid YoungEvent DMA Adapter Library
5*41dd9a6bSDavid Young=========================
6*41dd9a6bSDavid Young
7*41dd9a6bSDavid YoungDPDK :doc:`eventdev library <eventdev>` provides event driven programming model
8*41dd9a6bSDavid Youngwith features to schedule events.
9*41dd9a6bSDavid Young:doc:`../dmadev` provides an interface to DMA poll mode drivers
10*41dd9a6bSDavid Youngthat support DMA operations.
11*41dd9a6bSDavid YoungEvent DMA adapter is intended to bridge between the event device and the DMA device.
12*41dd9a6bSDavid Young
13*41dd9a6bSDavid YoungPacket flow from DMA device to the event device can be accomplished
14*41dd9a6bSDavid Youngusing software and hardware based transfer mechanisms.
15*41dd9a6bSDavid YoungThe adapter queries an eventdev PMD to determine which mechanism to be used.
16*41dd9a6bSDavid YoungThe adapter uses an EAL service core function for software-based packet transfer
17*41dd9a6bSDavid Youngand uses the eventdev PMD functions to configure hardware-based packet transfer
18*41dd9a6bSDavid Youngbetween DMA device and the event device.
19*41dd9a6bSDavid YoungDMA adapter uses a new event type called ``RTE_EVENT_TYPE_DMADEV``
20*41dd9a6bSDavid Youngto indicate the source of event.
21*41dd9a6bSDavid Young
22*41dd9a6bSDavid YoungApplication can choose to submit a DMA operation directly to a DMA device
23*41dd9a6bSDavid Youngor send it to a DMA adapter via eventdev
24*41dd9a6bSDavid Youngbased on ``RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD`` capability.
25*41dd9a6bSDavid YoungThe first mode is known as the event new (``RTE_EVENT_DMA_ADAPTER_OP_NEW``) mode
26*41dd9a6bSDavid Youngand the second as the event forward (``RTE_EVENT_DMA_ADAPTER_OP_FORWARD``) mode.
27*41dd9a6bSDavid YoungChoice of mode can be specified while creating the adapter.
28*41dd9a6bSDavid YoungIn the former mode, it is the application's responsibility to enable ingress packet ordering.
29*41dd9a6bSDavid YoungIn the latter mode, it is the adapter's responsibility to enable ingress packet ordering.
30*41dd9a6bSDavid Young
31*41dd9a6bSDavid Young
32*41dd9a6bSDavid YoungAdapter Modes
33*41dd9a6bSDavid Young-------------
34*41dd9a6bSDavid Young
35*41dd9a6bSDavid YoungRTE_EVENT_DMA_ADAPTER_OP_NEW mode
36*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37*41dd9a6bSDavid Young
38*41dd9a6bSDavid YoungIn the ``RTE_EVENT_DMA_ADAPTER_OP_NEW`` mode,
39*41dd9a6bSDavid Youngapplication submits DMA operations directly to an DMA device.
40*41dd9a6bSDavid YoungThe adapter then dequeues DMA completions from the DMA device
41*41dd9a6bSDavid Youngand enqueues them as events to the event device.
42*41dd9a6bSDavid YoungThis mode does not ensure ingress ordering
43*41dd9a6bSDavid Youngas the application directly enqueues to the dmadev without going through DMA/atomic stage.
44*41dd9a6bSDavid YoungIn this mode, events dequeued from the adapter are treated as new events.
45*41dd9a6bSDavid YoungThe application has to specify event information (response information)
46*41dd9a6bSDavid Youngwhich is needed to enqueue an event after the DMA operation is completed.
47*41dd9a6bSDavid Young
48*41dd9a6bSDavid Young.. _figure_event_dma_adapter_op_new:
49*41dd9a6bSDavid Young
50*41dd9a6bSDavid Young.. figure:: ../img/event_dma_adapter_op_new.*
51*41dd9a6bSDavid Young
52*41dd9a6bSDavid Young   Working model of ``RTE_EVENT_DMA_ADAPTER_OP_NEW`` mode
53*41dd9a6bSDavid Young
54*41dd9a6bSDavid Young
55*41dd9a6bSDavid YoungRTE_EVENT_DMA_ADAPTER_OP_FORWARD mode
56*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57*41dd9a6bSDavid Young
58*41dd9a6bSDavid YoungIn the ``RTE_EVENT_DMA_ADAPTER_OP_FORWARD`` mode,
59*41dd9a6bSDavid Youngif the event PMD and DMA PMD supports internal event port
60*41dd9a6bSDavid Young(``RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD``),
61*41dd9a6bSDavid Youngthe application should use ``rte_event_dma_adapter_enqueue()`` API
62*41dd9a6bSDavid Youngto enqueue DMA operations as events to DMA adapter.
63*41dd9a6bSDavid YoungIf not, application retrieves DMA adapter's event port
64*41dd9a6bSDavid Youngusing ``rte_event_dma_adapter_event_port_get()`` API,
65*41dd9a6bSDavid Younglinks its event queue to this port
66*41dd9a6bSDavid Youngand starts enqueuing DMA operations as events to eventdev
67*41dd9a6bSDavid Youngusing ``rte_event_enqueue_burst()``.
68*41dd9a6bSDavid YoungThe adapter then dequeues the events
69*41dd9a6bSDavid Youngand submits the DMA operations to the dmadev.
70*41dd9a6bSDavid YoungAfter the DMA operation is complete,
71*41dd9a6bSDavid Youngthe adapter enqueues events to the event device.
72*41dd9a6bSDavid Young
73*41dd9a6bSDavid YoungApplications can use this mode when ingress packet ordering is needed.
74*41dd9a6bSDavid YoungIn this mode, events dequeued from the adapter will be treated as forwarded events.
75*41dd9a6bSDavid YoungApplication has to specify event information (response information)
76*41dd9a6bSDavid Youngneeded to enqueue the event after the DMA operation has completed.
77*41dd9a6bSDavid Young
78*41dd9a6bSDavid Young.. _figure_event_dma_adapter_op_forward:
79*41dd9a6bSDavid Young
80*41dd9a6bSDavid Young.. figure:: ../img/event_dma_adapter_op_forward.*
81*41dd9a6bSDavid Young
82*41dd9a6bSDavid Young   Working model of ``RTE_EVENT_DMA_ADAPTER_OP_FORWARD`` mode
83*41dd9a6bSDavid Young
84*41dd9a6bSDavid Young
85*41dd9a6bSDavid YoungAPI Overview
86*41dd9a6bSDavid Young------------
87*41dd9a6bSDavid Young
88*41dd9a6bSDavid YoungThis section has a brief introduction to the event DMA adapter APIs.
89*41dd9a6bSDavid YoungThe application is expected to create an adapter
90*41dd9a6bSDavid Youngwhich is associated with a single eventdev,
91*41dd9a6bSDavid Youngthen add dmadev and vchan to the adapter instance.
92*41dd9a6bSDavid Young
93*41dd9a6bSDavid Young
94*41dd9a6bSDavid YoungCreate an adapter instance
95*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~
96*41dd9a6bSDavid Young
97*41dd9a6bSDavid YoungAn adapter instance is created using ``rte_event_dma_adapter_create()``.
98*41dd9a6bSDavid YoungThis function is called with event device
99*41dd9a6bSDavid Youngto be associated with the adapter and port configuration
100*41dd9a6bSDavid Youngfor the adapter to setup an event port (if the adapter needs to use a service function).
101*41dd9a6bSDavid Young
102*41dd9a6bSDavid YoungAdapter can be started in ``RTE_EVENT_DMA_ADAPTER_OP_NEW``
103*41dd9a6bSDavid Youngor ``RTE_EVENT_DMA_ADAPTER_OP_FORWARD`` mode.
104*41dd9a6bSDavid Young
105*41dd9a6bSDavid Young.. code-block:: c
106*41dd9a6bSDavid Young
107*41dd9a6bSDavid Young   enum rte_event_dma_adapter_mode mode;
108*41dd9a6bSDavid Young   struct rte_event_dev_info dev_info;
109*41dd9a6bSDavid Young   struct rte_event_port_conf conf;
110*41dd9a6bSDavid Young   uint8_t evdev_id;
111*41dd9a6bSDavid Young   uint8_t dma_id;
112*41dd9a6bSDavid Young   int ret;
113*41dd9a6bSDavid Young
114*41dd9a6bSDavid Young   ret = rte_event_dev_info_get(dma_id, &dev_info);
115*41dd9a6bSDavid Young
116*41dd9a6bSDavid Young   conf.new_event_threshold = dev_info.max_num_events;
117*41dd9a6bSDavid Young   conf.dequeue_depth = dev_info.max_event_port_dequeue_depth;
118*41dd9a6bSDavid Young   conf.enqueue_depth = dev_info.max_event_port_enqueue_depth;
119*41dd9a6bSDavid Young   mode = RTE_EVENT_DMA_ADAPTER_OP_FORWARD;
120*41dd9a6bSDavid Young   ret = rte_event_dma_adapter_create(dma_id, evdev_id, &conf, mode);
121*41dd9a6bSDavid Young
122*41dd9a6bSDavid Young
123*41dd9a6bSDavid Young``rte_event_dma_adapter_create_ext()`` function can be used by the application
124*41dd9a6bSDavid Youngto have a finer control on eventdev port allocation and setup.
125*41dd9a6bSDavid YoungThe ``rte_event_dma_adapter_create_ext()`` function is passed a callback function.
126*41dd9a6bSDavid YoungThe callback function is invoked if the adapter creates a service function
127*41dd9a6bSDavid Youngand uses an event port for it.
128*41dd9a6bSDavid YoungThe callback is expected to fill the ``struct rte_event_dma_adapter_conf`` passed to it.
129*41dd9a6bSDavid Young
130*41dd9a6bSDavid YoungIn the ``RTE_EVENT_DMA_ADAPTER_OP_FORWARD`` mode,
131*41dd9a6bSDavid Youngif the event PMD and DMA PMD supports internal event port
132*41dd9a6bSDavid Young(``RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD``),
133*41dd9a6bSDavid Youngevents with DMA operations should be enqueued to the DMA adapter
134*41dd9a6bSDavid Youngusing ``rte_event_dma_adapter_enqueue()`` API.
135*41dd9a6bSDavid YoungIf not, the event port created by the adapter can be retrieved
136*41dd9a6bSDavid Youngusing ``rte_event_dma_adapter_event_port_get()`` API.
137*41dd9a6bSDavid YoungAn application can use this event port to link with an event queue,
138*41dd9a6bSDavid Youngon which it enqueues events towards the DMA adapter using ``rte_event_enqueue_burst()``.
139*41dd9a6bSDavid Young
140*41dd9a6bSDavid Young.. code-block:: c
141*41dd9a6bSDavid Young
142*41dd9a6bSDavid Young   uint8_t dma_adpt_id, evdev_id, dma_dev_id, dma_ev_port_id, app_qid;
143*41dd9a6bSDavid Young   struct rte_event ev;
144*41dd9a6bSDavid Young   uint32_t cap;
145*41dd9a6bSDavid Young   int ret;
146*41dd9a6bSDavid Young
147*41dd9a6bSDavid Young   /* Fill in event info and update event_ptr with rte_event_dma_adapter_op */
148*41dd9a6bSDavid Young   memset(&ev, 0, sizeof(ev));
149*41dd9a6bSDavid Young   .
150*41dd9a6bSDavid Young   .
151*41dd9a6bSDavid Young   ev.event_ptr = op;
152*41dd9a6bSDavid Young
153*41dd9a6bSDavid Young   ret = rte_event_dma_adapter_caps_get(evdev_id, dma_dev_id, &cap);
154*41dd9a6bSDavid Young   if (cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) {
155*41dd9a6bSDavid Young           ret = rte_event_dma_adapter_enqueue(evdev_id, app_ev_port_id, ev, nb_events);
156*41dd9a6bSDavid Young   } else {
157*41dd9a6bSDavid Young           ret = rte_event_dma_adapter_event_port_get(dma_adpt_id, &dma_ev_port_id);
158*41dd9a6bSDavid Young           ret = rte_event_queue_setup(evdev_id, app_qid, NULL);
159*41dd9a6bSDavid Young           ret = rte_event_port_link(evdev_id, dma_ev_port_id, &app_qid, NULL, 1);
160*41dd9a6bSDavid Young           ev.queue_id = app_qid;
161*41dd9a6bSDavid Young           ret = rte_event_enqueue_burst(evdev_id, app_ev_port_id, ev, nb_events);
162*41dd9a6bSDavid Young   }
163*41dd9a6bSDavid Young
164*41dd9a6bSDavid Young
165*41dd9a6bSDavid YoungEvent device configuration for service based adapter
166*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
167*41dd9a6bSDavid Young
168*41dd9a6bSDavid YoungWhen ``rte_event_dma_adapter_create()`` is used for creating adapter instance,
169*41dd9a6bSDavid Young``rte_event_dev_config::nb_event_ports`` is automatically incremented,
170*41dd9a6bSDavid Youngand event device is reconfigured with additional event port during service initialization.
171*41dd9a6bSDavid YoungThis event device reconfigure logic also
172*41dd9a6bSDavid Youngincrements the ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
173*41dd9a6bSDavid Youngif the adapter event port config is of type ``RTE_EVENT_PORT_CFG_SINGLE_LINK``.
174*41dd9a6bSDavid Young
175*41dd9a6bSDavid YoungApplications using this mode of adapter creation need not configure the event device
176*41dd9a6bSDavid Youngwith ``rte_event_dev_config::nb_event_ports`` and
177*41dd9a6bSDavid Young``rte_event_dev_config::nb_single_link_event_port_queues`` parameters
178*41dd9a6bSDavid Youngrequired for DMA adapter when the adapter is created using the above-mentioned API.
179*41dd9a6bSDavid Young
180*41dd9a6bSDavid Young
181*41dd9a6bSDavid YoungQuerying adapter capabilities
182*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183*41dd9a6bSDavid Young
184*41dd9a6bSDavid YoungThe ``rte_event_dma_adapter_caps_get()`` function allows the application
185*41dd9a6bSDavid Youngto query the adapter capabilities for an eventdev and dmadev combination.
186*41dd9a6bSDavid YoungThis API provides whether dmadev and eventdev are connected using internal HW port or not.
187*41dd9a6bSDavid Young
188*41dd9a6bSDavid Young.. code-block:: c
189*41dd9a6bSDavid Young
190*41dd9a6bSDavid Young   rte_event_dma_adapter_caps_get(dev_id, dma_dev_id, &cap);
191*41dd9a6bSDavid Young
192*41dd9a6bSDavid Young
193*41dd9a6bSDavid YoungAdding vchan to the adapter instance
194*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195*41dd9a6bSDavid Young
196*41dd9a6bSDavid Youngdmadev device ID and vchan are configured using dmadev APIs.
197*41dd9a6bSDavid YoungFor more information, see :doc:`dmadev <../dmadev>`.
198*41dd9a6bSDavid Young
199*41dd9a6bSDavid Young.. code-block:: c
200*41dd9a6bSDavid Young
201*41dd9a6bSDavid Young   struct rte_dma_vchan_conf vchan_conf;
202*41dd9a6bSDavid Young   struct rte_dma_conf dev_conf;
203*41dd9a6bSDavid Young   uint8_t dev_id = 0;
204*41dd9a6bSDavid Young   uint16_t vchan = 0;
205*41dd9a6bSDavid Young
206*41dd9a6bSDavid Young   rte_dma_configure(dev_id, &dev_conf);
207*41dd9a6bSDavid Young   rte_dma_vchan_setup(dev_id, vchan, &vchan_conf);
208*41dd9a6bSDavid Young
209*41dd9a6bSDavid YoungThese dmadev ID and vchan are added to the instance
210*41dd9a6bSDavid Youngusing the ``rte_event_dma_adapter_vchan_add()`` API.
211*41dd9a6bSDavid YoungThe same is removed using ``rte_event_dma_adapter_vchan_del()`` API.
212*41dd9a6bSDavid YoungIf hardware supports ``RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_VCHAN_EV_BIND`` capability,
213*41dd9a6bSDavid Youngevent information must be passed to the add API.
214*41dd9a6bSDavid Young
215*41dd9a6bSDavid Young.. code-block:: c
216*41dd9a6bSDavid Young
217*41dd9a6bSDavid Young   uint32_t cap;
218*41dd9a6bSDavid Young   int ret;
219*41dd9a6bSDavid Young
220*41dd9a6bSDavid Young   ret = rte_event_dma_adapter_caps_get(evdev_id, dma_dev_id, &cap);
221*41dd9a6bSDavid Young   if (cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_VCHAN_EV_BIND) {
222*41dd9a6bSDavid Young           struct rte_event event;
223*41dd9a6bSDavid Young
224*41dd9a6bSDavid Young           rte_event_dma_adapter_vchan_add(id, dma_dev_id, vchan, &conf);
225*41dd9a6bSDavid Young   } else
226*41dd9a6bSDavid Young           rte_event_dma_adapter_vchan_add(id, dma_dev_id, vchan, NULL);
227*41dd9a6bSDavid Young
228*41dd9a6bSDavid Young
229*41dd9a6bSDavid YoungConfiguring service function
230*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231*41dd9a6bSDavid Young
232*41dd9a6bSDavid YoungIf the adapter uses a service function, the application is required
233*41dd9a6bSDavid Youngto assign a service core to the service function as show below.
234*41dd9a6bSDavid Young
235*41dd9a6bSDavid Young.. code-block:: c
236*41dd9a6bSDavid Young
237*41dd9a6bSDavid Young   uint32_t service_id;
238*41dd9a6bSDavid Young
239*41dd9a6bSDavid Young   if (rte_event_dma_adapter_service_id_get(dma_id, &service_id) == 0)
240*41dd9a6bSDavid Young           rte_service_map_lcore_set(service_id, CORE_ID);
241*41dd9a6bSDavid Young
242*41dd9a6bSDavid Young
243*41dd9a6bSDavid YoungSet event response information
244*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
245*41dd9a6bSDavid Young
246*41dd9a6bSDavid YoungIn the ``RTE_EVENT_DMA_ADAPTER_OP_FORWARD`` / ``RTE_EVENT_DMA_ADAPTER_OP_NEW`` mode,
247*41dd9a6bSDavid Youngthe application specifies the dmadev ID and vchan ID in ``struct rte_event_dma_adapter_op``
248*41dd9a6bSDavid Youngand the event information (response information)
249*41dd9a6bSDavid Youngneeded to enqueue an event after the DMA operation has completed.
250*41dd9a6bSDavid YoungThe response information is specified in ``struct rte_event``
251*41dd9a6bSDavid Youngand appended to the ``struct rte_event_dma_adapter_op``.
252*41dd9a6bSDavid Young
253*41dd9a6bSDavid Young
254*41dd9a6bSDavid YoungStart the adapter instance
255*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~
256*41dd9a6bSDavid Young
257*41dd9a6bSDavid YoungThe application calls ``rte_event_dma_adapter_start()`` to start the adapter.
258*41dd9a6bSDavid YoungThis function calls the start callbacks of the eventdev PMDs
259*41dd9a6bSDavid Youngfor hardware-based eventdev-dmadev connections
260*41dd9a6bSDavid Youngand ``rte_service_run_state_set()`` to enable the service function if one exists.
261*41dd9a6bSDavid Young
262*41dd9a6bSDavid Young.. code-block:: c
263*41dd9a6bSDavid Young
264*41dd9a6bSDavid Young   rte_event_dma_adapter_start(id);
265*41dd9a6bSDavid Young
266*41dd9a6bSDavid Young.. note::
267*41dd9a6bSDavid Young
268*41dd9a6bSDavid Young   The eventdev to which the event_dma_adapter is connected should be started
269*41dd9a6bSDavid Young   before calling ``rte_event_dma_adapter_start()``.
270*41dd9a6bSDavid Young
271*41dd9a6bSDavid Young
272*41dd9a6bSDavid YoungGet adapter statistics
273*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~
274*41dd9a6bSDavid Young
275*41dd9a6bSDavid YoungThe  ``rte_event_dma_adapter_stats_get()`` function reports counters
276*41dd9a6bSDavid Youngdefined in ``struct rte_event_dma_adapter_stats``.
277*41dd9a6bSDavid YoungThe received packet and enqueued event counts are a sum of the counts
278*41dd9a6bSDavid Youngfrom the eventdev PMD callbacks if the callback is supported,
279*41dd9a6bSDavid Youngand the counts maintained by the service function, if one exists.
280*41dd9a6bSDavid Young
281*41dd9a6bSDavid Young
282*41dd9a6bSDavid YoungSet/Get adapter runtime configuration parameters
283*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
284*41dd9a6bSDavid Young
285*41dd9a6bSDavid YoungThe runtime configuration parameters of adapter can be set/get using
286*41dd9a6bSDavid Young``rte_event_dma_adapter_runtime_params_set()`` and
287*41dd9a6bSDavid Young``rte_event_dma_adapter_runtime_params_get()`` respectively.
288*41dd9a6bSDavid YoungThe parameters that can be set/get are defined in
289*41dd9a6bSDavid Young``struct rte_event_dma_adapter_runtime_params``.
290