ndis will signal the kthread to exit and then sleep on the proc pointer to

be woken up by kthread_exit. This is racey and in some cases the kthread will
exit before ndis gets around to sleep so it will be stuck indefinitely. This
change reuses the kq_exit variable to indicate that the thread has gone and
will loop on tsleep with a timeout waiting for it. If the kthread has already
exited then it will not sleep at all.

Approved by:	re (rwatson)
This commit is contained in:
Andrew Thompson 2007-07-22 20:53:28 +00:00
parent 9bbad5af65
commit a4e531102e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=171548

View File

@ -2778,6 +2778,7 @@ ntoskrnl_workitem_thread(arg)
KeAcquireSpinLock(&kq->kq_lock, &irql);
if (kq->kq_exit) {
kq->kq_exit = 0;
KeReleaseSpinLock(&kq->kq_lock, irql);
break;
}
@ -2814,7 +2815,8 @@ ntoskrnl_destroy_workitem_threads(void)
kq = wq_queues + i;
kq->kq_exit = 1;
KeSetEvent(&kq->kq_proc, IO_NO_INCREMENT, FALSE);
tsleep(kq->kq_td->td_proc, PWAIT, "waitiw", 0);
while (kq->kq_exit)
tsleep(kq->kq_td->td_proc, PWAIT, "waitiw", hz/10);
}
return;
@ -3842,6 +3844,7 @@ ntoskrnl_dpc_thread(arg)
KeAcquireSpinLock(&kq->kq_lock, &irql);
if (kq->kq_exit) {
kq->kq_exit = 0;
KeReleaseSpinLock(&kq->kq_lock, irql);
break;
}
@ -3891,7 +3894,8 @@ ntoskrnl_destroy_dpc_threads(void)
KeInitializeDpc(&dpc, NULL, NULL);
KeSetTargetProcessorDpc(&dpc, i);
KeInsertQueueDpc(&dpc, NULL, NULL);
tsleep(kq->kq_td->td_proc, PWAIT, "dpcw", 0);
while (kq->kq_exit)
tsleep(kq->kq_td->td_proc, PWAIT, "dpcw", hz/10);
}
return;