summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_intr.c58
-rw-r--r--sys/kern/kern_jail.c2
-rw-r--r--sys/kern/kern_sx.c2
-rw-r--r--sys/kern/kern_sysctl.c30
-rw-r--r--sys/kern/subr_bus.c4
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);
OpenPOWER on IntegriCloud