Page MenuHomeFreeBSD

D27252.id79660.diff
No OneTemporary

D27252.id79660.diff

Index: sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
+++ sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
@@ -222,7 +222,7 @@
static void fasttrap_proc_release(fasttrap_proc_t *);
#ifndef illumos
-static void fasttrap_thread_dtor(void *, struct thread *);
+static void fasttrap_thread_dtor(struct thread *);
#endif
#define FASTTRAP_PROVS_INDEX(pid, name) \
@@ -232,7 +232,6 @@
#ifndef illumos
struct rmlock fasttrap_tp_lock;
-static eventhandler_tag fasttrap_thread_dtor_tag;
#endif
static unsigned long tpoints_hash_size = FASTTRAP_TPOINTS_DEFAULT_SIZE;
@@ -382,7 +381,7 @@
* free list.
*/
static void
-fasttrap_thread_dtor(void *arg __unused, struct thread *td)
+fasttrap_thread_dtor(struct thread *td)
{
fasttrap_bucket_t *bucket;
fasttrap_proc_t *fprc;
@@ -2499,8 +2498,7 @@
* This event handler must run before kdtrace_thread_dtor() since it
* accesses the thread's struct kdtrace_thread.
*/
- fasttrap_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor,
- fasttrap_thread_dtor, NULL, EVENTHANDLER_PRI_FIRST);
+ STATIC_EVENTHANDLER_REGISTER(thread_dtor, fasttrap_thread_dtor, FIRST);
#endif
/*
@@ -2602,7 +2600,7 @@
#endif
#ifndef illumos
- EVENTHANDLER_DEREGISTER(thread_dtor, fasttrap_thread_dtor_tag);
+ STATIC_EVENTHANDLER_DEREGISTER(thread_dtor, fasttrap_thread_dtor);
for (i = 0; i < fasttrap_tpoints.fth_nent; i++)
mutex_destroy(&fasttrap_tpoints.fth_table[i].ftb_mtx);
Index: sys/kern/init_main.c
===================================================================
--- sys/kern/init_main.c
+++ sys/kern/init_main.c
@@ -606,8 +606,10 @@
*/
EVENTHANDLER_DIRECT_INVOKE(process_init, p);
EVENTHANDLER_DIRECT_INVOKE(thread_init, td);
+ STATIC_EVENTHANDLER_INVOKE(thread_init, td);
EVENTHANDLER_DIRECT_INVOKE(process_ctor, p);
EVENTHANDLER_DIRECT_INVOKE(thread_ctor, td);
+ STATIC_EVENTHANDLER_INVOKE(thread_ctor, td);
/*
* Charge root for one process.
Index: sys/kern/kern_dtrace.c
===================================================================
--- sys/kern/kern_dtrace.c
+++ sys/kern/kern_dtrace.c
@@ -93,14 +93,14 @@
}
static void
-kdtrace_thread_ctor(void *arg __unused, struct thread *td)
+kdtrace_thread_ctor(struct thread *td)
{
td->td_dtrace = malloc(KDTRACE_THREAD_SIZE, M_KDTRACE, M_WAITOK|M_ZERO);
}
static void
-kdtrace_thread_dtor(void *arg __unused, struct thread *td)
+kdtrace_thread_dtor(struct thread *td)
{
if (td->td_dtrace != NULL) {
@@ -120,10 +120,8 @@
EVENTHANDLER_PRI_ANY);
EVENTHANDLER_REGISTER(process_dtor, kdtrace_proc_dtor, NULL,
EVENTHANDLER_PRI_ANY);
- EVENTHANDLER_REGISTER(thread_ctor, kdtrace_thread_ctor, NULL,
- EVENTHANDLER_PRI_ANY);
- EVENTHANDLER_REGISTER(thread_dtor, kdtrace_thread_dtor, NULL,
- EVENTHANDLER_PRI_ANY);
+ STATIC_EVENTHANDLER_REGISTER(thread_ctor, kdtrace_thread_ctor, ANY);
+ STATIC_EVENTHANDLER_REGISTER(thread_dtor, kdtrace_thread_dtor, ANY);
}
SYSINIT(kdtrace, SI_SUB_KDTRACE, SI_ORDER_FIRST, init_dtrace, NULL);
Index: sys/kern/kern_proc.c
===================================================================
--- sys/kern/kern_proc.c
+++ sys/kern/kern_proc.c
@@ -212,6 +212,7 @@
if (td != NULL) {
/* Make sure all thread constructors are executed */
EVENTHANDLER_DIRECT_INVOKE(thread_ctor, td);
+ STATIC_EVENTHANDLER_INVOKE(thread_ctor, td);
}
return (0);
}
@@ -241,6 +242,7 @@
/* Make sure all thread destructors are executed */
EVENTHANDLER_DIRECT_INVOKE(thread_dtor, td);
+ STATIC_EVENTHANDLER_INVOKE(thread_dtor, td);
}
EVENTHANDLER_DIRECT_INVOKE(process_dtor, p);
if (p->p_ksi != NULL)
Index: sys/kern/kern_thread.c
===================================================================
--- sys/kern/kern_thread.c
+++ sys/kern/kern_thread.c
@@ -169,6 +169,10 @@
EVENTHANDLER_LIST_DEFINE(thread_dtor);
EVENTHANDLER_LIST_DEFINE(thread_init);
EVENTHANDLER_LIST_DEFINE(thread_fini);
+STATIC_EVENTHANDLER_DEFINE(thread_ctor);
+STATIC_EVENTHANDLER_DEFINE(thread_dtor);
+STATIC_EVENTHANDLER_DEFINE(thread_init);
+STATIC_EVENTHANDLER_DEFINE(thread_fini);
static bool
thread_count_inc_try(void)
@@ -414,6 +418,7 @@
td->td_turnstile = turnstile_alloc();
td->td_rlqe = NULL;
EVENTHANDLER_DIRECT_INVOKE(thread_init, td);
+ STATIC_EVENTHANDLER_INVOKE(thread_init, td);
umtx_thread_init(td);
td->td_kstack = 0;
td->td_sel = NULL;
@@ -430,6 +435,7 @@
td = (struct thread *)mem;
EVENTHANDLER_DIRECT_INVOKE(thread_fini, td);
+ STATIC_EVENTHANDLER_INVOKE(thread_fini, td);
rlqentry_free(td->td_rlqe);
turnstile_free(td->td_turnstile);
sleepq_free(td->td_sleepqueue);
@@ -603,6 +609,7 @@
while (itd != NULL) {
ntd = itd->td_zombie;
EVENTHANDLER_DIRECT_INVOKE(thread_dtor, itd);
+ STATIC_EVENTHANDLER_INVOKE(thread_dtor, itd);
tidbatch_add(&tidbatch, itd);
credbatch_add(&credbatch, itd);
MPASS(itd->td_limit != NULL);
@@ -721,6 +728,7 @@
td->td_tid = tid;
cpu_thread_alloc(td);
EVENTHANDLER_DIRECT_INVOKE(thread_ctor, td);
+ STATIC_EVENTHANDLER_INVOKE(thread_ctor, td);
return (td);
}
@@ -764,6 +772,7 @@
lwpid_t tid;
EVENTHANDLER_DIRECT_INVOKE(thread_dtor, td);
+ STATIC_EVENTHANDLER_INVOKE(thread_dtor, td);
tid = td->td_tid;
thread_free_batched(td);
tid_free(tid);
Index: sys/kern/subr_eventhandler.c
===================================================================
--- sys/kern/subr_eventhandler.c
+++ sys/kern/subr_eventhandler.c
@@ -37,6 +37,7 @@
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/systm.h>
+#include <sys/rmlock.h>
#include <sys/eventhandler.h>
static MALLOC_DEFINE(M_EVENTHANDLER, "eventhandler", "Event handler records");
@@ -317,3 +318,204 @@
return (list);
}
+
+/*
+ * Static event handler points.
+ */
+static void
+static_eventhandler_validate(struct static_eventhandler *seh)
+{
+ int i;
+
+ for (i = 0; i < seh->count; i++) {
+ if (seh->cb[i] != NULL) {
+ switch (seh->prio[i]) {
+ case STATIC_EVENTHANDLER_PRIO_FIRST:
+ case STATIC_EVENTHANDLER_PRIO_ANY:
+ case STATIC_EVENTHANDLER_PRIO_LAST:
+ break;
+ default:
+ case STATIC_EVENTHANDLER_PRIO_INVALID:
+ panic("seh %p bad priority %d at %d\n", seh, seh->prio[i], i);
+ break;
+ }
+ }
+ }
+
+ for (i = 1; i < seh->count; i++) {
+ if (seh->prio[i] < seh->prio[i - 1]) {
+ panic("seh %p unsorted priorities (%d < %d) at %d\n", seh,
+ seh->prio[i], seh->prio[i - 1], i);
+ }
+ }
+
+
+ for (i = seh->count; i < seh->size; i++) {
+ if (seh->cb[i] != NULL) {
+ panic("seh %p callback %p found past the end\n", seh,
+ seh->cb[i]);
+ }
+ if (seh->prio[i] != STATIC_EVENTHANDLER_PRIO_INVALID) {
+ panic("seh %p prio %d found past the end\n", seh,
+ seh->prio[i]);
+ }
+ }
+}
+
+void
+static_eventhandler_init(struct static_eventhandler *seh)
+{
+
+ bzero(seh, sizeof(*seh));
+ rms_init(&seh->lock, "seh eventhandler");
+}
+
+void
+static_eventhandler_register(struct static_eventhandler *seh, void *pcb,
+ enum static_eventhandler_prio prio)
+{
+ static_eventhandler_cb **newcb, **tofree_cb, *cb;
+ size_t newsize;
+ enum static_eventhandler_prio *newprio, *tofree_prio;
+ int i;
+
+ if (prio == STATIC_EVENTHANDLER_PRIO_INVALID)
+ panic("invalid priority passed");
+
+ cb = (void *)pcb;
+ tofree_cb = NULL;
+ tofree_prio = NULL;
+ rms_wlock(&seh->lock);
+ MPASS(seh->count <= seh->size);
+ if (seh->cb == NULL) {
+ seh->size = 8;
+ seh->cb = malloc(sizeof(seh->cb[0]) * seh->size, M_EVENTHANDLER,
+ M_WAITOK | M_ZERO);
+ seh->prio = malloc(sizeof(seh->prio[0]) * seh->size, M_EVENTHANDLER,
+ M_WAITOK | M_ZERO);
+ } else if (seh->count == seh->size) {
+ newsize = seh->size * 2;
+ newcb = malloc(sizeof(seh->cb[0]) * newsize,
+ M_EVENTHANDLER, M_WAITOK | M_ZERO);
+ newprio = malloc(sizeof(seh->prio[0]) * newsize,
+ M_EVENTHANDLER, M_WAITOK | M_ZERO);
+ memcpy(newcb, seh->cb, sizeof(seh->cb[0]) * seh->size);
+ memcpy(newprio, seh->prio, sizeof(seh->prio[0]) * seh->size);
+
+ tofree_cb = seh->cb;
+ tofree_prio = seh->prio;
+ seh->cb = newcb;
+ seh->prio = newprio;
+ seh->size = newsize;
+ }
+
+ static_eventhandler_validate(seh);
+
+ for (i = 0; i < seh->size; i++) {
+ if (seh->cb[i] == cb)
+ panic("callback %p already registered", cb);
+ }
+
+ switch (prio) {
+ case STATIC_EVENTHANDLER_PRIO_INVALID:
+ /* appease clang */
+ panic("should not be here");
+ break;
+ case STATIC_EVENTHANDLER_PRIO_FIRST:
+ memmove(&seh->cb[1], seh->cb, sizeof(seh->cb[0]) * seh->count);
+ memmove(&seh->prio[1], seh->prio, sizeof(seh->prio[0]) * seh->count);
+ seh->cb[0] = cb;
+ seh->prio[0] = prio;
+ seh->count++;
+ break;
+ case STATIC_EVENTHANDLER_PRIO_ANY:
+ for (i = 0; i < seh->count; i++) {
+ if (seh->prio[i] != STATIC_EVENTHANDLER_PRIO_FIRST)
+ break;
+ }
+ if (i == seh->count) {
+ /*
+ * Insert at the end.
+ */
+ seh->cb[seh->count] = cb;
+ seh->prio[seh->count] = prio;
+ seh->count++;
+ } else {
+ /*
+ * Move all entries to handle STATIC_EVENTHANDLER_PRIO_LAST.
+ */
+ memmove(&seh->cb[i + 1], seh->cb, sizeof(seh->cb[0]) * (seh->count - i));
+ memmove(&seh->prio[i + 1], seh->prio, sizeof(seh->prio[0]) * (seh->count - i));
+ seh->cb[i] = cb;
+ seh->prio[i] = prio;
+ seh->count++;
+ }
+ break;
+ case STATIC_EVENTHANDLER_PRIO_LAST:
+ seh->cb[seh->count] = cb;
+ seh->prio[seh->count] = prio;
+ seh->count++;
+ break;
+ }
+ rms_wunlock(&seh->lock);
+ free(tofree_cb, M_EVENTHANDLER);
+ free(tofree_prio, M_EVENTHANDLER);
+}
+
+void
+static_eventhandler_deregister(struct static_eventhandler *seh, void *pcb)
+{
+ static_eventhandler_cb *cb;
+ int i;
+
+ cb = pcb;
+ rms_wlock(&seh->lock);
+ MPASS(seh->count <= seh->size);
+ static_eventhandler_validate(seh);
+
+ for (i = 0; i < seh->count; i++) {
+ if (seh->cb[i] == cb)
+ break;
+ }
+
+ if (i == seh->count)
+ panic("callback %p not found", cb);
+
+ switch (seh->prio[i]) {
+ case STATIC_EVENTHANDLER_PRIO_INVALID:
+ /* appease clang */
+ panic("should not be here");
+ break;
+ case STATIC_EVENTHANDLER_PRIO_FIRST:
+ memmove(seh->cb, &seh->cb[1], sizeof(seh->cb[0]) * (seh->count - 1));
+ memmove(seh->prio, &seh->prio[1], sizeof(seh->prio[0]) * (seh->count - 1));
+ break;
+ case STATIC_EVENTHANDLER_PRIO_ANY:
+ memmove(&seh->cb[i], &seh->cb[i + 1], sizeof(seh->cb[0]) * (seh->count - i));
+ memmove(&seh->prio[i], &seh->cb[i + 1], sizeof(seh->cb[0]) * (seh->count - i));
+ break;
+ case STATIC_EVENTHANDLER_PRIO_LAST:
+ seh->cb[i] = seh->cb[seh->count - 1];
+ seh->prio[i] = seh->prio[seh->count - 1];
+ break;
+ }
+ seh->cb[seh->count] = NULL;
+ seh->prio[seh->count] = STATIC_EVENTHANDLER_PRIO_INVALID;
+ seh->count--;
+ rms_wunlock(&seh->lock);
+}
+
+void
+static_eventhandler_invoke(struct static_eventhandler *seh, void *arg)
+{
+ int i;
+
+ if (seh->count == 0)
+ return;
+
+ rms_rlock(&seh->lock);
+ for (i = 0; i < seh->count; i++) {
+ (seh->cb[i])(arg);
+ }
+ rms_runlock(&seh->lock);
+}
Index: sys/kern/subr_smp.c
===================================================================
--- sys/kern/subr_smp.c
+++ sys/kern/subr_smp.c
@@ -895,6 +895,21 @@
{
int cpu;
+ /*
+ * Only one CPU to execute on.
+ */
+ if (!smp_started) {
+ spinlock_enter();
+ if (setup_func != NULL)
+ setup_func(arg);
+ if (action_func != NULL)
+ action_func(arg);
+ if (teardown_func != NULL)
+ teardown_func(arg);
+ spinlock_exit();
+ return;
+ }
+
/*
* Execute an action on all specified CPUs while retrying until they
* all acknowledge completion.
Index: sys/sys/_eventhandler.h
===================================================================
--- sys/sys/_eventhandler.h
+++ sys/sys/_eventhandler.h
@@ -69,4 +69,49 @@
}; \
struct __hack
+/*
+ * Headers to accomodate _rmlock.h
+ */
+#include <sys/param.h>
+#include <sys/_cpuset.h>
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+#include <sys/_sx.h>
+#include <sys/_rmlock.h>
+
+typedef void static_eventhandler_cb(void *);
+
+enum static_eventhandler_prio {
+ STATIC_EVENTHANDLER_PRIO_INVALID,
+ STATIC_EVENTHANDLER_PRIO_FIRST,
+ STATIC_EVENTHANDLER_PRIO_ANY,
+ STATIC_EVENTHANDLER_PRIO_LAST
+};
+
+struct static_eventhandler {
+ enum static_eventhandler_prio *prio;
+ struct rmslock lock;
+ u_int count;
+ u_int size;
+ static_eventhandler_cb **cb;
+};
+
+#define STATIC_EVENTHANDLER_DECLARE(name) \
+extern struct static_eventhandler static_eventhandler_ ## name
+
+#define STATIC_EVENTHANDLER_REGISTER(name, func, prio) \
+ static_eventhandler_register(&static_eventhandler_ ## name, func, \
+ STATIC_EVENTHANDLER_PRIO_ ## prio)
+
+#define STATIC_EVENTHANDLER_DEREGISTER(name, func) \
+ static_eventhandler_deregister(&static_eventhandler_ ## name, func)
+
+#define STATIC_EVENTHANDLER_INVOKE(name, arg) \
+ static_eventhandler_invoke(&static_eventhandler_ ## name, arg)
+
+#define STATIC_EVENTHANDLER_DEFINE(name) \
+struct static_eventhandler static_eventhandler_ ## name; \
+SYSINIT(_seh_init_ ## name, SI_SUB_EVENTHANDLER, SI_ORDER_ANY, \
+ static_eventhandler_init, &static_eventhandler_ ## name);
+
#endif
Index: sys/sys/eventhandler.h
===================================================================
--- sys/sys/eventhandler.h
+++ sys/sys/eventhandler.h
@@ -317,4 +317,13 @@
typedef void (*rt_addrmsg_fn)(void *, struct ifaddr *, int);
EVENTHANDLER_DECLARE(rt_addrmsg, rt_addrmsg_fn);
+/*
+ * Static eventhandler support.
+ */
+void static_eventhandler_init(struct static_eventhandler *seh);
+void static_eventhandler_register(struct static_eventhandler *seh, void *func,
+ enum static_eventhandler_prio prio);
+void static_eventhandler_deregister(struct static_eventhandler *seh, void *func);
+void static_eventhandler_invoke(struct static_eventhandler *seh, void *arg);
+
#endif /* _SYS_EVENTHANDLER_H_ */
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -1232,6 +1232,14 @@
EVENTHANDLER_LIST_DECLARE(thread_dtor);
EVENTHANDLER_LIST_DECLARE(thread_init);
+STATIC_EVENTHANDLER_DECLARE(thread_ctor);
+STATIC_EVENTHANDLER_DECLARE(thread_dtor);
+STATIC_EVENTHANDLER_DECLARE(thread_init);
+
+STATIC_EVENTHANDLER_DECLARE(thread_ctor);
+STATIC_EVENTHANDLER_DECLARE(thread_dtor);
+STATIC_EVENTHANDLER_DECLARE(thread_init);
+
#endif /* _KERNEL */
#endif /* !_SYS_PROC_H_ */

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 10, 8:00 AM (18 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29482376
Default Alt Text
D27252.id79660.diff (14 KB)

Event Timeline