Module Name:    src
Committed By:   pgoyette
Date:           Thu Dec 12 22:55:20 UTC 2019

Modified Files:
        src/sys/kern: files.kern init_main.c kern_module.c
        src/sys/rump/librump/rumpkern: Makefile.rumpkern
        src/sys/sys: module_hook.h param.h
Added Files:
        src/sys/kern: kern_module_hook.c

Log Message:
Eliminate per-hook duplication of common code as suggested by
(and with major contributions from) riastradh@

Welcome to 9.99.23


To generate a diff of this commit:
cvs rdiff -u -r1.38 -r1.39 src/sys/kern/files.kern
cvs rdiff -u -r1.508 -r1.509 src/sys/kern/init_main.c
cvs rdiff -u -r1.140 -r1.141 src/sys/kern/kern_module.c
cvs rdiff -u -r0 -r1.1 src/sys/kern/kern_module_hook.c
cvs rdiff -u -r1.177 -r1.178 src/sys/rump/librump/rumpkern/Makefile.rumpkern
cvs rdiff -u -r1.5 -r1.6 src/sys/sys/module_hook.h
cvs rdiff -u -r1.623 -r1.624 src/sys/sys/param.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/files.kern
diff -u src/sys/kern/files.kern:1.38 src/sys/kern/files.kern:1.39
--- src/sys/kern/files.kern:1.38	Wed Nov 20 19:37:53 2019
+++ src/sys/kern/files.kern	Thu Dec 12 22:55:20 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: files.kern,v 1.38 2019/11/20 19:37:53 pgoyette Exp $
+#	$NetBSD: files.kern,v 1.39 2019/12/12 22:55:20 pgoyette Exp $
 
 #
 # kernel sources
@@ -54,6 +54,7 @@ file	kern/kern_lock.c		kern
 file	kern/kern_lwp.c			kern
 file	kern/kern_malloc.c		kern
 file	kern/kern_module.c		kern
+file	kern/kern_module_hook.c		kern
 file	kern/kern_module_vfs.c		kern
 file	kern/kern_mutex.c		kern
 file	kern/kern_mutex_obj.c		kern

Index: src/sys/kern/init_main.c
diff -u src/sys/kern/init_main.c:1.508 src/sys/kern/init_main.c:1.509
--- src/sys/kern/init_main.c:1.508	Mon Dec  2 23:22:43 2019
+++ src/sys/kern/init_main.c	Thu Dec 12 22:55:20 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: init_main.c,v 1.508 2019/12/02 23:22:43 ad Exp $	*/
+/*	$NetBSD: init_main.c,v 1.509 2019/12/12 22:55:20 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009, 2019 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.508 2019/12/02 23:22:43 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.509 2019/12/12 22:55:20 pgoyette Exp $");
 
 #include "opt_ddb.h"
 #include "opt_inet.h"
@@ -170,6 +170,7 @@ extern void *_binary_splash_image_end;
 #include <sys/disk.h>
 #include <sys/msgbuf.h>
 #include <sys/module.h>
+#include <sys/module_hook.h>
 #include <sys/event.h>
 #include <sys/lockf.h>
 #include <sys/once.h>
@@ -354,6 +355,7 @@ main(void)
 
 	/* Start module system. */
 	module_init();
+	module_hook_init();
 
 	/*
 	 * Initialize the kernel authorization subsystem and start the

Index: src/sys/kern/kern_module.c
diff -u src/sys/kern/kern_module.c:1.140 src/sys/kern/kern_module.c:1.141
--- src/sys/kern/kern_module.c:1.140	Thu Dec 12 16:36:25 2019
+++ src/sys/kern/kern_module.c	Thu Dec 12 22:55:20 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_module.c,v 1.140 2019/12/12 16:36:25 pgoyette Exp $	*/
+/*	$NetBSD: kern_module.c,v 1.141 2019/12/12 22:55:20 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.140 2019/12/12 16:36:25 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.141 2019/12/12 22:55:20 pgoyette Exp $");
 
 #define _MODULE_INTERNAL
 
@@ -128,12 +128,6 @@ static int	sysctl_module_autotime(SYSCTL
 static void	module_callback_load(struct module *);
 static void	module_callback_unload(struct module *);
 
-/* Locking/synchronization stuff for module hooks */
-
-kmutex_t	module_hook_mtx;
-kcondvar_t	module_hook_cv;
-pserialize_t	module_hook_psz;
-
 #define MODULE_CLASS_MATCH(mi, modclass) \
 	((modclass) == MODULE_CLASS_ANY || (modclass) == (mi)->mi_class)
 
