git: eb9766b37ca5 - stable/13 - time(3): Align fast clock times to avoid firing multiple timers.

From: Hans Petter Selasky <hselasky_at_FreeBSD.org>
Date: Sat, 12 Nov 2022 12:41:44 UTC
The branch stable/13 has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=eb9766b37ca5432ddab6590a2c96e9043843bfaa

commit eb9766b37ca5432ddab6590a2c96e9043843bfaa
Author:     Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2022-10-03 08:54:40 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2022-11-12 11:59:32 +0000

    time(3): Align fast clock times to avoid firing multiple timers.
    
    In non-periodic mode absolute timers fire at exactly the time given.
    When specifying a fast clock, align the firing time so that less
    timer interrupt events are needed.
    
    Reviewed by:    rrs @
    Sponsored by:   NVIDIA Networking
    Differential Revision:  https://reviews.freebsd.org/D36858
    
    (cherry picked from commit 0def80f1a5c8f7a02b92c823e5c71f9f746c3e6b)
---
 sys/kern/kern_umtx.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 8a0b140c2794..f0129e96a294 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -707,6 +707,7 @@ umtx_abs_timeout_getsbt(struct umtx_abs_timeout *timo, sbintime_t *sbt,
 {
 	struct bintime bt, bbt;
 	struct timespec tts;
+	sbintime_t rem;
 
 	switch (timo->clockid) {
 
@@ -739,14 +740,24 @@ umtx_abs_timeout_getsbt(struct umtx_abs_timeout *timo, sbintime_t *sbt,
 			return (0);
 		}
 		*sbt = bttosbt(bt);
+
+		/*
+		 * Check if the absolute time should be aligned to
+		 * avoid firing multiple timer events in non-periodic
+		 * timer mode.
+		 */
 		switch (timo->clockid) {
 		case CLOCK_REALTIME_FAST:
 		case CLOCK_MONOTONIC_FAST:
 		case CLOCK_UPTIME_FAST:
-			*sbt += tc_tick_sbt;
+			rem = *sbt % tc_tick_sbt;
+			if (__predict_true(rem != 0))
+				*sbt += tc_tick_sbt - rem;
 			break;
 		case CLOCK_SECOND:
-			*sbt += SBT_1S;
+			rem = *sbt % SBT_1S;
+			if (__predict_true(rem != 0))
+				*sbt += SBT_1S - rem;
 			break;
 		}
 		*flags = C_ABSOLUTE;