summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_switch.c
diff options
context:
space:
mode:
authorups <ups@FreeBSD.org>2005-04-08 03:37:53 +0000
committerups <ups@FreeBSD.org>2005-04-08 03:37:53 +0000
commit7bac02c1465f16f80ca4f8673c20be951b6922a0 (patch)
tree1dd51e535e839033d7b1c0ba6104fb1725aa3705 /sys/kern/kern_switch.c
parent75973f60359658f053d14347abf7b60eaf3e0122 (diff)
downloadFreeBSD-src-7bac02c1465f16f80ca4f8673c20be951b6922a0.zip
FreeBSD-src-7bac02c1465f16f80ca4f8673c20be951b6922a0.tar.gz
Sprinkle some volatile magic and rearrange things a bit to avoid race
conditions in critical_exit now that it no longer blocks interrupts. Reviewed by: jhb
Diffstat (limited to 'sys/kern/kern_switch.c')
-rw-r--r--sys/kern/kern_switch.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/kern/kern_switch.c b/sys/kern/kern_switch.c
index 707a7f9..421cc31 100644
--- a/sys/kern/kern_switch.c
+++ b/sys/kern/kern_switch.c
@@ -357,7 +357,7 @@ maybe_preempt_in_ksegrp(struct thread *td)
return;
#ifdef PREEMPTION
if (running_thread->td_critnest > 1)
- running_thread->td_pflags |= TDP_OWEPREEMPT;
+ running_thread->td_owepreempt = 1;
else
mi_switch(SW_INVOL, NULL);
@@ -446,7 +446,7 @@ maybe_preempt_in_ksegrp(struct thread *td)
return;
#ifdef PREEMPTION
if (running_thread->td_critnest > 1)
- running_thread->td_pflags |= TDP_OWEPREEMPT;
+ running_thread->td_owepreempt = 1;
else
mi_switch(SW_INVOL, NULL);
@@ -598,15 +598,21 @@ critical_exit(void)
td->td_pflags &= ~TDP_WAKEPROC0;
wakeup(&proc0);
}
+
+ td->td_critnest = 0;
+
#ifdef PREEMPTION
mtx_assert(&sched_lock, MA_NOTOWNED);
- if (td->td_pflags & TDP_OWEPREEMPT) {
+ if (td->td_owepreempt) {
+ td->td_critnest = 1;
mtx_lock_spin(&sched_lock);
+ td->td_critnest--;
mi_switch(SW_INVOL, NULL);
mtx_unlock_spin(&sched_lock);
}
+
#endif
- td->td_critnest = 0;
+
} else {
td->td_critnest--;
}
@@ -672,7 +678,7 @@ maybe_preempt(struct thread *td)
if (ctd->td_critnest > 1) {
CTR1(KTR_PROC, "maybe_preempt: in critical section %d",
ctd->td_critnest);
- ctd->td_pflags |= TDP_OWEPREEMPT;
+ ctd->td_owepreempt = 1;
return (0);
}
OpenPOWER on IntegriCloud