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