Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Eliminate per-hook duplication of common code as suggest...



details:   https://anonhg.NetBSD.org/src/rev/df90edd80e7b
branches:  trunk
changeset: 1005554:df90edd80e7b
user:      pgoyette <pgoyette%NetBSD.org@localhost>
date:      Thu Dec 12 22:55:20 2019 +0000

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

Welcome to 9.99.23

diffstat:

 sys/kern/files.kern                         |    3 +-
 sys/kern/init_main.c                        |    6 +-
 sys/kern/kern_module.c                      |   14 +--
 sys/kern/kern_module_hook.c                 |  132 ++++++++++++++++++++++++++++
 sys/rump/librump/rumpkern/Makefile.rumpkern |    3 +-
 sys/sys/module_hook.h                       |   96 ++++---------------
 sys/sys/param.h                             |    4 +-
 7 files changed, 165 insertions(+), 93 deletions(-)

diffs (truncated from 406 to 300 lines):

diff -r 3bf6c89e6043 -r df90edd80e7b sys/kern/files.kern
--- a/sys/kern/files.kern       Thu Dec 12 20:14:21 2019 +0000
+++ b/sys/kern/files.kern       Thu Dec 12 22:55:20 2019 +0000
@@ -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_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
diff -r 3bf6c89e6043 -r df90edd80e7b sys/kern/init_main.c
--- a/sys/kern/init_main.c      Thu Dec 12 20:14:21 2019 +0000
+++ b/sys/kern/init_main.c      Thu Dec 12 22:55:20 2019 +0000
@@ -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 @@
 #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 @@
 
        /* Start module system. */
        module_init();
+       module_hook_init();
 
        /*
         * Initialize the kernel authorization subsystem and start the
diff -r 3bf6c89e6043 -r df90edd80e7b sys/kern/kern_module.c
--- a/sys/kern/kern_module.c    Thu Dec 12 20:14:21 2019 +0000
+++ b/sys/kern/kern_module.c    Thu Dec 12 22:55:20 2019 +0000
@@ -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 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_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();
 }
 
 /*
diff -r 3bf6c89e6043 -r df90edd80e7b sys/kern/kern_module_hook.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/kern/kern_module_hook.c       Thu Dec 12 22:55:20 2019 +0000
@@ -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();
+}
diff -r 3bf6c89e6043 -r df90edd80e7b sys/rump/librump/rumpkern/Makefile.rumpkern
--- a/sys/rump/librump/rumpkern/Makefile.rumpkern       Thu Dec 12 20:14:21 2019 +0000
+++ b/sys/rump/librump/rumpkern/Makefile.rumpkern       Thu Dec 12 22:55:20 2019 +0000
@@ -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 @@
        kern_ksyms.c            \
        kern_malloc.c           \
        kern_module.c           \
+       kern_module_hook.c      \
        kern_mutex_obj.c        \
        kern_ntptime.c          \
        kern_proc.c             \
diff -r 3bf6c89e6043 -r df90edd80e7b sys/sys/module_hook.h
--- a/sys/sys/module_hook.h     Thu Dec 12 20:14:21 2019 +0000
+++ b/sys/sys/module_hook.h     Thu Dec 12 22:55:20 2019 +0000
@@ -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 @@
 
 #define MODULE_HOOK_SET(hook, func)                            \
 do {                                                           \
-                                                               \
-       KASSERT(kernconfig_is_held());                          \
-       KASSERT(!hook.hooked);                                  \
-                                                               \
-       localcount_init(&hook.lc);                              \
-       hook.f = func;                                          \



Home | Main Index | Thread Index | Old Index