git: 477d2ea79252 - main - sched_ule: fix invalid tdq_slice() and sched_slice_min

From: Minsoo Choo <mchoo_at_FreeBSD.org>
Date: Fri, 18 Sep 2026 14:14:59 UTC
The branch main has been updated by mchoo:

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

commit 477d2ea79252054596c73fa5f485bd224c028fd9
Author:     Minsoo Choo <mchoo@FreeBSD.org>
AuthorDate: 2026-08-24 23:35:27 +0000
Commit:     Minsoo Choo <mchoo@FreeBSD.org>
CommitDate: 2026-09-18 14:14:14 +0000

    sched_ule: fix invalid tdq_slice() and sched_slice_min
    
    sched_slice_min should always to be greater than zero. When modifying
    sched_slice through sysctl, if the new value is less than
    SCHED_SLICE_MIN_DIVISOR, sched_slice_min is computed to zero. Add
    imax(1, ...) to prevent this.
    
    tdq_slice() should not return a value less than sched_slice_min since
    that will cause integer underflow of ts2->ts_slice in
    sched_ule_fork_thread. SCHED_SLICE_MIN_DIVISOR is currently set to 6 so
    when load is 5 and sched_slice is 4, the two if conditions in
    tdq_slice() will pass and the function will return zero. Thus use imax()
    so tdq_slice returns sched_slice_min at minimum.
    
    Reviewed by:    olce
    Approved by:    olce (mentor)
    MFC after:      2 weeks
    Sponsored by:   FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D59408
---
 sys/kern/sched_ule.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index dc84b18e5ebf..9cd4d8e448f8 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -675,11 +675,9 @@ tdq_slice(struct tdq *tdq)
 	 * cannot be higher priority load in the system.
 	 */
 	load = tdq->tdq_sysload - 1;
-	if (load >= SCHED_SLICE_MIN_DIVISOR)
-		return (sched_slice_min);
 	if (load <= 1)
 		return (sched_slice);
-	return (sched_slice / load);
+	return (imax(sched_slice_min, sched_slice / load));
 }
 
 /*
@@ -3478,7 +3476,7 @@ sysctl_kern_quantum(SYSCTL_HANDLER_ARGS)
 	if (new_val <= 0)
 		return (EINVAL);
 	sched_slice = imax(1, (new_val + period / 2) / period);
-	sched_slice_min = sched_slice / SCHED_SLICE_MIN_DIVISOR;
+	sched_slice_min = imax(1, sched_slice / SCHED_SLICE_MIN_DIVISOR);
 	hogticks = imax(1, (2 * hz * sched_slice + realstathz / 2) /
 	    realstathz);
 	return (0);