@@ -451,10 +445,6 @@ module_init(void)
 	module_netbsd = module_newmodule(MODULE_SOURCE_KERNEL);
 	module_netbsd->mod_refcnt = 1;
 	module_netbsd->mod_info = &module_netbsd_modinfo;
-
-	mutex_init(&module_hook_mtx, MUTEX_DEFAULT, IPL_NONE);
-	cv_init(&module_hook_cv, "mod_hook");
-	module_hook_psz = pserialize_create();
 }
 
 /*

Index: src/sys/rump/librump/rumpkern/Makefile.rumpkern
diff -u src/sys/rump/librump/rumpkern/Makefile.rumpkern:1.177 src/sys/rump/librump/rumpkern/Makefile.rumpkern:1.178
--- src/sys/rump/librump/rumpkern/Makefile.rumpkern:1.177	Sun Oct 13 07:28:14 2019
+++ src/sys/rump/librump/rumpkern/Makefile.rumpkern	Thu Dec 12 22:55:20 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.rumpkern,v 1.177 2019/10/13 07:28:14 mrg Exp $
+#	$NetBSD: Makefile.rumpkern,v 1.178 2019/12/12 22:55:20 pgoyette Exp $
 #
 
 IOCONFDIR:=	${.PARSEDIR}
@@ -75,6 +75,7 @@ SRCS+=	init_sysctl_base.c	\
 	kern_ksyms.c		\
 	kern_malloc.c		\
 	kern_module.c		\
+	kern_module_hook.c	\
 	kern_mutex_obj.c	\
 	kern_ntptime.c		\
 	kern_proc.c		\

Index: src/sys/sys/module_hook.h
diff -u src/sys/sys/module_hook.h:1.5 src/sys/sys/module_hook.h:1.6
--- src/sys/sys/module_hook.h:1.5	Thu Dec 12 02:15:43 2019
+++ src/sys/sys/module_hook.h	Thu Dec 12 22:55:20 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: module_hook.h,v 1.5 2019/12/12 02:15:43 pgoyette Exp $	*/
+/* $NetBSD: module_hook.h,v 1.6 2019/12/12 22:55:20 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -33,11 +33,14 @@
 #define _SYS_MODULE_HOOK_H
 
 #include <sys/param.h>	/* for COHERENCY_UNIT, for __cacheline_aligned */
-#include <sys/mutex.h>
 #include <sys/localcount.h>
