doc: add notes about eventdev producer/consumer dependency
[dpdk.git] / doc / guides / prog_guide / event_timer_adapter.rst
1 ..  SPDX-License-Identifier: BSD-3-Clause
2     Copyright(c) 2017 Intel Corporation. All rights reserved.
3
4 Event Timer Adapter Library
5 ===========================
6
7 The DPDK
8 `Event Device library <http://doc.dpdk.org/guides/prog_guide/eventdev.html>`_
9 introduces an event driven programming model which presents applications with
10 an alternative to the polling model traditionally used in DPDK
11 applications. Event devices can be coupled with arbitrary components to provide
12 new event sources by using **event adapters**. The Event Timer Adapter is one
13 such adapter; it bridges event devices and timer mechanisms.
14
15 The Event Timer Adapter library extends the event driven model
16 by introducing a :ref:`new type of event <timer_expiry_event>` that represents
17 a timer expiration, and providing an API with which adapters can be created or
18 destroyed, and :ref:`event timers <event_timer>` can be armed and canceled.
19
20 The Event Timer Adapter library is designed to interface with hardware or
21 software implementations of the timer mechanism; it will query an eventdev PMD
22 to determine which implementation should be used.  The default software
23 implementation manages timers using the DPDK
24 `Timer library <http://doc.dpdk.org/guides/prog_guide/timer_lib.html>`_.
25
26 Examples of using the API are presented in the `API Overview`_ and
27 `Processing Timer Expiry Events`_ sections.  Code samples are abstracted and
28 are based on the example of handling a TCP retransmission.
29
30 .. _event_timer:
31
32 Event Timer struct
33 ------------------
34 Event timers are timers that enqueue a timer expiration event to an event
35 device upon timer expiration.
36
37 The Event Timer Adapter API represents each event timer with a generic struct,
38 which contains an event and user metadata.  The ``rte_event_timer`` struct is
39 defined in ``lib/librte_event/librte_event_timer_adapter.h``.
40
41 .. _timer_expiry_event:
42
43 Timer Expiry Event
44 ~~~~~~~~~~~~~~~~~~
45
46 The event contained by an event timer is enqueued in the event device when the
47 timer expires, and the event device uses the attributes below when scheduling
48 it:
49
50 * ``event_queue_id`` - Application should set this to specify an event queue to
51   which the timer expiry event should be enqueued
52 * ``event_priority`` - Application can set this to indicate the priority of the
53   timer expiry event in the event queue relative to other events
54 * ``sched_type`` - Application can set this to specify the scheduling type of
55   the timer expiry event
56 * ``flow_id`` - Application can set this to indicate which flow this timer
57   expiry event corresponds to
58 * ``op`` - Will be set to ``RTE_EVENT_OP_NEW`` by the event timer adapter
59 * ``event_type`` - Will be set to ``RTE_EVENT_TYPE_TIMER`` by the event timer
60   adapter
61
62 Timeout Ticks
63 ~~~~~~~~~~~~~
64
65 The number of ticks from now in which the timer will expire. The ticks value
66 has a resolution (``timer_tick_ns``) that is specified in the event timer
67 adapter configuration.
68
69 State
70 ~~~~~
71
72 Before arming an event timer, the application should initialize its state to
73 RTE_EVENT_TIMER_NOT_ARMED. The event timer's state will be updated when a
74 request to arm or cancel it takes effect.
75
76 If the application wishes to rearm the timer after it has expired, it should
77 reset the state back to RTE_EVENT_TIMER_NOT_ARMED before doing so.
78
79 User Metadata
80 ~~~~~~~~~~~~~
81
82 Memory to store user specific metadata.  The event timer adapter implementation
83 will not modify this area.
84
85 API Overview
86 ------------
87
88 This section will introduce the reader to the event timer adapter API, showing
89 how to create and configure an event timer adapter and use it to manage event
90 timers.
91
92 From a high level, the setup steps are:
93
94 * rte_event_timer_adapter_create()
95 * rte_event_timer_adapter_start()
96
97 And to start and stop timers:
98
99 * rte_event_timer_arm_burst()
100 * rte_event_timer_cancel_burst()
101
102 Create and Configure an Adapter Instance
103 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
104
105 To create an event timer adapter instance, initialize an
106 ``rte_event_timer_adapter_conf`` struct with the desired values, and pass it
107 to ``rte_event_timer_adapter_create()``.
108
109 .. code-block:: c
110
111         #define NSECPERSEC 1E9 // No of ns in 1 sec
112         const struct rte_event_timer_adapter_conf adapter_config = {
113                 .event_dev_id = event_dev_id,
114                 .timer_adapter_id = 0,
115                 .clk_src = RTE_EVENT_TIMER_ADAPTER_CPU_CLK,
116                 .timer_tick_ns = NSECPERSEC / 10, // 100 milliseconds
117                 .max_tmo_nsec = 180 * NSECPERSEC // 2 minutes
118                 .nb_timers = 40000,
119                 .timer_adapter_flags = 0,
120         };
121
122         struct rte_event_timer_adapter *adapter = NULL;
123         adapter = rte_event_timer_adapter_create(&adapter_config);
124
125         if (adapter == NULL) { ... };
126
127 Before creating an instance of a timer adapter, the application should create
128 and configure an event device along with its event ports. Based on the event
129 device capability, it might require creating an additional event port to be
130 used by the timer adapter.  If required, the
131 ``rte_event_timer_adapter_create()`` function will use a default method to
132 configure an event port;  it will examine the current event device
133 configuration, determine the next available port identifier number, and create
134 a new event port with a default port configuration.
135
136 If the application desires to have finer control of event port allocation
137 and setup, it can use the ``rte_event_timer_adapter_create_ext()`` function.
138 This function is passed a callback function that will be invoked if the
139 adapter needs to create an event port, giving the application the opportunity
140 to control how it is done.
141
142 Retrieve Event Timer Adapter Contextual Information
143 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
144 The event timer adapter implementation may have constraints on tick resolution
145 or maximum timer expiry timeout based on the given event timer adapter or
146 system.  In this case, the implementation may adjust the tick resolution or
147 maximum timeout to the best possible configuration.
148
149 Upon successful event timer adapter creation, the application can get the
150 configured resolution and max timeout with
151 ``rte_event_timer_adapter_get_info()``. This function will return an
152 ``rte_event_timer_adapter_info`` struct, which contains the following members:
153
154 * ``min_resolution_ns`` - Minimum timer adapter tick resolution in ns.
155 * ``max_tmo_ns`` - Maximum timer timeout(expiry) in ns.
156 * ``adapter_conf`` - Configured event timer adapter attributes
157
158 Configuring the Service Component
159 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
160
161 If the adapter uses a service component, the application is required to map
162 the service to a service core before starting the adapter:
163
164 .. code-block:: c
165
166         uint32_t service_id;
167
168         if (rte_event_timer_adapter_service_id_get(adapter, &service_id) == 0)
169                 rte_service_map_lcore_set(service_id, EVTIM_CORE_ID);
170
171 An event timer adapter uses a service component if the event device PMD
172 indicates that the adapter should use a software implementation.
173
174 Starting the Adapter Instance
175 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
176
177 The application should call ``rte_event_timer_adapter_start()`` to start
178 running the event timer adapter. This function calls the start entry points
179 defined by eventdev PMDs for hardware implementations or puts a service
180 component into the running state in the software implementation.
181
182 .. Note::
183
184          The eventdev to which the event_timer_adapter is connected needs to
185          be started before calling rte_event_timer_adapter_start().
186
187 Arming Event Timers
188 ~~~~~~~~~~~~~~~~~~~
189
190 Once an event timer adapter has been started, an application can begin to
191 manage event timers with it.
192
193 The application should allocate ``struct rte_event_timer`` objects from a
194 mempool or huge-page backed application buffers of required size. Upon
195 successful allocation, the application should initialize the event timer, and
196 then set any of the necessary event attributes described in the
197 `Timer Expiry Event`_ section. In the following example, assume ``conn``
198 represents a TCP connection and that ``event_timer_pool`` is a mempool that
199 was created previously:
200
201 .. code-block:: c
202
203         rte_mempool_get(event_timer_pool, (void **)&conn->evtim);
204         if (conn->evtim == NULL) { ... }
205
206         /* Set up the event timer. */
207         conn->evtim->ev.op = RTE_EVENT_OP_NEW;
208         conn->evtim->ev.queue_id = event_queue_id;
209         conn->evtim->ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
210         conn->evtim->ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL;
211         conn->evtim->ev.event_type = RTE_EVENT_TYPE_TIMER;
212         conn->evtim->ev.event_ptr = conn;
213         conn->evtim->state = RTE_EVENT_TIMER_NOT_ARMED;
214         conn->evtim->timeout_ticks = 30; //3 sec Per RFC1122(TCP returns)
215
216 Note that it is necessary to initialize the event timer state to
217 RTE_EVENT_TIMER_NOT_ARMED.  Also note that we have saved a pointer to the
218 ``conn`` object in the timer's event payload. This will allow us to locate
219 the connection object again once we dequeue the timer expiry event from the
220 event device later.  As a convenience, the application may specify no value for
221 ev.event_ptr, and the adapter will by default set it to point at the event
222 timer itself.
223
224 Now we can arm the event timer with ``rte_event_timer_arm_burst()``:
225
226 .. code-block:: c
227
228         ret = rte_event_timer_arm_burst(adapter, &conn->evtim, 1);
229         if (ret != 1) { ... }
230
231 Once an event timer expires, the application may free it or rearm it as
232 necessary.  If the application will rearm the timer, the state should be reset
233 to RTE_EVENT_TIMER_NOT_ARMED by the application before rearming it.
234
235 Multiple Event Timers with Same Expiry Value
236 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
237
238 In the special case that there is a set of event timers that should all expire
239 at the same time, the application may call
240 ``rte_event_timer_arm_tmo_tick_burst()``, which allows the implementation to
241 optimize the operation if possible.
242
243 Canceling Event Timers
244 ~~~~~~~~~~~~~~~~~~~~~~
245
246 An event timer that has been armed as described in `Arming Event Timers`_ can
247 be canceled by calling ``rte_event_timer_cancel_burst()``:
248
249 .. code-block:: c
250
251         /* Ack for the previous tcp data packet has been received;
252          * cancel the retransmission timer
253          */
254         rte_event_timer_cancel_burst(adapter, &conn->timer, 1);
255
256 Processing Timer Expiry Events
257 ------------------------------
258
259 Once an event timer has successfully enqueued a timer expiry event in the event
260 device, the application will subsequently dequeue it from the event device.
261 The application can use the event payload to retrieve a pointer to the object
262 associated with the event timer. It can then re-arm the event timer or free the
263 event timer object as desired:
264
265 .. code-block:: c
266
267         void
268         event_processing_loop(...)
269         {
270                 while (...) {
271                         /* Receive events from the configured event port. */
272                         rte_event_dequeue_burst(event_dev_id, event_port, &ev, 1, 0);
273                         ...
274                         switch(ev.event_type) {
275                                 ...
276                                 case RTE_EVENT_TYPE_TIMER:
277                                         process_timer_event(ev);
278                                         ...
279                                         break;
280                         }
281                 }
282         }
283
284         uint8_t
285         process_timer_event(...)
286         {
287                 /* A retransmission timeout for the connection has been received. */
288                 conn = ev.event_ptr;
289                 /* Retransmit last packet (e.g. TCP segment). */
290                 ...
291                 /* Re-arm timer using original values. */
292                 rte_event_timer_arm_burst(adapter_id, &conn->timer, 1);
293         }
294
295 Summary
296 -------
297
298 The Event Timer Adapter library extends the DPDK event-based programming model
299 by representing timer expirations as events in the system and allowing
300 applications to use existing event processing loops to arm and cancel event
301 timers or handle timer expiry events.