git: ce38acee8d0b - main - Add kern/sched_shim.c

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Thu, 29 Jan 2026 18:12:23 UTC
The branch main has been updated by kib:

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

commit ce38acee8d0bb35223b227479b9998c77b47f41b
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-01-22 04:19:52 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-01-29 18:11:55 +0000

    Add kern/sched_shim.c
    
    This is the infrastructure to allow scheduler implementation to be
    selected on boot, supported by ifuncs.
    
    The DEFINE_SHIM() macros and their usage provided by jrtc27@.
    
    Reviewed by:    olce
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D54831
---
 sys/conf/files        |  1 +
 sys/kern/sched_shim.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++
 sys/sys/sched.h       | 48 ++++++++++++++++++++++++++
 3 files changed, 143 insertions(+)

diff --git a/sys/conf/files b/sys/conf/files
index 97834f05431d..b330727b58c6 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -3922,6 +3922,7 @@ kern/linker_if.m		standard
 kern/p1003_1b.c			standard
 kern/posix4_mib.c		standard
 kern/sched_4bsd.c		optional sched_4bsd
+kern/sched_shim.c		standard
 kern/sched_ule.c		optional sched_ule
 kern/serdev_if.m		standard
 kern/stack_protector.c		standard \
diff --git a/sys/kern/sched_shim.c b/sys/kern/sched_shim.c
new file mode 100644
index 000000000000..079d7d73ec45
--- /dev/null
+++ b/sys/kern/sched_shim.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2026 The FreeBSD Foundation
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ */
+
+#include "opt_sched.h"
+
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/proc.h>
+#include <sys/runq.h>
+#include <sys/sched.h>
+#include <machine/ifunc.h>
+
+const struct sched_instance *active_sched;
+
+#ifndef __DO_NOT_HAVE_SYS_IFUNCS
+#define	__DEFINE_SHIM(__m, __r, __n, __p, __a)	\
+	DEFINE_IFUNC(, __r, __n, __p)		\
+	{					\
+		return (active_sched->__m);	\
+	}
+#else
+#define	__DEFINE_SHIM(__m, __r, __n, __p, __a)	\
+	__r					\
+	__n __p					\
+	{					\
+		return (active_sched->__m __a);	\
+	}
+#endif
+#define	DEFINE_SHIM0(__m, __r, __n)	\
+    __DEFINE_SHIM(__m, __r, __n, (void), ())
+#define	DEFINE_SHIM1(__m, __r, __n, __t1, __a1)	\
+    __DEFINE_SHIM(__m, __r, __n, (__t1 __a1), (__a1))
+#define	DEFINE_SHIM2(__m, __r, __n, __t1, __a1, __t2, __a2)	\
+    __DEFINE_SHIM(__m, __r, __n, (__t1 __a1, __t2 __a2), (__a1, __a2))
+
+DEFINE_SHIM0(load, int, sched_load)
+DEFINE_SHIM0(rr_interval, int, sched_rr_interval)
+DEFINE_SHIM0(runnable, bool, sched_runnable)
+DEFINE_SHIM2(exit, void, sched_exit, struct proc *, p,
+    struct thread *, childtd)
+DEFINE_SHIM2(fork, void, sched_fork, struct thread *, td,
+    struct thread *, childtd)
+DEFINE_SHIM1(fork_exit, void, sched_fork_exit, struct thread *, td)
+DEFINE_SHIM2(class, void, sched_class, struct thread *, td, int, class)
+DEFINE_SHIM2(nice, void, sched_nice, struct proc *, p, int, nice)
+DEFINE_SHIM0(ap_entry, void, sched_ap_entry)
+DEFINE_SHIM2(exit_thread, void, sched_exit_thread, struct thread *, td,
+    struct thread *, child)
+DEFINE_SHIM1(estcpu, u_int, sched_estcpu, struct thread *, td)
+DEFINE_SHIM2(fork_thread, void, sched_fork_thread, struct thread *, td,
+    struct thread *, child)
+DEFINE_SHIM2(ithread_prio, void, sched_ithread_prio, struct thread *, td,
+    u_char, prio)
+DEFINE_SHIM2(lend_prio, void, sched_lend_prio, struct thread *, td,
+    u_char, prio)
+DEFINE_SHIM2(lend_user_prio, void, sched_lend_user_prio, struct thread *, td,
+    u_char, pri)
+DEFINE_SHIM2(lend_user_prio_cond, void, sched_lend_user_prio_cond,
+    struct thread *, td, u_char, pri)
+DEFINE_SHIM1(pctcpu, fixpt_t, sched_pctcpu, struct thread *, td)
+DEFINE_SHIM2(prio, void, sched_prio, struct thread *, td, u_char, prio)
+DEFINE_SHIM2(sleep, void, sched_sleep, struct thread *, td, int, prio)
+DEFINE_SHIM2(sswitch, void, sched_switch, struct thread *, td, int, flags)
+DEFINE_SHIM1(throw, void, sched_throw, struct thread *, td)
+DEFINE_SHIM2(unlend_prio, void, sched_unlend_prio, struct thread *, td,
+    u_char, prio)
+DEFINE_SHIM2(user_prio, void, sched_user_prio, struct thread *, td,
+    u_char, prio)
+DEFINE_SHIM1(userret_slowpath, void, sched_userret_slowpath,
+    struct thread *, td)
+DEFINE_SHIM2(add, void, sched_add, struct thread *, td, int, flags)
+DEFINE_SHIM0(choose, struct thread *, sched_choose)
+DEFINE_SHIM2(clock, void, sched_clock, struct thread *, td, int, cnt)
+DEFINE_SHIM1(idletd, void, sched_idletd, void *, dummy)
+DEFINE_SHIM1(preempt, void, sched_preempt, struct thread *, td)
+DEFINE_SHIM1(relinquish, void, sched_relinquish, struct thread *, td)
+DEFINE_SHIM1(rem, void, sched_rem, struct thread *, td)
+DEFINE_SHIM2(wakeup, void, sched_wakeup, struct thread *, td, int, srqflags)
+DEFINE_SHIM2(bind, void, sched_bind, struct thread *, td, int, cpu)
+DEFINE_SHIM1(unbind, void, sched_unbind, struct thread *, td)
+DEFINE_SHIM1(is_bound, int, sched_is_bound, struct thread *, td)
+DEFINE_SHIM1(affinity, void, sched_affinity, struct thread *, td)
+DEFINE_SHIM0(sizeof_proc, int, sched_sizeof_proc)
+DEFINE_SHIM0(sizeof_thread, int, sched_sizeof_thread)
+DEFINE_SHIM1(tdname, char *, sched_tdname, struct thread *, td)
+DEFINE_SHIM1(clear_tdname, void, sched_clear_tdname, struct thread *, td)
+DEFINE_SHIM0(init_ap, void, schedinit_ap)
diff --git a/sys/sys/sched.h b/sys/sys/sched.h
index 8f383840192f..b733d4d07e34 100644
--- a/sys/sys/sched.h
+++ b/sys/sys/sched.h
@@ -239,6 +239,54 @@ void schedinit(void);
  * Fixup scheduler state for secondary APs
  */
 void schedinit_ap(void);
