diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_intr.c | 58 | ||||
-rw-r--r-- | sys/kern/kern_jail.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_sx.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 30 | ||||
-rw-r--r-- | sys/kern/subr_bus.c | 4 |
5 files changed, 86 insertions, 10 deletions
diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index ea1aa1b..daeb2dc 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -74,6 +74,7 @@ struct intr_thread { /* Interrupt thread flags kept in it_flags */ #define IT_DEAD 0x000001 /* Thread is waiting to exit. */ +#define IT_WAIT 0x000002 /* Thread is waiting for completion. */ struct intr_entropy { struct thread *td; @@ -735,6 +736,39 @@ intr_handler_source(void *cookie) return (ie->ie_source); } +/* + * Sleep until an ithread finishes executing an interrupt handler. + * + * XXX Doesn't currently handle interrupt filters or fast interrupt + * handlers. This is intended for compatibility with linux drivers + * only. Do not use in BSD code. + */ +void +_intr_drain(int irq) +{ + struct mtx *mtx; + struct intr_event *ie; + struct intr_thread *ithd; + struct thread *td; + + ie = intr_lookup(irq); + if (ie == NULL) + return; + if (ie->ie_thread == NULL) + return; + ithd = ie->ie_thread; + td = ithd->it_thread; + thread_lock(td); + mtx = td->td_lock; + if (!TD_AWAITING_INTR(td)) { + ithd->it_flags |= IT_WAIT; + msleep_spin(ithd, mtx, "isync", 0); + } + mtx_unlock_spin(mtx); + return; +} + + #ifndef INTR_FILTER int intr_event_remove_handler(void *cookie) @@ -1271,6 +1305,7 @@ ithread_loop(void *arg) struct intr_event *ie; struct thread *td; struct proc *p; + int wake; td = curthread; p = td->td_proc; @@ -1279,6 +1314,7 @@ ithread_loop(void *arg) ("%s: ithread and proc linkage out of sync", __func__)); ie = ithd->it_event; ie->ie_count = 0; + wake = 0; /* * As long as we have interrupts outstanding, go through the @@ -1319,12 +1355,20 @@ ithread_loop(void *arg) * set again, so we have to check it again. */ thread_lock(td); - if (!ithd->it_need && !(ithd->it_flags & IT_DEAD)) { + if (!ithd->it_need && !(ithd->it_flags & (IT_DEAD | IT_WAIT))) { TD_SET_IWAIT(td); ie->ie_count = 0; mi_switch(SW_VOL | SWT_IWAIT, NULL); } + if (ithd->it_flags & IT_WAIT) { + wake = 1; + ithd->it_flags &= ~IT_WAIT; + } thread_unlock(td); + if (wake) { + wakeup(ithd); + wake = 0; + } } } @@ -1439,6 +1483,7 @@ ithread_loop(void *arg) struct thread *td; struct proc *p; int priv; + int wake; td = curthread; p = td->td_proc; @@ -1449,6 +1494,7 @@ ithread_loop(void *arg) ("%s: ithread and proc linkage out of sync", __func__)); ie = ithd->it_event; ie->ie_count = 0; + wake = 0; /* * As long as we have interrupts outstanding, go through the @@ -1492,12 +1538,20 @@ ithread_loop(void *arg) * set again, so we have to check it again. */ thread_lock(td); - if (!ithd->it_need && !(ithd->it_flags & IT_DEAD)) { + if (!ithd->it_need && !(ithd->it_flags & (IT_DEAD | IT_WAIT))) { TD_SET_IWAIT(td); ie->ie_count = 0; mi_switch(SW_VOL | SWT_IWAIT, NULL); } + if (ithd->it_flags & IT_WAIT) { + wake = 1; + ithd->it_flags &= ~IT_WAIT; + } thread_unlock(td); + if (wake) { + wakeup(ithd); + wake = 0; + } } } diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index ed98a77..08343dd 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -4182,7 +4182,7 @@ sysctl_jail_param(SYSCTL_HANDLER_ARGS) i = 0; return (SYSCTL_OUT(req, &i, sizeof(i))); case CTLTYPE_STRING: - snprintf(numbuf, sizeof(numbuf), "%d", arg2); + snprintf(numbuf, sizeof(numbuf), "%jd", (intmax_t)arg2); return (sysctl_handle_string(oidp, numbuf, sizeof(numbuf), req)); case CTLTYPE_STRUCT: diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c index 1333c66..b824eac 100644 --- a/sys/kern/kern_sx.c +++ b/sys/kern/kern_sx.c @@ -194,7 +194,7 @@ sx_sysinit(void *arg) { struct sx_args *sargs = arg; - sx_init(sargs->sa_sx, sargs->sa_desc); + sx_init_flags(sargs->sa_sx, sargs->sa_desc, sargs->sa_flags); } void diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index c061a47..0f1e357 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -365,10 +365,31 @@ sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse) return (error); } +int +sysctl_remove_name(struct sysctl_oid *parent, const char *name, + int del, int recurse) +{ + struct sysctl_oid *p, *tmp; + int error; + + error = ENOENT; + SYSCTL_XLOCK(); + SLIST_FOREACH_SAFE(p, SYSCTL_CHILDREN(parent), oid_link, tmp) { + if (strcmp(p->oid_name, name) == 0) { + error = sysctl_remove_oid_locked(p, del, recurse); + break; + } + } + SYSCTL_XUNLOCK(); + + return (error); +} + + static int sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse) { - struct sysctl_oid *p; + struct sysctl_oid *p, *tmp; int error; SYSCTL_ASSERT_XLOCKED(); @@ -387,7 +408,8 @@ sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse) */ if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { if (oidp->oid_refcnt == 1) { - SLIST_FOREACH(p, SYSCTL_CHILDREN(oidp), oid_link) { + SLIST_FOREACH_SAFE(p, + SYSCTL_CHILDREN(oidp), oid_link, tmp) { if (!recurse) return (ENOTEMPTY); error = sysctl_remove_oid_locked(p, del, @@ -428,14 +450,13 @@ sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse) } return (0); } - /* * Create new sysctls at run time. * clist may point to a valid context initialized with sysctl_ctx_init(). */ struct sysctl_oid * sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, - int number, const char *name, int kind, void *arg1, int arg2, + int number, const char *name, int kind, void *arg1, intptr_t arg2, int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr) { struct sysctl_oid *oidp; @@ -479,6 +500,7 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, SYSCTL_CHILDREN_SET(oidp, malloc(sizeof(struct sysctl_oid_list), M_SYSCTLOID, M_WAITOK)); SLIST_INIT(SYSCTL_CHILDREN(oidp)); + oidp->oid_arg2 = arg2; } else { oidp->oid_arg1 = arg1; oidp->oid_arg2 = arg2; diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index f6b1ecc..a865586 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -1038,7 +1038,7 @@ devclass_driver_added(devclass_t dc, driver_t *driver) * @param dc the devclass to edit * @param driver the driver to register */ -static int +int devclass_add_driver(devclass_t dc, driver_t *driver, int pass, devclass_t *dcp) { driverlink_t dl; @@ -1172,7 +1172,7 @@ devclass_driver_deleted(devclass_t busclass, devclass_t dc, driver_t *driver) * @param dc the devclass to edit * @param driver the driver to unregister */ -static int +int devclass_delete_driver(devclass_t busclass, driver_t *driver) { devclass_t dc = devclass_find(driver->name); |