From: Antonio Huete Jimenez Date: Mon, 17 Oct 2011 19:26:22 +0000 (-0700) Subject: pmap - Missing critical section when calling lwkt_ipiq_process(). X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/db39668bd529972dc154be070b57f398dfe94449 pmap - Missing critical section when calling lwkt_ipiq_process(). - 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: Reviewed by: @dillon, @vsrinivas --- diff --git a/sys/platform/pc32/i386/pmap.c b/sys/platform/pc32/i386/pmap.c index 3bb09b8438..f7c79218ec 100644 --- a/sys/platform/pc32/i386/pmap.c +++ b/sys/platform/pc32/i386/pmap.c @@ -3489,11 +3489,12 @@ 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(); } } diff --git a/sys/platform/pc64/x86_64/pmap.c b/sys/platform/pc64/x86_64/pmap.c index 1f2a59f9d4..ac06c70459 100644 --- a/sys/platform/pc64/x86_64/pmap.c +++ b/sys/platform/pc64/x86_64/pmap.c @@ -3876,7 +3876,13 @@ pmap_setlwpvm(struct lwp *lp, struct vmspace *newvm) #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) @@ -3885,11 +3891,12 @@ 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(); } }