+
+struct sched_instance {
+	int	(*load)(void);
+	int	(*rr_interval)(void);
+	bool	(*runnable)(void);
+	void	(*exit)(struct proc *p, struct thread *childtd);
+	void	(*fork)(struct thread *td, struct thread *childtd);
+	void	(*fork_exit)(struct thread *td);
+	void	(*class)(struct thread *td, int class);
+	void	(*nice)(struct proc *p, int nice);
+	void	(*ap_entry)(void);
+	void	(*exit_thread)(struct thread *td, struct thread *child);
+	u_int	(*estcpu)(struct thread *td);
+	void	(*fork_thread)(struct thread *td, struct thread *child);
+	void	(*ithread_prio)(struct thread *td, u_char prio);
+	void	(*lend_prio)(struct thread *td, u_char prio);
+	void	(*lend_user_prio)(struct thread *td, u_char pri);
+	void	(*lend_user_prio_cond)(struct thread *td, u_char pri);
+	fixpt_t	(*pctcpu)(struct thread *td);
+	void	(*prio)(struct thread *td, u_char prio);
+	void	(*sleep)(struct thread *td, int prio);
+	void	(*sswitch)(struct thread *td, int flags);
+	void	(*throw)(struct thread *td);
+	void	(*unlend_prio)(struct thread *td, u_char prio);
+	void	(*user_prio)(struct thread *td, u_char prio);
+	void	(*userret_slowpath)(struct thread *td);
+	void	(*add)(struct thread *td, int flags);
+	struct thread *(*choose)(void);
+	void	(*clock)(struct thread *td, int cnt);
+	void	(*idletd)(void *);
+	void	(*preempt)(struct thread *td);
+	void	(*relinquish)(struct thread *td);
+	void	(*rem)(struct thread *td);
+	void	(*wakeup)(struct thread *td, int srqflags);
+	void	(*bind)(struct thread *td, int cpu);
+	void	(*unbind)(struct thread *td);
+	int	(*is_bound)(struct thread *td);
+	void	(*affinity)(struct thread *td);
+	int	(*sizeof_proc)(void);
+	int	(*sizeof_thread)(void);
+	char	*(*tdname)(struct thread *td);
+	void	(*clear_tdname)(struct thread *td);
+	void	(*init)(void);
+	void	(*init_ap)(void);
+};
+
+extern const struct sched_instance *active_sched;
+
 #endif /* _KERNEL */
 
 /* POSIX 1003.1b Process Scheduling */