- pmap_interlock_wait() explicitly calls lwkt_process_ipiq() which expects to
be in a critical section. We still need cpu_ccfence() to guarantee that
pmap->pm_active is always read inside the loop.
- Sync pmap_interlock_wait's comment for both i386 and x86_64.
DragonFly-bug: <http://bugs.dragonflybsd.org/issue2152>
Reviewed by: @dillon, @vsrinivas
if (pmap->pm_active & CPUMASK_LOCK) {
DEBUG_PUSH_INFO("pmap_interlock_wait");
+ crit_enter();
while (pmap->pm_active & CPUMASK_LOCK) {
- cpu_pause();
cpu_ccfence();
lwkt_process_ipiq();
}
+ crit_exit();
DEBUG_POP_INFO();
}
}
#ifdef SMP
/*
- * Called when switching to a locked pmap
+ * Called when switching to a locked pmap, used to interlock against pmaps
+ * undergoing modifications to prevent us from activating the MMU for the
+ * target pmap until all such modifications have completed. We have to do
+ * this because the thread making the modifications has already set up its
+ * SMP synchronization mask.
+ *
+ * No requirements.
*/
void
pmap_interlock_wait(struct vmspace *vm)
if (pmap->pm_active & CPUMASK_LOCK) {
DEBUG_PUSH_INFO("pmap_interlock_wait");
+ crit_enter();
while (pmap->pm_active & CPUMASK_LOCK) {
- cpu_pause();
cpu_ccfence();
lwkt_process_ipiq();
}
+ crit_exit();
DEBUG_POP_INFO();
}
}