diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c index 417d73e7b621..ca35a05ec67d 100644 --- a/sys/kern/subr_eventhandler.c +++ b/sys/kern/subr_eventhandler.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,19 @@ struct eventhandler_entry_generic void (* func)(void); }; +/* + * Initialize the eventhandler mutex and list. + */ +static void +eventhandler_init(void *dummy __unused) +{ + TAILQ_INIT(&eventhandler_lists); + mtx_init(&eventhandler_mutex, "eventhandler", MTX_DEF); + eventhandler_lists_initted = 1; +} +SYSINIT(eventhandlers, SI_SUB_EVENTHANDLER, SI_ORDER_FIRST, eventhandler_init, + NULL) + /* * Insertion is O(n) due to the priority scan, but optimises to O(1) * if all priorities are identical. @@ -56,12 +70,7 @@ eventhandler_register(struct eventhandler_list *list, char *name, struct eventhandler_entry_generic *eg; struct eventhandler_entry *ep; - /* avoid the need for a SYSINIT just to init the list */ - if (!eventhandler_lists_initted) { - TAILQ_INIT(&eventhandler_lists); - mtx_init(&eventhandler_mutex, "eventhandler", MTX_DEF); - eventhandler_lists_initted = 1; - } + KASSERT(eventhandler_lists_initted, ("eventhandler registered too early")); /* lock the eventhandler lists */ mtx_enter(&eventhandler_mutex, MTX_DEF); @@ -86,7 +95,7 @@ eventhandler_register(struct eventhandler_list *list, char *name, } if (!(list->el_flags & EHE_INITTED)) { TAILQ_INIT(&list->el_entries); - mtx_init(&list->el_mutex, name, MTX_DEF); + lockinit(&list->el_lock, PZERO, name, 0, 0); list->el_flags = EHE_INITTED; } @@ -101,7 +110,7 @@ eventhandler_register(struct eventhandler_list *list, char *name, eg->ee.ee_priority = priority; /* sort it into the list */ - mtx_enter(&list->el_mutex, MTX_DEF); + lockmgr(&list->el_lock, LK_EXCLUSIVE, NULL, CURPROC); for (ep = TAILQ_FIRST(&list->el_entries); ep != NULL; ep = TAILQ_NEXT(ep, ee_link)) { @@ -112,7 +121,7 @@ eventhandler_register(struct eventhandler_list *list, char *name, } if (ep == NULL) TAILQ_INSERT_TAIL(&list->el_entries, &eg->ee, ee_link); - mtx_exit(&list->el_mutex, MTX_DEF); + lockmgr(&list->el_lock, LK_RELEASE, NULL, CURPROC); mtx_exit(&eventhandler_mutex, MTX_DEF); return(&eg->ee); } @@ -123,7 +132,7 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag) struct eventhandler_entry *ep = tag; /* XXX insert diagnostic check here? */ - mtx_enter(&list->el_mutex, MTX_DEF); + lockmgr(&list->el_lock, LK_EXCLUSIVE, NULL, CURPROC); if (ep != NULL) { /* remove just this entry */ TAILQ_REMOVE(&list->el_entries, ep, ee_link); @@ -136,7 +145,7 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag) free(ep, M_EVENTHANDLER); } } - mtx_exit(&list->el_mutex, MTX_DEF); + lockmgr(&list->el_lock, LK_RELEASE, NULL, CURPROC); } struct eventhandler_list * diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index 4a1e01a61fa4..1c011e2b41e5 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -30,7 +30,7 @@ #define SYS_EVENTHANDLER_H #include -#include +#include struct eventhandler_entry { @@ -44,7 +44,7 @@ struct eventhandler_list char *el_name; int el_flags; #define EHE_INITTED (1<<0) - struct mtx el_mutex; + struct lock el_lock; TAILQ_ENTRY(eventhandler_list) el_link; TAILQ_HEAD(,eventhandler_entry) el_entries; }; @@ -77,18 +77,18 @@ struct __hack #define EVENTHANDLER_FAST_INVOKE(name, args...) \ do { \ struct eventhandler_list *_el = &Xeventhandler_list_ ## name ; \ - struct eventhandler_entry *_ep = TAILQ_FIRST(&(_el->el_entries)); \ - struct eventhandler_entry *_en; \ + struct eventhandler_entry *_ep, *_en; \ \ if (_el->el_flags & EHE_INITTED) { \ + lockmgr(&_el->el_lock, LK_EXCLUSIVE, NULL, CURPROC); \ + _ep = TAILQ_FIRST(&(_el->el_entries)); \ while (_ep != NULL) { \ - mtx_enter(&_el->el_mutex, MTX_DEF); \ _en = TAILQ_NEXT(_ep, ee_link); \ - mtx_exit(&_el->el_mutex, MTX_DEF); \ ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , \ ## args); \ _ep = _en; \ } \ + lockmgr(&_el->el_lock, LK_RELEASE, NULL, CURPROC); \ } \ } while (0) @@ -120,17 +120,15 @@ do { \ \ if (((_el = eventhandler_find_list(#name)) != NULL) && \ (_el->el_flags & EHE_INITTED)) { \ - mtx_enter(&_el->el_mutex, MTX_DEF); \ + lockmgr(&_el->el_lock, LK_EXCLUSIVE, NULL, CURPROC); \ _ep = TAILQ_FIRST(&(_el->el_entries)); \ - mtx_exit(&_el->el_mutex, MTX_DEF); \ while (_ep != NULL) { \ - mtx_enter(&_el->el_mutex, MTX_DEF); \ _en = TAILQ_NEXT(_ep, ee_link); \ - mtx_exit(&_el->el_mutex, MTX_DEF); \ ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , \ ## args); \ _ep = _en; \ } \ + lockmgr(&_el->el_lock, LK_RELEASE, NULL, CURPROC); \ } \ } while (0) diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h index 7d1f57cdfed7..7474b424bff9 100644 --- a/sys/sys/kernel.h +++ b/sys/sys/kernel.h @@ -114,6 +114,7 @@ enum sysinit_sub_id { SI_SUB_KMEM = 0x1800000, /* kernel memory*/ SI_SUB_KVM_RSRC = 0x1A00000, /* kvm operational limits*/ SI_SUB_LOCK = 0x1B00000, /* lockmgr locks */ + SI_SUB_EVENTHANDLER = 0x1C00000, /* eventhandler init */ SI_SUB_CPU = 0x2000000, /* CPU resource(s)*/ SI_SUB_KLD = 0x2100000, /* KLD and module setup */ SI_SUB_INTRINSIC = 0x2200000, /* proc 0*/