summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2005-10-22 05:15:20 +0000
committerwpaul <wpaul@FreeBSD.org>2005-10-22 05:15:20 +0000
commitbe0b87ae9318f36ecbbd0aec85672bc551305f66 (patch)
tree54311641e5ababd57dd17f963eaf343931297698 /sys/compat
parentacd6923419a86b702232316d9daae546732a366b (diff)
downloadFreeBSD-src-be0b87ae9318f36ecbbd0aec85672bc551305f66.zip
FreeBSD-src-be0b87ae9318f36ecbbd0aec85672bc551305f66.tar.gz
Make the multiple DPC threads an option, and create only one by default.
This avoids the need for sched_bind() in the default case so that you can start up the NDIS subsystem at boot time when only CPU 0 is running. There are potentially ways to fix it so that the DPC threads aren't started until after the other CPUs are launched, but doing it correctly is tricky. You need to defer the startup of the ntoskrnl subsystem (ntoskrnl_libinit()), not just defer ndis_attach(). For now, I don't think it will make much difference having just the single DPC thread (I started out with just one anyway). Note that this turns the KeSetTargetProcessorDpc() routine into a no-op, since the CPU number in struct kdpc is now ignored.
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/ndis/subr_ntoskrnl.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c
index b2a231b..bcd8e45 100644
--- a/sys/compat/ndis/subr_ntoskrnl.c
+++ b/sys/compat/ndis/subr_ntoskrnl.c
@@ -269,7 +269,11 @@ ntoskrnl_libinit()
mtx_init(&ntoskrnl_calllock, MTX_NTOSKRNL_SPIN_LOCK, NULL, MTX_SPIN);
kq_queues = ExAllocatePoolWithTag(NonPagedPool,
+#ifdef NTOSKRNL_MULTIPLE_DPCS
sizeof(kdpc_queue) * mp_ncpus, 0);
+#else
+ sizeof(kdpc_queue), 0);
+#endif
if (kq_queues == NULL)
return(ENOMEM);
@@ -287,7 +291,11 @@ ntoskrnl_libinit()
* Launch the DPC threads.
*/
+#ifdef NTOSKRNL_MULTIPLE_DPCS
for (i = 0; i < mp_ncpus; i++) {
+#else
+ for (i = 0; i < 1; i++) {
+#endif
kq = kq_queues + i;
kq->kq_cpu = i;
sprintf(name, "Windows DPC %d", i);
@@ -3558,9 +3566,11 @@ ntoskrnl_dpc_thread(arg)
*/
mtx_lock_spin(&sched_lock);
+#ifdef NTOSKRNL_MULTIPLE_DPCS
#if __FreeBSD_version >= 502102
sched_bind(curthread, kq->kq_cpu);
#endif
+#endif
sched_prio(curthread, PRI_MIN_KERN);
#if __FreeBSD_version < 600000
curthread->td_base_pri = PRI_MIN_KERN;
@@ -3611,7 +3621,11 @@ ntoskrnl_destroy_dpc_threads(void)
int i;
kq = kq_queues;
+#ifdef NTOSKRNL_MULTIPLE_DPCS
for (i = 0; i < mp_ncpus; i++) {
+#else
+ for (i = 0; i < 1; i++) {
+#endif
kq += i;
kq->kq_exit = 1;
@@ -3680,6 +3694,9 @@ KeInsertQueueDpc(dpc, sysarg1, sysarg2)
if (dpc == NULL)
return(FALSE);
+ kq = kq_queues;
+
+#ifdef NTOSKRNL_MULTIPLE_DPCS
KeRaiseIrql(DISPATCH_LEVEL, &irql);
/*
@@ -3687,13 +3704,15 @@ KeInsertQueueDpc(dpc, sysarg1, sysarg2)
* that scheduled it.
*/
- kq = kq_queues;
if (dpc->k_num == KDPC_CPU_DEFAULT)
kq += curthread->td_oncpu;
else
kq += dpc->k_num;
-
KeAcquireSpinLockAtDpcLevel(&kq->kq_lock);
+#else
+ KeAcquireSpinLock(&kq->kq_lock, &irql);
+#endif
+
r = ntoskrnl_insert_dpc(&kq->kq_disp, dpc);
if (r == TRUE) {
dpc->k_sysarg1 = sysarg1;
@@ -3719,11 +3738,17 @@ KeRemoveQueueDpc(dpc)
if (dpc == NULL)
return(FALSE);
+#ifdef NTOSKRNL_MULTIPLE_DPCS
KeRaiseIrql(DISPATCH_LEVEL, &irql);
kq = kq_queues + dpc->k_num;
KeAcquireSpinLockAtDpcLevel(&kq->kq_lock);
+#else
+ kq = kq_queues;
+ KeAcquireSpinLock(&kq->kq_lock, &irql);
+#endif
+
if (dpc->k_dpclistentry.nle_flink == &dpc->k_dpclistentry) {
KeReleaseSpinLockFromDpcLevel(&kq->kq_lock);
KeLowerIrql(irql);
@@ -3775,7 +3800,11 @@ KeFlushQueuedDpcs(void)
* for them to drain.
*/
+#ifdef NTOSKRNL_MULTIPLE_DPCS
for (i = 0; i < mp_ncpus; i++) {
+#else
+ for (i = 0; i < 1; i++) {
+#endif
kq = kq_queues + i;
KeSetEvent(&kq->kq_proc, IO_NO_INCREMENT, FALSE);
KeWaitForSingleObject(&kq->kq_done, 0, 0, TRUE, NULL);
OpenPOWER on IntegriCloud