aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2017-05-30 17:15:50 -0400
committerThomas Gleixner <tglx@linutronix.de>2017-06-04 09:40:27 -0400
commit91d57bae08689199c8acc77a8b3b41150cafab1c (patch)
tree31db8b4a4554fcc51fbdb947a9ad30ce18071818
parent63841b2a6969501de183efafc14d20175e402804 (diff)
posix-timers: Make use of forward/remaining callbacks
Replace the hrtimer calls by calls to the new forward/remaining kclock callbacks and move the hrtimer specific implementation into the corresponding callback functions. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: John Stultz <john.stultz@linaro.org> Link: http://lkml.kernel.org/r/20170530211657.121437232@linutronix.de
-rw-r--r--kernel/time/posix-timers.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 795215bba73d..48f6c37ae5df 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -607,6 +607,20 @@ static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags)
607 return NULL; 607 return NULL;
608} 608}
609 609
610static ktime_t common_hrtimer_remaining(struct k_itimer *timr, ktime_t now)
611{
612 struct hrtimer *timer = &timr->it.real.timer;
613
614 return __hrtimer_expires_remaining_adjusted(timer, now);
615}
616
617static int common_hrtimer_forward(struct k_itimer *timr, ktime_t now)
618{
619 struct hrtimer *timer = &timr->it.real.timer;
620
621 return (int)hrtimer_forward(timer, now, timr->it_interval);
622}
623
610/* 624/*
611 * Get the time remaining on a POSIX.1b interval timer. This function 625 * Get the time remaining on a POSIX.1b interval timer. This function
612 * is ALWAYS called with spin_lock_irq on the timer, thus it must not 626 * is ALWAYS called with spin_lock_irq on the timer, thus it must not
@@ -626,42 +640,54 @@ static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags)
626static void 640static void
627common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting) 641common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
628{ 642{
643 const struct k_clock *kc = timr->kclock;
629 ktime_t now, remaining, iv; 644 ktime_t now, remaining, iv;
630 struct hrtimer *timer = &timr->it.real.timer; 645 struct timespec64 ts64;
646 bool sig_none;
631 647
632 memset(cur_setting, 0, sizeof(*cur_setting)); 648 memset(cur_setting, 0, sizeof(*cur_setting));
633 649
650 sig_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE;
634 iv = timr->it_interval; 651 iv = timr->it_interval;
635 652
636 /* interval timer ? */ 653 /* interval timer ? */
637 if (iv) 654 if (iv) {
638 cur_setting->it_interval = ktime_to_timespec64(iv); 655 cur_setting->it_interval = ktime_to_timespec64(iv);
639 else if (!hrtimer_active(timer) && 656 } else if (!timr->it_active) {
640 (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) 657 /*
641 return; 658 * SIGEV_NONE oneshot timers are never queued. Check them
659 * below.
660 */
661 if (!sig_none)
662 return;
663 }
642 664
643 now = timer->base->get_time(); 665 /*
666 * The timespec64 based conversion is suboptimal, but it's not
667 * worth to implement yet another callback.
668 */
669 kc->clock_get(timr->it_clock, &ts64);
670 now = timespec64_to_ktime(ts64);
644 671
645 /* 672 /*
646 * When a requeue is pending or this is a SIGEV_NONE 673 * When a requeue is pending or this is a SIGEV_NONE timer move the
647 * timer move the expiry time forward by intervals, so 674 * expiry time forward by intervals, so expiry is > now.
648 * expiry is > now.
649 */ 675 */
650 if (iv && (timr->it_requeue_pending & REQUEUE_PENDING || 676 if (iv && (timr->it_requeue_pending & REQUEUE_PENDING || sig_none))
651 (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) 677 timr->it_overrun += kc->timer_forward(timr, now);
652 timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
653 678
654 remaining = __hrtimer_expires_remaining_adjusted(timer, now); 679 remaining = kc->timer_remaining(timr, now);
655 /* Return 0 only, when the timer is expired and not pending */ 680 /* Return 0 only, when the timer is expired and not pending */
656 if (remaining <= 0) { 681 if (remaining <= 0) {
657 /* 682 /*
658 * A single shot SIGEV_NONE timer must return 0, when 683 * A single shot SIGEV_NONE timer must return 0, when
659 * it is expired ! 684 * it is expired !
660 */ 685 */
661 if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) 686 if (!sig_none)
662 cur_setting->it_value.tv_nsec = 1; 687 cur_setting->it_value.tv_nsec = 1;
663 } else 688 } else {
664 cur_setting->it_value = ktime_to_timespec64(remaining); 689 cur_setting->it_value = ktime_to_timespec64(remaining);
690 }
665} 691}
666 692
667/* Get the time remaining on a POSIX.1b interval timer. */ 693/* Get the time remaining on a POSIX.1b interval timer. */
@@ -1049,6 +1075,8 @@ static const struct k_clock clock_realtime = {
1049 .timer_get = common_timer_get, 1075 .timer_get = common_timer_get,
1050 .timer_del = common_timer_del, 1076 .timer_del = common_timer_del,
1051 .timer_rearm = common_hrtimer_rearm, 1077 .timer_rearm = common_hrtimer_rearm,
1078 .timer_forward = common_hrtimer_forward,
1079 .timer_remaining= common_hrtimer_remaining,
1052}; 1080};
1053 1081
1054static const struct k_clock clock_monotonic = { 1082static const struct k_clock clock_monotonic = {
@@ -1061,6 +1089,8 @@ static const struct k_clock clock_monotonic = {
1061 .timer_get = common_timer_get, 1089 .timer_get = common_timer_get,
1062 .timer_del = common_timer_del, 1090 .timer_del = common_timer_del,
1063 .timer_rearm = common_hrtimer_rearm, 1091 .timer_rearm = common_hrtimer_rearm,
1092 .timer_forward = common_hrtimer_forward,
1093 .timer_remaining= common_hrtimer_remaining,
1064}; 1094};
1065 1095
1066static const struct k_clock clock_monotonic_raw = { 1096static const struct k_clock clock_monotonic_raw = {
@@ -1088,6 +1118,8 @@ static const struct k_clock clock_tai = {
1088 .timer_get = common_timer_get, 1118 .timer_get = common_timer_get,
1089 .timer_del = common_timer_del, 1119 .timer_del = common_timer_del,
1090 .timer_rearm = common_hrtimer_rearm, 1120 .timer_rearm = common_hrtimer_rearm,
1121 .timer_forward = common_hrtimer_forward,
1122 .timer_remaining= common_hrtimer_remaining,
1091}; 1123};
1092 1124
1093static const struct k_clock clock_boottime = { 1125static const struct k_clock clock_boottime = {
@@ -1100,6 +1132,8 @@ static const struct k_clock clock_boottime = {
1100 .timer_get = common_timer_get, 1132 .timer_get = common_timer_get,
1101 .timer_del = common_timer_del, 1133 .timer_del = common_timer_del,
1102 .timer_rearm = common_hrtimer_rearm, 1134 .timer_rearm = common_hrtimer_rearm,
1135 .timer_forward = common_hrtimer_forward,
1136 .timer_remaining= common_hrtimer_remaining,
1103}; 1137};
1104 1138
1105static const struct k_clock * const posix_clocks[] = { 1139static const struct k_clock * const posix_clocks[] = {