Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/sys Introduce a generic linear hook list
details: https://anonhg.NetBSD.org/src/rev/6f3509584d68
branches: trunk
changeset: 1023864:6f3509584d68
user: yamaguchi <yamaguchi%NetBSD.org@localhost>
date: Thu Sep 30 01:26:07 2021 +0000
description:
Introduce a generic linear hook list
diffstat:
distrib/sets/lists/comp/mi | 3 +-
sys/kern/kern_hook.c | 207 ++++++++++++++++++++++++++++++++++++++++++++-
sys/sys/Makefile | 4 +-
sys/sys/hook.h | 52 +++++++++++
4 files changed, 261 insertions(+), 5 deletions(-)
diffs (truncated from 329 to 300 lines):
diff -r 6571f1fbdf48 -r 6f3509584d68 distrib/sets/lists/comp/mi
--- a/distrib/sets/lists/comp/mi Thu Sep 30 01:20:53 2021 +0000
+++ b/distrib/sets/lists/comp/mi Thu Sep 30 01:26:07 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.2393 2021/09/19 15:51:27 thorpej Exp $
+# $NetBSD: mi,v 1.2394 2021/09/30 01:26:07 yamaguchi Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
./etc/mtree/set.comp comp-sys-root
@@ -3306,6 +3306,7 @@
./usr/include/sys/gmon.h comp-c-include
./usr/include/sys/gpio.h comp-c-include
./usr/include/sys/hash.h comp-c-include
+./usr/include/sys/hook.h comp-c-include
./usr/include/sys/idtype.h comp-c-include
./usr/include/sys/ieee754.h comp-c-include
./usr/include/sys/intr.h comp-c-include
diff -r 6571f1fbdf48 -r 6f3509584d68 sys/kern/kern_hook.c
--- a/sys/kern/kern_hook.c Thu Sep 30 01:20:53 2021 +0000
+++ b/sys/kern/kern_hook.c Thu Sep 30 01:26:07 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_hook.c,v 1.8 2019/10/16 18:29:49 christos Exp $ */
+/* $NetBSD: kern_hook.c,v 1.9 2021/09/30 01:26:07 yamaguchi Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999, 2002, 2007, 2008 The NetBSD Foundation, Inc.
@@ -31,13 +31,16 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_hook.c,v 1.8 2019/10/16 18:29:49 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_hook.c,v 1.9 2021/09/30 01:26:07 yamaguchi Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/rwlock.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/hook.h>
+#include <sys/kmem.h>
+#include <sys/condvar.h>
/*
* A generic linear hook.
@@ -49,6 +52,23 @@
};
typedef LIST_HEAD(, hook_desc) hook_list_t;
+enum hook_list_st {
+ HKLIST_IDLE,
+ HKLIST_INUSE,
+};
+
+struct khook_list {
+ hook_list_t hl_list;
+ kmutex_t hl_lock;
+ kmutex_t *hl_cvlock;
+ struct lwp *hl_lwp;
+ kcondvar_t hl_cv;
+ enum hook_list_st
+ hl_state;
+ khook_t *hl_active_hk;
+ char hl_namebuf[HOOKNAMSIZ];
+};
+
int powerhook_debug = 0;
static void *
@@ -398,3 +418,186 @@
if (powerhook_debug)
printf("dopowerhooks: %s done\n", why_name);
}
+
+/*
+ * A simple linear hook.
+ */
+
+khook_list_t *
+simplehook_create(int ipl, const char *wmsg)
+{
+ khook_list_t *l;
+
+ l = kmem_zalloc(sizeof(*l), KM_SLEEP);
+
+ mutex_init(&l->hl_lock, MUTEX_DEFAULT, ipl);
+ strlcpy(l->hl_namebuf, wmsg, sizeof(l->hl_namebuf));
+ cv_init(&l->hl_cv, l->hl_namebuf);
+ LIST_INIT(&l->hl_list);
+ l->hl_state = HKLIST_IDLE;
+
+ return l;
+}
+
+void
+simplehook_destroy(khook_list_t *l)
+{
+ struct hook_desc *hd;
+
+ KASSERT(l->hl_state == HKLIST_IDLE);
+
+ while ((hd = LIST_FIRST(&l->hl_list)) != NULL) {
+ LIST_REMOVE(hd, hk_list);
+ kmem_free(hd, sizeof(*hd));
+ }
+
+ cv_destroy(&l->hl_cv);
+ mutex_destroy(&l->hl_lock);
+ kmem_free(l, sizeof(*l));
+}
+
+int
+simplehook_dohooks(khook_list_t *l)
+{
+ struct hook_desc *hd, *nexthd;
+ kmutex_t *cv_lock;
+ void (*fn)(void *);
+ void *arg;
+
+ mutex_enter(&l->hl_lock);
+ if (l->hl_state != HKLIST_IDLE) {
+ mutex_exit(&l->hl_lock);
+ return EBUSY;
+ }
+
+ /* stop removing hooks */
+ l->hl_state = HKLIST_INUSE;
+ l->hl_lwp = curlwp;
+
+ LIST_FOREACH(hd, &l->hl_list, hk_list) {
+ if (hd->hk_fn == NULL)
+ continue;
+
+ fn = hd->hk_fn;
+ arg = hd->hk_arg;
+ l->hl_active_hk = hd;
+ l->hl_cvlock = NULL;
+
+ mutex_exit(&l->hl_lock);
+
+ /* do callback without l->hl_lock */
+ (*fn)(arg);
+
+ mutex_enter(&l->hl_lock);
+ l->hl_active_hk = NULL;
+ cv_lock = l->hl_cvlock;
+
+ if (hd->hk_fn == NULL) {
+ if (cv_lock != NULL) {
+ mutex_exit(&l->hl_lock);
+ mutex_enter(cv_lock);
+ }
+
+ cv_broadcast(&l->hl_cv);
+
+ if (cv_lock != NULL) {
+ mutex_exit(cv_lock);
+ mutex_enter(&l->hl_lock);
+ }
+ }
+ }
+
+ /* remove marked node while running hooks */
+ LIST_FOREACH_SAFE(hd, &l->hl_list, hk_list, nexthd) {
+ if (hd->hk_fn == NULL) {
+ LIST_REMOVE(hd, hk_list);
+ kmem_free(hd, sizeof(*hd));
+ }
+ }
+
+ l->hl_lwp = NULL;
+ l->hl_state = HKLIST_IDLE;
+ mutex_exit(&l->hl_lock);
+
+ return 0;
+}
+
+khook_t *
+simplehook_establish(khook_list_t *l, void (*fn)(void *), void *arg)
+{
+ struct hook_desc *hd;
+
+ hd = kmem_zalloc(sizeof(*hd), KM_SLEEP);
+ hd->hk_fn = fn;
+ hd->hk_arg = arg;
+
+ mutex_enter(&l->hl_lock);
+ LIST_INSERT_HEAD(&l->hl_list, hd, hk_list);
+ mutex_exit(&l->hl_lock);
+
+ return hd;
+}
+
+void
+simplehook_disestablish(khook_list_t *l, khook_t *hd, kmutex_t *lock)
+{
+ struct hook_desc *hd0 __diagused;
+ kmutex_t *cv_lock;
+
+ KASSERT(lock == NULL || mutex_owned(lock));
+ mutex_enter(&l->hl_lock);
+
+#ifdef DIAGNOSTIC
+ LIST_FOREACH(hd0, &l->hl_list, hk_list) {
+ if (hd == hd0)
+ break;
+ }
+
+ if (hd0 == NULL)
+ panic("hook_disestablish: hook %p not established", hd);
+#endif
+
+ /* The hook is not referred, remove immidiately */
+ if (l->hl_state == HKLIST_IDLE) {
+ LIST_REMOVE(hd, hk_list);
+ kmem_free(hd, sizeof(*hd));
+ mutex_exit(&l->hl_lock);
+ return;
+ }
+
+ /* remove callback. hd will be removed in dohooks */
+ hd->hk_fn = NULL;
+ hd->hk_arg = NULL;
+
+ /* If the hook is running, wait for the completion */
+ if (l->hl_active_hk == hd &&
+ l->hl_lwp != curlwp) {
+ if (lock != NULL) {
+ cv_lock = lock;
+ KASSERT(l->hl_cvlock == NULL);
+ l->hl_cvlock = lock;
+ mutex_exit(&l->hl_lock);
+ } else {
+ cv_lock = &l->hl_lock;
+ }
+
+ cv_wait(&l->hl_cv, cv_lock);
+
+ if (lock == NULL)
+ mutex_exit(&l->hl_lock);
+ } else {
+ mutex_exit(&l->hl_lock);
+ }
+}
+
+bool
+simplehook_has_hooks(khook_list_t *l)
+{
+ bool empty;
+
+ mutex_enter(&l->hl_lock);
+ empty = LIST_EMPTY(&l->hl_list);
+ mutex_exit(&l->hl_lock);
+
+ return !empty;
+}
diff -r 6571f1fbdf48 -r 6f3509584d68 sys/sys/Makefile
--- a/sys/sys/Makefile Thu Sep 30 01:20:53 2021 +0000
+++ b/sys/sys/Makefile Thu Sep 30 01:26:07 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.178 2021/09/19 15:51:27 thorpej Exp $
+# $NetBSD: Makefile,v 1.179 2021/09/30 01:26:07 yamaguchi Exp $
.include <bsd.own.mk>
@@ -23,7 +23,7 @@
fault.h \
fcntl.h fd_set.h fdio.h featuretest.h file.h filedesc.h filio.h \
flashio.h float_ieee754.h fstypes.h futex.h gcq.h gmon.h gpio.h hash.h \
- idtype.h ieee754.h intr.h intrio.h inttypes.h ioccom.h ioctl.h \
+ hook.h idtype.h ieee754.h intr.h intrio.h inttypes.h ioccom.h ioctl.h \
ioctl_compat.h iostat.h ipc.h ipmi.h \
joystick.h \
kcore.h kcov.h kcpuset.h kgdb.h kmem.h ksem.h ksyms.h ktrace.h \
diff -r 6571f1fbdf48 -r 6f3509584d68 sys/sys/hook.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/sys/hook.h Thu Sep 30 01:26:07 2021 +0000
@@ -0,0 +1,52 @@
+/* $NetBSD: hook.h,v 1.1 2021/09/30 01:26:07 yamaguchi Exp $ */
+
+/*
+ * Copyright (c) 2021 Internet Initiative Japan 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
Home |
Main Index |
Thread Index |
Old Index