Hi, There seems to be a race in the ndis code when stopping the ntoskrnl_workitem threads. It sets a flag, wakes up the thread, and then sleeps on the proc for the wakeup from kthread_exit. I have found that the kthread can exit before ntoskrnl_destroy_workitem_threads() gets to sleep on the proc, this means that it will sleep indefinitely. Here is a patch that fixes it for me, it reuses the kq_exit flag to identify that its already closed. Andrew Index: subr_ntoskrnl.c =================================================================== RCS file: /home/ncvs/src/sys/compat/ndis/subr_ntoskrnl.c,v retrieving revision 1.89 diff -u -p -r1.89 subr_ntoskrnl.c --- subr_ntoskrnl.c 5 Jun 2007 00:00:50 -0000 1.89 +++ subr_ntoskrnl.c 20 Jul 2007 02:05:43 -0000 _at__at_ -2778,6 +2778,7 _at__at_ ntoskrnl_workitem_thread(arg) KeAcquireSpinLock(&kq->kq_lock, &irql); if (kq->kq_exit) { + kq->kq_exit = 0; KeReleaseSpinLock(&kq->kq_lock, irql); break; } _at__at_ -2814,7 +2815,8 _at__at_ 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); + if (kq->kq_exit) + tsleep(kq->kq_td->td_proc, PWAIT, "waitiw", 0); } return; _at__at_ -3842,6 +3844,7 _at__at_ ntoskrnl_dpc_thread(arg) KeAcquireSpinLock(&kq->kq_lock, &irql); if (kq->kq_exit) { + kq->kq_exit = 0; KeReleaseSpinLock(&kq->kq_lock, irql); break; } _at__at_ -3891,7 +3894,8 _at__at_ 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); + if (kq->kq_exit) + tsleep(kq->kq_td->td_proc, PWAIT, "dpcw", 0); } return;Received on Fri Jul 20 2007 - 00:17:07 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:14 UTC