Make kldunload cbb work:
o Implement the thread killing interlock as described by jhb in arch@ while talking to markm. o Hold Giant around cbb_insert()/cbb_remove(). Deep in the belly of the vm code we panic if we don't hold this when we activate the memory for reading the CIS. o If we had to do the kludge alloc, then do a kludge free.
This commit is contained in:
parent
cb71b7bb07
commit
2af88da4a8
@ -732,20 +732,18 @@ cbb_detach(device_t brdev)
|
|||||||
sc->flags |= CBB_KTHREAD_DONE;
|
sc->flags |= CBB_KTHREAD_DONE;
|
||||||
if (sc->flags & CBB_KTHREAD_RUNNING) {
|
if (sc->flags & CBB_KTHREAD_RUNNING) {
|
||||||
cv_broadcast(&sc->cv);
|
cv_broadcast(&sc->cv);
|
||||||
mtx_unlock(&sc->mtx);
|
msleep(sc->event_thread, &sc->mtx, PWAIT, "cbbun", 0);
|
||||||
DEVPRINTF((brdev, "waiting for kthread exit..."));
|
|
||||||
error = tsleep(sc, PWAIT, "cbb-detach-wait", 60 * hz);
|
|
||||||
if (error)
|
|
||||||
DPRINTF(("timeout\n"));
|
|
||||||
else
|
|
||||||
DPRINTF(("done\n"));
|
|
||||||
} else {
|
|
||||||
mtx_unlock(&sc->mtx);
|
|
||||||
}
|
}
|
||||||
|
mtx_unlock(&sc->mtx);
|
||||||
|
|
||||||
bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res);
|
bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res);
|
||||||
bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE,
|
if (sc->flags & CBB_KLUDGE_ALLOC)
|
||||||
sc->base_res);
|
bus_generic_release_resource(device_get_parent(brdev),
|
||||||
|
brdev, SYS_RES_MEMORY, CBBR_SOCKBASE,
|
||||||
|
sc->base_res);
|
||||||
|
else
|
||||||
|
bus_release_resource(brdev, SYS_RES_MEMORY,
|
||||||
|
CBBR_SOCKBASE, sc->base_res);
|
||||||
mtx_destroy(&sc->mtx);
|
mtx_destroy(&sc->mtx);
|
||||||
cv_destroy(&sc->cv);
|
cv_destroy(&sc->cv);
|
||||||
return (0);
|
return (0);
|
||||||
@ -898,10 +896,11 @@ cbb_event_thread(void *arg)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We take out Giant here because we drop it in tsleep
|
* We take out Giant here because we need it deep, down in
|
||||||
* and need it for kthread_exit, which drops it.
|
* the bowels of the vm system for mapping the memory we need
|
||||||
|
* to read the CIS. We also need it for kthread_exit, which
|
||||||
|
* drops it.
|
||||||
*/
|
*/
|
||||||
mtx_lock(&Giant);
|
|
||||||
sc->flags |= CBB_KTHREAD_RUNNING;
|
sc->flags |= CBB_KTHREAD_RUNNING;
|
||||||
while (1) {
|
while (1) {
|
||||||
/*
|
/*
|
||||||
@ -913,10 +912,13 @@ cbb_event_thread(void *arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
status = cbb_get(sc, CBB_SOCKET_STATE);
|
status = cbb_get(sc, CBB_SOCKET_STATE);
|
||||||
|
mtx_lock(&Giant);
|
||||||
if ((status & CBB_SOCKET_STAT_CD) == 0)
|
if ((status & CBB_SOCKET_STAT_CD) == 0)
|
||||||
cbb_insert(sc);
|
cbb_insert(sc);
|
||||||
else
|
else
|
||||||
cbb_removal(sc);
|
cbb_removal(sc);
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until it has been 1s since the last time we
|
* Wait until it has been 1s since the last time we
|
||||||
* get an interrupt. We handle the rest of the interrupt
|
* get an interrupt. We handle the rest of the interrupt
|
||||||
@ -931,14 +933,7 @@ cbb_event_thread(void *arg)
|
|||||||
mtx_unlock(&sc->mtx);
|
mtx_unlock(&sc->mtx);
|
||||||
}
|
}
|
||||||
sc->flags &= ~CBB_KTHREAD_RUNNING;
|
sc->flags &= ~CBB_KTHREAD_RUNNING;
|
||||||
/*
|
mtx_lock(&Giant);
|
||||||
* XXX I think there's a race here. If we wakeup in the other
|
|
||||||
* thread before kthread_exit is called and this routine returns,
|
|
||||||
* and that thread causes us to be unmapped, then we are setting
|
|
||||||
* ourselves up for a panic. Make sure that I check out
|
|
||||||
* jhb's crash.c for a fix.
|
|
||||||
*/
|
|
||||||
wakeup(sc);
|
|
||||||
kthread_exit(0);
|
kthread_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user