Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/pgoyette-compat]: src/sys/sys Finish the macros for MP-safe COMPAT_HOOKS
details: https://anonhg.NetBSD.org/src/rev/0dceb50a346f
branches: pgoyette-compat
changeset: 830712:0dceb50a346f
user: pgoyette <pgoyette%NetBSD.org@localhost>
date: Sun Sep 16 00:40:27 2018 +0000
description:
Finish the macros for MP-safe COMPAT_HOOKS
diffstat:
sys/sys/compat_stub.h | 163 +++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 143 insertions(+), 20 deletions(-)
diffs (200 lines):
diff -r 2bf0af9c21ca -r 0dceb50a346f sys/sys/compat_stub.h
--- a/sys/sys/compat_stub.h Sat Sep 15 06:37:48 2018 +0000
+++ b/sys/sys/compat_stub.h Sun Sep 16 00:40:27 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: compat_stub.h,v 1.1.2.18 2018/09/15 06:37:48 pgoyette Exp $ */
+/* $NetBSD: compat_stub.h,v 1.1.2.19 2018/09/16 00:40:27 pgoyette Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -32,34 +32,152 @@
#ifndef _SYS_COMPAT_STUB_H
#define _SYS_COMPAT_STUB_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>
/*
- * Macro for creating MP-safe vectored function calls
+ * Macros for creating MP-safe vectored function calls, where
+ * the function implementations are in modules which could be
+ * unloaded.
*/
-#if defined(MODULAR)
-#define COMPAT_HOOK(name,type,args) \
-struct __CONCAT(name,_t) { \
- kmutex_t lock; \
- kcondvar_t cv; \
- struct localcount lc; \
- pserialize_t psz; \
- bool hooked; \
- type (*func)(args); \
-} name __cacheline_aligned;
-#else /* defined(MODULAR) */
-#define COMPAT_HOOK(name,type,args) \
-struct __CONCAT(name,_t) { \
- bool hooked; \
- type (*func)(args); \
-} name __cacheline_aligned;
-#endif /* defined(MODULAR) */
+
+#define COMPAT_HOOK(hook,type,args) \
+extern struct __CONCAT(hook,_t) { \
+ kmutex_t lock; \
+ kcondvar_t cv; \
+ struct localcount lc; \
+ pserialize_t psz; \
+ bool hooked; \
+ type (*func)args; \
+} hook __cacheline_aligned;
+
+#define COMPAT_HOOK2(hook,type1,args1,type2,args2) \
+extern struct __CONCAT(hook,_t) { \
+ kmutex_t lock; \
+ kcondvar_t cv; \
+ struct localcount lc; \
+ pserialize_t psz; \
+ bool hooked; \
+ type1 (*func1)args1; \
+ type2 (*func2)args2; \
+} hook __cacheline_aligned;
+
+#define COMPAT_SET_HOOK(hook, waitchan, f) \
+static void __CONCAT(hook,sethook)(void) \
+{ \
+ \
+ KASSERT(!hook.hooked); \
+ \
+ hook.psz = pserialize_create(); \
+ mutex_init(&hook.mtx, MUTEX_DEFAULT, IPL_NONE); \
+ cv_init(&hook.cv, waitchan); \
+ localcount_init(&hook.lc); \
+ hook.func = f; \
+ \
+ /* Make sure it's initialized before anyone uses it */ \
+ membar_producer(); \
+ \
+ /* Let them use it */ \
+ hook.hooked = true; \
+}
+
+#define COMPAT_SET_HOOK2(hook, waitchan, f1, f2) \
+static void __CONCAT(hook,sethook)(void) \
+{ \
+ \
+ KASSERT(!hook.hooked); \
+ \
+ hook.psz = pserialize_create(); \
+ mutex_init(&hook.mtx, MUTEX_DEFAULT, IPL_NONE); \
+ cv_init(&hook.cv, waitchan); \
+ localcount_init(&hook.lc); \
+ hook.func1 = f1; \
+ hook.func2 = f2; \
+ \
+ /* Make sure it's initialized before anyone uses it */ \
+ membar_producer(); \
+ \
+ /* Let them use it */ \
+ hook.hooked = true; \
+}
+
+#define COMPAT_UNSET_HOOK(hook) \
+static void __CONCAT(hook,unsethook)(void) \
+{ \
+ \
+ KASSERT(kernconfig_is_held()); \
+ KASSERT(hook.hooked); \
+ KASSERT(hook.func); \
+ \
+ /* Prevent new localcount_acquire calls. */ \
+ hook.hooked = false; \
+ \
+ /* Wait for existing localcount_acquire calls to drain. */ \
+ pserialize_perform(hook.psz); \
+ \
+ /* Wait for existing localcount references to drain. */\
+ localcount_drain(&hook.lc, &hook.cv, &hook.mtx); \
+ \
+ localcount_fini(&hook.lc); \
+ cv_destroy(&hook.cv); \
+ mutex_destroy(&hook.mtx); \
+ pserialize_destroy(hook.psz); \
+}
+
+#define COMPAT_UNSET_HOOK2(hook) \
+static void __CONCAT(hook,unsethook)(void) \
+{ \
+ \
+ KASSERT(kernconfig_is_held()); \
+ KASSERT(hook.hooked); \
+ KASSERT(hook.func1); \
+ KASSERT(hook.func2); \
+ \
+ /* Prevent new localcount_acquire calls. */ \
+ hook.hooked = false; \
+ \
+ /* Wait for existing localcount_acquire calls to drain. */ \
+ pserialize_perform(hook.psz); \
+ \
+ /* Wait for existing localcount references to drain. */\
+ localcount_drain(&hook.lc, &hook.cv, &hook.mtx); \
+ \
+ localcount_fini(&hook.lc); \
+ cv_destroy(&hook.cv); \
+ mutex_destroy(&hook.mtx); \
+ pserialize_destroy(hook.psz); \
+}
+
+#define COMPAT_CALL_HOOK(hook, which, args, no_hook) \
+type \
+__CONCAT(call_,hook)(args) \
+{ \
+ bool hooked; \
+ int error, s; \
+ \
+ s = pserialize_read_enter(); \
+ hooked = hook.hooked; \
+ if (hooked) { \
+ membar_consumer(): \
+ localcount_acquire(&hook.lc); \
+ } \
+ pserialize_read_exit(); \
+ \
+ if (hooked) { \
+ error = (*hook.which)(args); \
+ localcount_release(&hook.lc, &hook.cv, \
+ &hook.mtx); \
+ } else { \
+ error = no_hook(args); \
+ } \
+ return error; \
+;
/*
- * Routine vectors for compat_50___sys_ntp_gettime
+ * Routine hooks for compat_50___sys_ntp_gettime
*/
struct ntptimeval;
@@ -67,6 +185,8 @@
extern void (*vec_ntp_gettime)(struct ntptimeval *);
extern int (*vec_ntp_timestatus)(void);
+COMPAT_HOOK2(ntp_gettime_hooks, void, (struct ntptimeval *), int, (void))
+
/*
* Routine vector for dev/ccd ioctl()
*/
@@ -74,6 +194,9 @@
extern int (*compat_ccd_ioctl_60)(dev_t, u_long, void *, int, struct lwp *,
int (*f)(dev_t, u_long, void *, int, struct lwp *));
+COMPAT_HOOK(ccd_ioctl_hook, int, (dev_t, u_long, void *, int, struct lwp *,
+ int (*f)(dev_t, u_long, void *, int, struct lwp *)))
+
/*
* Routine vector for dev/clockctl ioctl()
*/
Home |
Main Index |
Thread Index |
Old Index