-#include <sys/condvar.h>
-#include <sys/pserialize.h>
-#include <sys/atomic.h>
+#include <sys/stdbool.h>
+
+void module_hook_init(void);
+void module_hook_set(bool *, struct localcount *);
+void module_hook_unset(bool *, struct localcount *);
+bool module_hook_tryenter(bool *, struct localcount *);
+void module_hook_exit(struct localcount *); 
 
 /*
  * Macros for creating MP-safe vectored function calls, where
@@ -48,14 +51,10 @@
 #define MODULE_HOOK(hook, type, args)				\
 extern struct hook ## _t {					\
 	struct localcount	lc;				\
-        bool			hooked;				\
 	type			(*f)args;			\
+	bool			hooked;				\
 } hook __cacheline_aligned;
 
-extern kmutex_t		module_hook_mtx;
-extern kcondvar_t	module_hook_cv;
-extern pserialize_t	module_hook_psz;
-
 /*
  * We use pserialize_perform() to issue a memory barrier on the current
  * CPU and on all other CPUs so that all prior memory operations on the
@@ -69,85 +68,32 @@ extern pserialize_t	module_hook_psz;
 
 #define MODULE_HOOK_SET(hook, func)				\
 do {								\
-								\
-	KASSERT(kernconfig_is_held());				\
-	KASSERT(!hook.hooked);					\
-								\
-	localcount_init(&hook.lc);				\
-	hook.f = func;						\
-								\
-	/* Make sure it's initialized before anyone uses it */	\
-	pserialize_perform(module_hook_psz);			\
-								\
-	/* Let them use it */					\
-	atomic_store_relaxed(&hook.hooked, true);		\
+	(hook).f = func;					\
+	module_hook_set(&(hook).hooked, &(hook).lc);		\
 } while /* CONSTCOND */ (0)
 
 #define MODULE_HOOK_UNSET(hook)					\
 do {								\
-								\
-	KASSERT(kernconfig_is_held());				\
-	KASSERT(hook.hooked);					\
-	KASSERT(hook.f);					\
-								\
-	/* Grab the mutex */					\
-	mutex_enter(&module_hook_mtx);				\
-								\
-	/* Prevent new localcount_acquire calls.  */		\
-	atomic_store_relaxed(&hook.hooked, false);		\
-								\
-	/*							\
-	 * Wait for localcount_acquire calls already under way	\
-	 * to finish.						\
-	 */							\
-	pserialize_perform(module_hook_psz);			\
-								\
-	/* Wait for existing localcount references to drain.  */\
-	localcount_drain(&hook.lc, &module_hook_cv,		\
-	     &module_hook_mtx);					\
-								\
-	/* Release the mutex and clean up all resources */	\
-	mutex_exit(&module_hook_mtx);				\
-	localcount_fini(&hook.lc);				\
+	KASSERT((hook).f);					\
+	module_hook_unset(&(hook).hooked, &(hook).lc);		\
+	(hook).f = NULL;	/* paranoia */			\
 } while /* CONSTCOND */ (0)
 
 #define MODULE_HOOK_CALL(hook, args, default, retval)		\
 do {								\
-	bool __hooked;						\
-	int __hook_s;						\
-								\
-	__hook_s = pserialize_read_enter();			\
-	__hooked = atomic_load_relaxed(&hook.hooked);		\
-	if (__hooked) {						\
-		localcount_acquire(&hook.lc);			\
-	}							\
-	pserialize_read_exit(__hook_s);				\
-								\
-	if (__hooked) {						\
-		retval = (*hook.f)args;				\
-		localcount_release(&hook.lc, &module_hook_cv,	\
-		    &module_hook_mtx);				\
+	if (module_hook_tryenter(&(hook).hooked, &(hook).lc)) {	\
+		(retval) = (*(hook).f)args;			\
+		module_hook_exit(&(hook).lc);			\
 	} else {						\
-		retval = default;				\
+		(retval) = (default);				\
 	}							\
 } while /* CONSTCOND */ (0)
 
 #define MODULE_HOOK_CALL_VOID(hook, args, default)		\
 do {								\
-	bool __hooked;						\
-	int __hook_s;						\
-								\
-	__hook_s = pserialize_read_enter();			\
-	__hooked = atomic_load_relaxed(&hook.hooked);		\
-	if (__hooked) {						\
-		localcount_acquire(&hook.lc);			\
-	}							\
-	pserialize_read_exit(__hook_s);				\
-								\
-	if (__hooked) {						\
-		(*hook.f)args;					\
-		localcount_release(&hook.lc, &module_hook_cv,	\
-		    &module_hook_mtx);				\
+	if (module_hook_tryenter(&(hook).hooked, &(hook).lc)) {	\
+		(*(hook).f)args;				\
+		module_hook_exit(&(hook).lc);			\
 	} else {						\
 		default;					\
 	}							\

Index: src/sys/sys/param.h
diff -u src/sys/sys/param.h:1.623 src/sys/sys/param.h:1.624
--- src/sys/sys/param.h:1.623	Thu Dec 12 02:15:43 2019
+++ src/sys/sys/param.h	Thu Dec 12 22:55:20 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: param.h,v 1.623 2019/12/12 02:15:43 pgoyette Exp $	*/
+/*	$NetBSD: param.h,v 1.624 2019/12/12 22:55:20 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -67,7 +67,7 @@
  *	2.99.9		(299000900)
  */
 
-#define	__NetBSD_Version__	999002200	/* NetBSD 9.99.22 */
+#define	__NetBSD_Version__	999002300	/* NetBSD 9.99.23 */
 
 #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
     (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)

Added files:

Index: src/sys/kern/kern_module_hook.c
diff -u /dev/null src/sys/kern/kern_module_hook.c:1.1
--- /dev/null	Thu Dec 12 22:55:20 2019
+++ src/sys/kern/kern_module_hook.c	Thu Dec 12 22:55:20 2019
@@ -0,0 +1,132 @@
+/*	$NetBSD: kern_module_hook.c,v 1.1 2019/12/12 22:55:20 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Kernel module support.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: kern_module_hook.c,v 1.1 2019/12/12 22:55:20 pgoyette Exp $");
+
+#include <sys/param.h>
+#include <sys/module_hook.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/pserialize.h>
+
+#include <uvm/uvm_extern.h>
+
+/* Locking/synchronization stuff for module hooks */
+
+static struct {
+	kmutex_t	mtx;
+	kcondvar_t	cv;
+	pserialize_t	psz;
+} module_hook __cacheline_aligned;
+
+/* 
+ * We use pserialize_perform() to issue a memory barrier on the current
+ * CPU and on all other CPUs so that all prior memory operations on the  
+ * current CPU globally happen before all subsequent memory operations 
+ * on the current CPU, as perceived by any other CPU.
+ * 
+ * pserialize_perform() might be rather heavy-weight here, but it only
+ * happens during module loading, and it allows MODULE_HOOK_CALL() to
+ * work without any other memory barriers.
+ */
+
+void
+module_hook_set(bool *hooked, struct localcount *lc)
+{
+
+	KASSERT(kernconfig_is_held());
+	KASSERT(!*hooked);
+
+	localcount_init(lc);
+
+	/* Wait until setup has been witnessed by all CPUs.  */
+	pserialize_perform(module_hook.psz);
+
+	/* Let others use it */
+	atomic_store_relaxed(hooked, true);
+}
+
+void
+module_hook_unset(bool *hooked, struct localcount *lc)
+{
+
+	KASSERT(kernconfig_is_held());
+	KASSERT(*hooked);
+
+	/* Get exclusive with pserialize and localcount. */
+	mutex_enter(&module_hook.mtx);
+
+	/* Prevent new calls to module_hook_tryenter(). */
+	atomic_store_relaxed(hooked, false);
+
+	/* Wait for existing calls to module_hook_tryenter(). */
+	pserialize_perform(module_hook.psz);
+
+	/* Wait for module_hook_exit. */
+	localcount_drain(lc, &module_hook.cv, &module_hook.mtx);
+
+	/* All done! */
+	mutex_exit(&module_hook.mtx);
+	localcount_fini(lc);
+}
+
+bool
+module_hook_tryenter(bool *hooked, struct localcount *lc)
+{
+	bool call_hook;
+	int s;
+
+	s = pserialize_read_enter();
+	call_hook = atomic_load_relaxed(hooked);
+	if (call_hook)
+		localcount_acquire(lc);
+	pserialize_read_exit(s);
+
+	return call_hook;
+}
+
+void
+module_hook_exit(struct localcount *lc)
+{
+
+	localcount_release(lc, &module_hook.cv, &module_hook.mtx);
+}
+
+void
+module_hook_init(void)
+{
+
+	mutex_init(&module_hook.mtx, MUTEX_DEFAULT, IPL_NONE);
+	cv_init(&module_hook.cv, "mod_hook");
+	module_hook.psz = pserialize_create();
+}

Reply via email to