tailq: remove unneeded inclusions
[dpdk.git] / lib / librte_timer / rte_timer.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <string.h>
35 #include <stdio.h>
36 #include <stdint.h>
37 #include <inttypes.h>
38 #include <assert.h>
39 #include <sys/queue.h>
40
41 #include <rte_atomic.h>
42 #include <rte_common.h>
43 #include <rte_cycles.h>
44 #include <rte_per_lcore.h>
45 #include <rte_memory.h>
46 #include <rte_memzone.h>
47 #include <rte_launch.h>
48 #include <rte_eal.h>
49 #include <rte_per_lcore.h>
50 #include <rte_lcore.h>
51 #include <rte_branch_prediction.h>
52 #include <rte_spinlock.h>
53 #include <rte_random.h>
54
55 #include "rte_timer.h"
56
57 LIST_HEAD(rte_timer_list, rte_timer);
58
59 struct priv_timer {
60         struct rte_timer pending_head;  /**< dummy timer instance to head up list */
61         rte_spinlock_t list_lock;       /**< lock to protect list access */
62
63         /** per-core variable that true if a timer was updated on this
64          *  core since last reset of the variable */
65         int updated;
66
67         /** track the current depth of the skiplist */
68         unsigned curr_skiplist_depth;
69
70         unsigned prev_lcore;              /**< used for lcore round robin */
71
72 #ifdef RTE_LIBRTE_TIMER_DEBUG
73         /** per-lcore statistics */
74         struct rte_timer_debug_stats stats;
75 #endif
76 } __rte_cache_aligned;
77
78 /** per-lcore private info for timers */
79 static struct priv_timer priv_timer[RTE_MAX_LCORE];
80
81 /* when debug is enabled, store some statistics */
82 #ifdef RTE_LIBRTE_TIMER_DEBUG
83 #define __TIMER_STAT_ADD(name, n) do {                                  \
84                 unsigned __lcore_id = rte_lcore_id();                   \
85                 if (__lcore_id < RTE_MAX_LCORE)                         \
86                         priv_timer[__lcore_id].stats.name += (n);       \
87         } while(0)
88 #else
89 #define __TIMER_STAT_ADD(name, n) do {} while(0)
90 #endif
91
92 /* Init the timer library. */
93 void
94 rte_timer_subsystem_init(void)
95 {
96         unsigned lcore_id;
97
98         /* since priv_timer is static, it's zeroed by default, so only init some
99          * fields.
100          */
101         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++) {
102                 rte_spinlock_init(&priv_timer[lcore_id].list_lock);
103                 priv_timer[lcore_id].prev_lcore = lcore_id;
104         }
105 }
106
107 /* Initialize the timer handle tim for use */
108 void
109 rte_timer_init(struct rte_timer *tim)
110 {
111         union rte_timer_status status;
112
113         status.state = RTE_TIMER_STOP;
114         status.owner = RTE_TIMER_NO_OWNER;
115         tim->status.u32 = status.u32;
116 }
117
118 /*
119  * if timer is pending or stopped (or running on the same core than
120  * us), mark timer as configuring, and on success return the previous
121  * status of the timer
122  */
123 static int
124 timer_set_config_state(struct rte_timer *tim,
125                        union rte_timer_status *ret_prev_status)
126 {
127         union rte_timer_status prev_status, status;
128         int success = 0;
129         unsigned lcore_id;
130
131         lcore_id = rte_lcore_id();
132
133         /* wait that the timer is in correct status before update,
134          * and mark it as being configured */
135         while (success == 0) {
136                 prev_status.u32 = tim->status.u32;
137
138                 /* timer is running on another core, exit */
139                 if (prev_status.state == RTE_TIMER_RUNNING &&
140                     prev_status.owner != (uint16_t)lcore_id)
141                         return -1;
142
143                 /* timer is being configured on another core */
144                 if (prev_status.state == RTE_TIMER_CONFIG)
145                         return -1;
146
147                 /* here, we know that timer is stopped or pending,
148                  * mark it atomically as being configured */
149                 status.state = RTE_TIMER_CONFIG;
150                 status.owner = (int16_t)lcore_id;
151                 success = rte_atomic32_cmpset(&tim->status.u32,
152                                               prev_status.u32,
153                                               status.u32);
154         }
155
156         ret_prev_status->u32 = prev_status.u32;
157         return 0;
158 }
159
160 /*
161  * if timer is pending, mark timer as running
162  */
163 static int
164 timer_set_running_state(struct rte_timer *tim)
165 {
166         union rte_timer_status prev_status, status;
167         unsigned lcore_id = rte_lcore_id();
168         int success = 0;
169
170         /* wait that the timer is in correct status before update,
171          * and mark it as running */
172         while (success == 0) {
173                 prev_status.u32 = tim->status.u32;
174
175                 /* timer is not pending anymore */
176                 if (prev_status.state != RTE_TIMER_PENDING)
177                         return -1;
178
179                 /* here, we know that timer is stopped or pending,
180                  * mark it atomically as beeing configured */
181                 status.state = RTE_TIMER_RUNNING;
182                 status.owner = (int16_t)lcore_id;
183                 success = rte_atomic32_cmpset(&tim->status.u32,
184                                               prev_status.u32,
185                                               status.u32);
186         }
187
188         return 0;
189 }
190
191 /*
192  * Return a skiplist level for a new entry.
193  * This probabalistically gives a level with p=1/4 that an entry at level n
194  * will also appear at level n+1.
195  */
196 static uint32_t
197 timer_get_skiplist_level(unsigned curr_depth)
198 {
199 #ifdef RTE_LIBRTE_TIMER_DEBUG
200         static uint32_t i, count = 0;
201         static uint32_t levels[MAX_SKIPLIST_DEPTH] = {0};
202 #endif
203
204         /* probability value is 1/4, i.e. all at level 0, 1 in 4 is at level 1,
205          * 1 in 16 at level 2, 1 in 64 at level 3, etc. Calculated using lowest
206          * bit position of a (pseudo)random number.
207          */
208         uint32_t rand = rte_rand() & (UINT32_MAX - 1);
209         uint32_t level = rand == 0 ? MAX_SKIPLIST_DEPTH : (rte_bsf32(rand)-1) / 2;
210
211         /* limit the levels used to one above our current level, so we don't,
212          * for instance, have a level 0 and a level 7 without anything between
213          */
214         if (level > curr_depth)
215                 level = curr_depth;
216         if (level >= MAX_SKIPLIST_DEPTH)
217                 level = MAX_SKIPLIST_DEPTH-1;
218 #ifdef RTE_LIBRTE_TIMER_DEBUG
219         count ++;
220         levels[level]++;
221         if (count % 10000 == 0)
222                 for (i = 0; i < MAX_SKIPLIST_DEPTH; i++)
223                         printf("Level %u: %u\n", (unsigned)i, (unsigned)levels[i]);
224 #endif
225         return level;
226 }
227
228 /*
229  * For a given time value, get the entries at each level which
230  * are <= that time value.
231  */
232 static void
233 timer_get_prev_entries(uint64_t time_val, unsigned tim_lcore,
234                 struct rte_timer **prev)
235 {
236         unsigned lvl = priv_timer[tim_lcore].curr_skiplist_depth;
237         prev[lvl] = &priv_timer[tim_lcore].pending_head;
238         while(lvl != 0) {
239                 lvl--;
240                 prev[lvl] = prev[lvl+1];
241                 while (prev[lvl]->sl_next[lvl] &&
242                                 prev[lvl]->sl_next[lvl]->expire <= time_val)
243                         prev[lvl] = prev[lvl]->sl_next[lvl];
244         }
245 }
246
247 /*
248  * Given a timer node in the skiplist, find the previous entries for it at
249  * all skiplist levels.
250  */
251 static void
252 timer_get_prev_entries_for_node(struct rte_timer *tim, unsigned tim_lcore,
253                 struct rte_timer **prev)
254 {
255         int i;
256         /* to get a specific entry in the list, look for just lower than the time
257          * values, and then increment on each level individually if necessary
258          */
259         timer_get_prev_entries(tim->expire - 1, tim_lcore, prev);
260         for (i = priv_timer[tim_lcore].curr_skiplist_depth - 1; i >= 0; i--) {
261                 while (prev[i]->sl_next[i] != NULL &&
262                                 prev[i]->sl_next[i] != tim &&
263                                 prev[i]->sl_next[i]->expire <= tim->expire)
264                         prev[i] = prev[i]->sl_next[i];
265         }
266 }
267
268 /*
269  * add in list, lock if needed
270  * timer must be in config state
271  * timer must not be in a list
272  */
273 static void
274 timer_add(struct rte_timer *tim, unsigned tim_lcore, int local_is_locked)
275 {
276         unsigned lcore_id = rte_lcore_id();
277         unsigned lvl;
278         struct rte_timer *prev[MAX_SKIPLIST_DEPTH+1];
279
280         /* if timer needs to be scheduled on another core, we need to
281          * lock the list; if it is on local core, we need to lock if
282          * we are not called from rte_timer_manage() */
283         if (tim_lcore != lcore_id || !local_is_locked)
284                 rte_spinlock_lock(&priv_timer[tim_lcore].list_lock);
285
286         /* find where exactly this element goes in the list of elements
287          * for each depth. */
288         timer_get_prev_entries(tim->expire, tim_lcore, prev);
289
290         /* now assign it a new level and add at that level */
291         const unsigned tim_level = timer_get_skiplist_level(
292                         priv_timer[tim_lcore].curr_skiplist_depth);
293         if (tim_level == priv_timer[tim_lcore].curr_skiplist_depth)
294                 priv_timer[tim_lcore].curr_skiplist_depth++;
295
296         lvl = tim_level;
297         while (lvl > 0) {
298                 tim->sl_next[lvl] = prev[lvl]->sl_next[lvl];
299                 prev[lvl]->sl_next[lvl] = tim;
300                 lvl--;
301         }
302         tim->sl_next[0] = prev[0]->sl_next[0];
303         prev[0]->sl_next[0] = tim;
304
305         /* save the lowest list entry into the expire field of the dummy hdr
306          * NOTE: this is not atomic on 32-bit*/
307         priv_timer[tim_lcore].pending_head.expire = priv_timer[tim_lcore].\
308                         pending_head.sl_next[0]->expire;
309
310         if (tim_lcore != lcore_id || !local_is_locked)
311                 rte_spinlock_unlock(&priv_timer[tim_lcore].list_lock);
312 }
313
314 /*
315  * del from list, lock if needed
316  * timer must be in config state
317  * timer must be in a list
318  */
319 static void
320 timer_del(struct rte_timer *tim, union rte_timer_status prev_status,
321                 int local_is_locked)
322 {
323         unsigned lcore_id = rte_lcore_id();
324         unsigned prev_owner = prev_status.owner;
325         int i;
326         struct rte_timer *prev[MAX_SKIPLIST_DEPTH+1];
327
328         /* if timer needs is pending another core, we need to lock the
329          * list; if it is on local core, we need to lock if we are not
330          * called from rte_timer_manage() */
331         if (prev_owner != lcore_id || !local_is_locked)
332                 rte_spinlock_lock(&priv_timer[prev_owner].list_lock);
333
334         /* save the lowest list entry into the expire field of the dummy hdr.
335          * NOTE: this is not atomic on 32-bit */
336         if (tim == priv_timer[prev_owner].pending_head.sl_next[0])
337                 priv_timer[prev_owner].pending_head.expire =
338                                 ((tim->sl_next[0] == NULL) ? 0 : tim->sl_next[0]->expire);
339
340         /* adjust pointers from previous entries to point past this */
341         timer_get_prev_entries_for_node(tim, prev_owner, prev);
342         for (i = priv_timer[prev_owner].curr_skiplist_depth - 1; i >= 0; i--) {
343                 if (prev[i]->sl_next[i] == tim)
344                         prev[i]->sl_next[i] = tim->sl_next[i];
345         }
346
347         /* in case we deleted last entry at a level, adjust down max level */
348         for (i = priv_timer[prev_owner].curr_skiplist_depth - 1; i >= 0; i--)
349                 if (priv_timer[prev_owner].pending_head.sl_next[i] == NULL)
350                         priv_timer[prev_owner].curr_skiplist_depth --;
351                 else
352                         break;
353
354         if (prev_owner != lcore_id || !local_is_locked)
355                 rte_spinlock_unlock(&priv_timer[prev_owner].list_lock);
356 }
357
358 /* Reset and start the timer associated with the timer handle (private func) */
359 static int
360 __rte_timer_reset(struct rte_timer *tim, uint64_t expire,
361                   uint64_t period, unsigned tim_lcore,
362                   rte_timer_cb_t fct, void *arg,
363                   int local_is_locked)
364 {
365         union rte_timer_status prev_status, status;
366         int ret;
367         unsigned lcore_id = rte_lcore_id();
368
369         /* round robin for tim_lcore */
370         if (tim_lcore == (unsigned)LCORE_ID_ANY) {
371                 if (lcore_id < RTE_MAX_LCORE) {
372                         /* EAL thread with valid lcore_id */
373                         tim_lcore = rte_get_next_lcore(
374                                 priv_timer[lcore_id].prev_lcore,
375                                 0, 1);
376                         priv_timer[lcore_id].prev_lcore = tim_lcore;
377                 } else
378                         /* non-EAL thread do not run rte_timer_manage(),
379                          * so schedule the timer on the first enabled lcore. */
380                         tim_lcore = rte_get_next_lcore(LCORE_ID_ANY, 0, 1);
381         }
382
383         /* wait that the timer is in correct status before update,
384          * and mark it as being configured */
385         ret = timer_set_config_state(tim, &prev_status);
386         if (ret < 0)
387                 return -1;
388
389         __TIMER_STAT_ADD(reset, 1);
390         if (prev_status.state == RTE_TIMER_RUNNING &&
391             lcore_id < RTE_MAX_LCORE) {
392                 priv_timer[lcore_id].updated = 1;
393         }
394
395         /* remove it from list */
396         if (prev_status.state == RTE_TIMER_PENDING) {
397                 timer_del(tim, prev_status, local_is_locked);
398                 __TIMER_STAT_ADD(pending, -1);
399         }
400
401         tim->period = period;
402         tim->expire = expire;
403         tim->f = fct;
404         tim->arg = arg;
405
406         __TIMER_STAT_ADD(pending, 1);
407         timer_add(tim, tim_lcore, local_is_locked);
408
409         /* update state: as we are in CONFIG state, only us can modify
410          * the state so we don't need to use cmpset() here */
411         rte_wmb();
412         status.state = RTE_TIMER_PENDING;
413         status.owner = (int16_t)tim_lcore;
414         tim->status.u32 = status.u32;
415
416         return 0;
417 }
418
419 /* Reset and start the timer associated with the timer handle tim */
420 int
421 rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
422                 enum rte_timer_type type, unsigned tim_lcore,
423                 rte_timer_cb_t fct, void *arg)
424 {
425         uint64_t cur_time = rte_get_timer_cycles();
426         uint64_t period;
427
428         if (unlikely((tim_lcore != (unsigned)LCORE_ID_ANY) &&
429                         !rte_lcore_is_enabled(tim_lcore)))
430                 return -1;
431
432         if (type == PERIODICAL)
433                 period = ticks;
434         else
435                 period = 0;
436
437         return __rte_timer_reset(tim,  cur_time + ticks, period, tim_lcore,
438                           fct, arg, 0);
439 }
440
441 /* loop until rte_timer_reset() succeed */
442 void
443 rte_timer_reset_sync(struct rte_timer *tim, uint64_t ticks,
444                      enum rte_timer_type type, unsigned tim_lcore,
445                      rte_timer_cb_t fct, void *arg)
446 {
447         while (rte_timer_reset(tim, ticks, type, tim_lcore,
448                                fct, arg) != 0)
449                 rte_pause();
450 }
451
452 /* Stop the timer associated with the timer handle tim */
453 int
454 rte_timer_stop(struct rte_timer *tim)
455 {
456         union rte_timer_status prev_status, status;
457         unsigned lcore_id = rte_lcore_id();
458         int ret;
459
460         /* wait that the timer is in correct status before update,
461          * and mark it as being configured */
462         ret = timer_set_config_state(tim, &prev_status);
463         if (ret < 0)
464                 return -1;
465
466         __TIMER_STAT_ADD(stop, 1);
467         if (prev_status.state == RTE_TIMER_RUNNING &&
468             lcore_id < RTE_MAX_LCORE) {
469                 priv_timer[lcore_id].updated = 1;
470         }
471
472         /* remove it from list */
473         if (prev_status.state == RTE_TIMER_PENDING) {
474                 timer_del(tim, prev_status, 0);
475                 __TIMER_STAT_ADD(pending, -1);
476         }
477
478         /* mark timer as stopped */
479         rte_wmb();
480         status.state = RTE_TIMER_STOP;
481         status.owner = RTE_TIMER_NO_OWNER;
482         tim->status.u32 = status.u32;
483
484         return 0;
485 }
486
487 /* loop until rte_timer_stop() succeed */
488 void
489 rte_timer_stop_sync(struct rte_timer *tim)
490 {
491         while (rte_timer_stop(tim) != 0)
492                 rte_pause();
493 }
494
495 /* Test the PENDING status of the timer handle tim */
496 int
497 rte_timer_pending(struct rte_timer *tim)
498 {
499         return tim->status.state == RTE_TIMER_PENDING;
500 }
501
502 /* must be called periodically, run all timer that expired */
503 void rte_timer_manage(void)
504 {
505         union rte_timer_status status;
506         struct rte_timer *tim, *next_tim;
507         unsigned lcore_id = rte_lcore_id();
508         struct rte_timer *prev[MAX_SKIPLIST_DEPTH + 1];
509         uint64_t cur_time;
510         int i, ret;
511
512         /* timer manager only runs on EAL thread with valid lcore_id */
513         assert(lcore_id < RTE_MAX_LCORE);
514
515         __TIMER_STAT_ADD(manage, 1);
516         /* optimize for the case where per-cpu list is empty */
517         if (priv_timer[lcore_id].pending_head.sl_next[0] == NULL)
518                 return;
519         cur_time = rte_get_timer_cycles();
520
521 #ifdef RTE_ARCH_X86_64
522         /* on 64-bit the value cached in the pending_head.expired will be updated
523          * atomically, so we can consult that for a quick check here outside the
524          * lock */
525         if (likely(priv_timer[lcore_id].pending_head.expire > cur_time))
526                 return;
527 #endif
528
529         /* browse ordered list, add expired timers in 'expired' list */
530         rte_spinlock_lock(&priv_timer[lcore_id].list_lock);
531
532         /* if nothing to do just unlock and return */
533         if (priv_timer[lcore_id].pending_head.sl_next[0] == NULL ||
534                         priv_timer[lcore_id].pending_head.sl_next[0]->expire > cur_time)
535                 goto done;
536
537         /* save start of list of expired timers */
538         tim = priv_timer[lcore_id].pending_head.sl_next[0];
539
540         /* break the existing list at current time point */
541         timer_get_prev_entries(cur_time, lcore_id, prev);
542         for (i = priv_timer[lcore_id].curr_skiplist_depth -1; i >= 0; i--) {
543                 priv_timer[lcore_id].pending_head.sl_next[i] = prev[i]->sl_next[i];
544                 if (prev[i]->sl_next[i] == NULL)
545                         priv_timer[lcore_id].curr_skiplist_depth--;
546                 prev[i] ->sl_next[i] = NULL;
547         }
548
549         /* now scan expired list and call callbacks */
550         for ( ; tim != NULL; tim = next_tim) {
551                 next_tim = tim->sl_next[0];
552
553                 ret = timer_set_running_state(tim);
554
555                 /* this timer was not pending, continue */
556                 if (ret < 0)
557                         continue;
558
559                 rte_spinlock_unlock(&priv_timer[lcore_id].list_lock);
560
561                 priv_timer[lcore_id].updated = 0;
562
563                 /* execute callback function with list unlocked */
564                 tim->f(tim, tim->arg);
565
566                 rte_spinlock_lock(&priv_timer[lcore_id].list_lock);
567                 __TIMER_STAT_ADD(pending, -1);
568                 /* the timer was stopped or reloaded by the callback
569                  * function, we have nothing to do here */
570                 if (priv_timer[lcore_id].updated == 1)
571                         continue;
572
573                 if (tim->period == 0) {
574                         /* remove from done list and mark timer as stopped */
575                         status.state = RTE_TIMER_STOP;
576                         status.owner = RTE_TIMER_NO_OWNER;
577                         rte_wmb();
578                         tim->status.u32 = status.u32;
579                 }
580                 else {
581                         /* keep it in list and mark timer as pending */
582                         status.state = RTE_TIMER_PENDING;
583                         __TIMER_STAT_ADD(pending, 1);
584                         status.owner = (int16_t)lcore_id;
585                         rte_wmb();
586                         tim->status.u32 = status.u32;
587                         __rte_timer_reset(tim, cur_time + tim->period,
588                                         tim->period, lcore_id, tim->f, tim->arg, 1);
589                 }
590         }
591
592         /* update the next to expire timer value */
593         priv_timer[lcore_id].pending_head.expire =
594                         (priv_timer[lcore_id].pending_head.sl_next[0] == NULL) ? 0 :
595                                         priv_timer[lcore_id].pending_head.sl_next[0]->expire;
596 done:
597         /* job finished, unlock the list lock */
598         rte_spinlock_unlock(&priv_timer[lcore_id].list_lock);
599 }
600
601 /* dump statistics about timers */
602 void rte_timer_dump_stats(FILE *f)
603 {
604 #ifdef RTE_LIBRTE_TIMER_DEBUG
605         struct rte_timer_debug_stats sum;
606         unsigned lcore_id;
607
608         memset(&sum, 0, sizeof(sum));
609         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
610                 sum.reset += priv_timer[lcore_id].stats.reset;
611                 sum.stop += priv_timer[lcore_id].stats.stop;
612                 sum.manage += priv_timer[lcore_id].stats.manage;
613                 sum.pending += priv_timer[lcore_id].stats.pending;
614         }
615         fprintf(f, "Timer statistics:\n");
616         fprintf(f, "  reset = %"PRIu64"\n", sum.reset);
617         fprintf(f, "  stop = %"PRIu64"\n", sum.stop);
618         fprintf(f, "  manage = %"PRIu64"\n", sum.manage);
619         fprintf(f, "  pending = %"PRIu64"\n", sum.pending);
620 #else
621         fprintf(f, "No timer statistics, RTE_LIBRTE_TIMER_DEBUG is disabled\n");
622 #endif
623 }