If we fail to write to a vnode during a ktrace write, then we drop all
other references to that vnode as a trace vnode in other processes as well as in any pending requests on the todo list. Thus, it is possible for a ktrace request structure to have a NULL ktr_vp when it is destroyed in ktr_freerequest(). We shouldn't call vrele() on the vnode in that case. Reported by: bde
This commit is contained in:
parent
292ee3bd86
commit
a20667249e
@ -261,7 +261,7 @@ exit1(td, rv)
|
||||
* Close open files and release open-file table.
|
||||
* This may block!
|
||||
*/
|
||||
fdfree(td); /* XXXKSE *//* may not be the one in proc */
|
||||
fdfree(td);
|
||||
|
||||
/*
|
||||
* Remove ourself from our leader's peer list and wake our leader.
|
||||
|
@ -271,9 +271,11 @@ ktr_freerequest(struct ktr_request *req)
|
||||
{
|
||||
|
||||
crfree(req->ktr_cred);
|
||||
mtx_lock(&Giant);
|
||||
vrele(req->ktr_vp);
|
||||
mtx_unlock(&Giant);
|
||||
if (req->ktr_vp != NULL) {
|
||||
mtx_lock(&Giant);
|
||||
vrele(req->ktr_vp);
|
||||
mtx_unlock(&Giant);
|
||||
}
|
||||
mtx_lock(&ktrace_mtx);
|
||||
STAILQ_INSERT_HEAD(&ktr_free, req, ktr_list);
|
||||
mtx_unlock(&ktrace_mtx);
|
||||
|
@ -420,7 +420,7 @@ shutdown_reset(void *junk, int howto)
|
||||
}
|
||||
|
||||
#ifdef SMP
|
||||
static u_int panic_cpu = NOCPU;
|
||||
static uintptr_t panic_thread = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -441,15 +441,17 @@ panic(const char *fmt, ...)
|
||||
#ifdef SMP
|
||||
/*
|
||||
* We don't want multiple CPU's to panic at the same time, so we
|
||||
* use panic_cpu as a simple spinlock. We have to keep checking
|
||||
* panic_cpu if we are spinning in case the panic on the first
|
||||
* use panic_thread as a simple spinlock. We have to keep checking
|
||||
* panic_thread if we are spinning in case the panic on the first
|
||||
* CPU is canceled.
|
||||
*/
|
||||
if (panic_cpu != PCPU_GET(cpuid))
|
||||
while (atomic_cmpset_int(&panic_cpu, NOCPU,
|
||||
PCPU_GET(cpuid)) == 0)
|
||||
while (panic_cpu != NOCPU)
|
||||
; /* nothing */
|
||||
if (panic_thread != curthread)
|
||||
while (atomic_cmpset_ptr(&panic_thread, NULL, curthread) == 0)
|
||||
while (panic_thread != NULL) {
|
||||
#ifdef __i386__
|
||||
ia32_pause();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
bootopt = RB_AUTOBOOT | RB_DUMP;
|
||||
@ -481,7 +483,7 @@ panic(const char *fmt, ...)
|
||||
/* See if the user aborted the panic, in which case we continue. */
|
||||
if (panicstr == NULL) {
|
||||
#ifdef SMP
|
||||
atomic_store_rel_int(&panic_cpu, NOCPU);
|
||||
atomic_store_rel_ptr(&panic_thread, NULL);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ taskqueue_free(struct taskqueue *queue)
|
||||
{
|
||||
|
||||
mtx_lock(&queue->tq_mutex);
|
||||
KASSERT(queue->tq_draining == 0, ("free'ing a draining taskqueue"));
|
||||
queue->tq_draining = 1;
|
||||
mtx_unlock(&queue->tq_mutex);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user