git: 11d26e3c7e8e - main - callout: provide callout_init_lock()

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Fri, 18 Sep 2026 21:31:53 UTC
The branch main has been updated by glebius:

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

commit 11d26e3c7e8e6261190c4475520f5330619d974a
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2026-09-18 21:15:12 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2026-09-18 21:17:02 +0000

    callout: provide callout_init_lock()
    
    This is type agnostic locked callout initializer.  The callout_init_mtx()
    and etc remain for compatibility.
    
    Reviewed by:            kib, markj
    Differential Revision:  https://reviews.freebsd.org/D59456
---
 share/man/man9/callout.9 | 51 +++++++++++++++++++++++-------------------------
 sys/sys/callout.h        | 15 ++++++++------
 2 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/share/man/man9/callout.9 b/share/man/man9/callout.9
index aef4567764c2..d90d896a81e1 100644
--- a/share/man/man9/callout.9
+++ b/share/man/man9/callout.9
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 4, 2026
+.Dd September 18, 2026
 .Dt CALLOUT 9
 .Os
 .Sh NAME
@@ -35,6 +35,7 @@
 .Nm callout_deactivate ,
 .Nm callout_drain ,
 .Nm callout_init ,
+.Nm callout_init_lock ,
 .Nm callout_init_mtx ,
 .Nm callout_init_rm ,
 .Nm callout_init_rw ,
@@ -69,6 +70,8 @@ typedef void callout_func_t (void *);
 .Ft void
 .Fn callout_init "struct callout *c" "int mpsafe"
 .Ft void
+.Fn callout_init_lock "struct callout *c" "lock" "int flags"
+.Ft void
 .Fn callout_init_mtx "struct callout *c" "struct mtx *mtx" "int flags"
 .Ft void
 .Fn callout_init_rm "struct callout *c" "struct rmlock *rm" "int flags"
@@ -192,11 +195,8 @@ perform blocking allocation requests,
 or invoke any other action that might sleep.
 .Pp
 Each callout structure must be initialized by
-.Fn callout_init ,
-.Fn callout_init_mtx ,
-.Fn callout_init_rm ,
-or
-.Fn callout_init_rw
+.Fn callout_init or
+.Fn callout_init_lock
 before it is passed to any of the other callout functions.
 The
 .Fn callout_init
@@ -212,19 +212,21 @@ and the Giant lock will be acquired before calling the callout function
 and released when the callout function returns.
 .Pp
 The
+.Fn callout_init_lock
+macro initializes a callout structure in
+.Fa c
+that is associated with a specific lock.
+The lock argument can be a pointer to either
+.Fa struct mtx ,
+.Fa struct rwlock
+or
+.Fa struct rmlock .
+Macros
 .Fn callout_init_mtx ,
 .Fn callout_init_rm ,
 and
 .Fn callout_init_rw
-functions initialize a callout structure in
-.Fa c
-that is associated with a specific lock.
-The lock is specified by the
-.Fa mtx ,
-.Fa rm ,
-or
-.Fa rw
-parameter.
+are provided for compatibility.
 The associated lock must be held while stopping or rescheduling the
 callout.
 The callout subsystem acquires the associated lock before calling the
@@ -242,8 +244,7 @@ one initialized with the
 .Dv RM_SLEEPABLE
 flag
 .Pc
-may not be used with
-.Fn callout_init_rm .
+may not be used.
 Similarly, other sleepable lock types such as
 .Xr sx 9
 and
@@ -254,10 +255,8 @@ the callout subsystem.
 These
 .Fa flags
 may be specified for
-.Fn callout_init_mtx ,
-.Fn callout_init_rm ,
-or
-.Fn callout_init_rw :
+.Fn callout_init_lock
+and associated compatibility macros.
 .Bl -tag -width ".Dv CALLOUT_RETURNUNLOCKED"
 .It Dv CALLOUT_RETURNUNLOCKED
 The callout function will release the associated lock itself,
@@ -265,8 +264,8 @@ so the callout subsystem should not attempt to unlock it
 after the callout function returns.
 .It Dv CALLOUT_SHAREDLOCK
 The lock is only acquired in read mode when running the callout handler.
-This flag is ignored by
-.Fn callout_init_mtx .
+This flag is ignored if the lock is of type
+.Xr mutex 9 .
 .El
 .Pp
 The function
@@ -585,10 +584,8 @@ The first approach is preferred as it is the simplest:
 .It
 Callouts can be associated with a specific lock when they are initialized
 by
-.Fn callout_init_mtx ,
-.Fn callout_init_rm ,
-or
-.Fn callout_init_rw .
+.Fn callout_init_lock
+or compatibility macros.
 When a callout is associated with a lock,
 the callout subsystem acquires the lock before the callout function is
 invoked.
diff --git a/sys/sys/callout.h b/sys/sys/callout.h
index c3350b324296..d756b9fdf5e3 100644
--- a/sys/sys/callout.h
+++ b/sys/sys/callout.h
@@ -63,6 +63,7 @@
 #define	CS_DRAIN		0x0001 /* callout_drain(), wait allowed */
 
 #ifdef _KERNEL
+#include <sys/lock.h>
 /* 
  * Note the flags field is actually *two* fields. The c_flags
  * field is the one that caller operations that may, or may not have
@@ -84,12 +85,14 @@
 #define	callout_drain(c)	_callout_stop_safe(c, CS_DRAIN)
 void	callout_init(struct callout *, int);
 void	_callout_init_lock(struct callout *, struct lock_object *, int);
-#define	callout_init_mtx(c, mtx, flags)					\
-	_callout_init_lock((c), &(mtx)->lock_object, (flags))
-#define	callout_init_rm(c, rm, flags)					\
-	_callout_init_lock((c), &(rm)->lock_object, (flags))
-#define	callout_init_rw(c, rw, flags)					\
-	_callout_init_lock((c), &(rw)->lock_object, (flags))
+#define	callout_init_lock(c, lk, f)		_Generic((lk),		\
+    struct mtx *: _callout_init_lock((c), lk2lo(lk), (f)),		\
+    struct mtx_padalign *: _callout_init_lock((c), lk2lo(lk), (f)),	\
+    struct rmlock *: _callout_init_lock((c), lk2lo(lk), (f)),		\
+    struct rwlock *: _callout_init_lock((c), lk2lo(lk), (f)))
+#define	callout_init_mtx(c, mtx, flags)	callout_init_lock((c), (mtx), (flags))
+#define	callout_init_rm(c, rm, flags)	callout_init_lock((c), (rm), (flags))
+#define	callout_init_rw(c, rw, flags)	callout_init_lock((c), (rw), (flags))
 #define	callout_pending(c)	((c)->c_iflags & CALLOUT_PENDING)
 int	callout_reset_sbt_on(struct callout *, sbintime_t, sbintime_t,
 	    void (*)(void *), void *, int, int);