ndis kthread teardown

From: Andrew Thompson <thompsa_at_FreeBSD.org>
Date: Fri, 20 Jul 2007 14:17:06 +1200
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