diff --git a/sys/kern/usched_bsd4.c b/sys/kern/usched_bsd4.c --- a/sys/kern/usched_bsd4.c +++ b/sys/kern/usched_bsd4.c @@ -1480,7 +1480,8 @@ * Limit the number of checks/queue to a configurable value to * minimize the contention (we are in a locked region */ - while (checks < usched_bsd4_queue_checks) { + while (checks < (usched_bsd4_queue_checks > 0 ? + usched_bsd4_queue_checks : 1)) { if (CPUMASK_TESTMASK(lp->lwp_cpumask, cpumask) == 0 || (CPUMASK_TESTMASK(siblings, lp->lwp_thread->td_gd->gd_cpumask) == 0 && @@ -1881,6 +1882,23 @@ return (0); } +/* sysctl queue_checks parameter — reject <= 0 to avoid NULL-deref panic */ +static int +sysctl_usched_bsd4_queue_checks(SYSCTL_HANDLER_ARGS) +{ + int error, new_val; + + new_val = usched_bsd4_queue_checks; + + error = sysctl_handle_int(oidp, &new_val, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + if (new_val < 1) + return (EINVAL); + usched_bsd4_queue_checks = new_val; + return (0); +} + /* * Setup our scheduler helpers. Note that curprocmask bit 0 has already * been cleared by rqinit() and we should not mess with it further. @@ -2040,10 +2058,12 @@ &usched_bsd4_upri_affinity, 1, "Number of PPQs in user priority check"); - SYSCTL_ADD_INT(&usched_bsd4_sysctl_ctx, + SYSCTL_ADD_PROC(&usched_bsd4_sysctl_ctx, SYSCTL_CHILDREN(usched_bsd4_sysctl_tree), - OID_AUTO, "queue_checks", CTLFLAG_RW, - &usched_bsd4_queue_checks, 5, + OID_AUTO, "queue_checks", + CTLTYPE_INT | CTLFLAG_RW, + NULL, sizeof usched_bsd4_queue_checks, + sysctl_usched_bsd4_queue_checks, "I", "LWPs to check from a queue before giving up"); SYSCTL_ADD_PROC(&usched_bsd4_sysctl_ctx,