Skip to content

Commit a86e928

Browse files
committed
posix-timers: Document common_clock_get() correctly
Replace another confusing and inaccurate set of comments. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Frederic Weisbecker <frederic@kernel.org> Link: https://lore.kernel.org/r/20230425183313.409169321@linutronix.de
1 parent 01679b5 commit a86e928

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

kernel/time/posix-timers.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -660,20 +660,16 @@ static s64 common_hrtimer_forward(struct k_itimer *timr, ktime_t now)
660660
}
661661

662662
/*
663-
* Get the time remaining on a POSIX.1b interval timer. This function
664-
* is ALWAYS called with spin_lock_irq on the timer, thus it must not
665-
* mess with irq.
663+
* Get the time remaining on a POSIX.1b interval timer.
666664
*
667-
* We have a couple of messes to clean up here. First there is the case
668-
* of a timer that has a requeue pending. These timers should appear to
669-
* be in the timer list with an expiry as if we were to requeue them
670-
* now.
665+
* Two issues to handle here:
671666
*
672-
* The second issue is the SIGEV_NONE timer which may be active but is
673-
* not really ever put in the timer list (to save system resources).
674-
* This timer may be expired, and if so, we will do it here. Otherwise
675-
* it is the same as a requeue pending timer WRT to what we should
676-
* report.
667+
* 1) The timer has a requeue pending. The return value must appear as
668+
* if the timer has been requeued right now.
669+
*
670+
* 2) The timer is a SIGEV_NONE timer. These timers are never enqueued
671+
* into the hrtimer queue and therefore never expired. Emulate expiry
672+
* here taking #1 into account.
677673
*/
678674
void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
679675
{
@@ -689,8 +685,12 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
689685
cur_setting->it_interval = ktime_to_timespec64(iv);
690686
} else if (!timr->it_active) {
691687
/*
692-
* SIGEV_NONE oneshot timers are never queued. Check them
693-
* below.
688+
* SIGEV_NONE oneshot timers are never queued and therefore
689+
* timr->it_active is always false. The check below
690+
* vs. remaining time will handle this case.
691+
*
692+
* For all other timers there is nothing to update here, so
693+
* return.
694694
*/
695695
if (!sig_none)
696696
return;
@@ -699,18 +699,29 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
699699
now = kc->clock_get_ktime(timr->it_clock);
700700

701701
/*
702-
* When a requeue is pending or this is a SIGEV_NONE timer move the
703-
* expiry time forward by intervals, so expiry is > now.
702+
* If this is an interval timer and either has requeue pending or
703+
* is a SIGEV_NONE timer move the expiry time forward by intervals,
704+
* so expiry is > now.
704705
*/
705706
if (iv && (timr->it_requeue_pending & REQUEUE_PENDING || sig_none))
706707
timr->it_overrun += kc->timer_forward(timr, now);
707708

708709
remaining = kc->timer_remaining(timr, now);
709-
/* Return 0 only, when the timer is expired and not pending */
710+
/*
711+
* As @now is retrieved before a possible timer_forward() and
712+
* cannot be reevaluated by the compiler @remaining is based on the
713+
* same @now value. Therefore @remaining is consistent vs. @now.
714+
*
715+
* Consequently all interval timers, i.e. @iv > 0, cannot have a
716+
* remaining time <= 0 because timer_forward() guarantees to move
717+
* them forward so that the next timer expiry is > @now.
718+
*/
710719
if (remaining <= 0) {
711720
/*
712-
* A single shot SIGEV_NONE timer must return 0, when
713-
* it is expired !
721+
* A single shot SIGEV_NONE timer must return 0, when it is
722+
* expired! Timers which have a real signal delivery mode
723+
* must return a remaining time greater than 0 because the
724+
* signal has not yet been delivered.
714725
*/
715726
if (!sig_none)
716727
cur_setting->it_value.tv_nsec = 1;
@@ -719,7 +730,6 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
719730
}
720731
}
721732

722-
/* Get the time remaining on a POSIX.1b interval timer. */
723733
static int do_timer_gettime(timer_t timer_id, struct itimerspec64 *setting)
724734
{
725735
struct k_itimer *timr;

0 commit comments

Comments
 (0)