aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-03-30 08:31:16 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-03-30 08:31:16 +0100
commitf17a2b83f791f152d7590e9eb04d2fd20220217c (patch)
tree5db367c48c3bdabbe2d27670e97a64ede1ec3100
parentb1ded68a3c56de12dc2c18978bdf999f25909af3 (diff)
downloadxen-f17a2b83f791f152d7590e9eb04d2fd20220217c.tar.gz
xen-f17a2b83f791f152d7590e9eb04d2fd20220217c.tar.bz2
xen-f17a2b83f791f152d7590e9eb04d2fd20220217c.zip
When flush tlb mask, we need consider the cpu_online_map.
The same is true for EPT flushes. We noticed sometime system hang on cpu online/offline stress test. The reason is because flush_tlb_mask from __get_page_type is deadloop. This should be caused by a small windows in cpu offline. The cpu_online_map is changed and the interrupt is disabled at take_cpu_down() for the to-be-offline CPU. However, the __sync_lazy_execstate() called from idle_task_exit() in the idle_loop() for the to-be-offline CPU. At that time, the stop_machine_run is finished already, and __get_page_type may be called in other CPU before the __sync_lazy_execstate(). Thanks Jan pointing out issue in my original patch. Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c4
-rw-r--r--xen/arch/x86/smp.c3
2 files changed, 5 insertions, 2 deletions
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 62c923a0a7..b54dc8e82c 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -1234,7 +1234,9 @@ void ept_sync_domain(struct domain *d)
* the ept_synced mask before on_selected_cpus() reads it, resulting in
* unnecessary extra flushes, to avoid allocating a cpumask_t on the stack.
*/
- d->arch.hvm_domain.vmx.ept_synced = d->domain_dirty_cpumask;
+ cpus_and(d->arch.hvm_domain.vmx.ept_synced,
+ d->domain_dirty_cpumask, cpu_online_map);
+
on_selected_cpus(&d->arch.hvm_domain.vmx.ept_synced,
__ept_sync_domain, d, 1);
}
diff --git a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c
index b2f1eadfad..2a01923900 100644
--- a/xen/arch/x86/smp.c
+++ b/xen/arch/x86/smp.c
@@ -228,7 +228,8 @@ void flush_area_mask(const cpumask_t *mask, const void *va, unsigned int flags)
if ( !cpus_subset(*mask, *cpumask_of(smp_processor_id())) )
{
spin_lock(&flush_lock);
- cpus_andnot(flush_cpumask, *mask, *cpumask_of(smp_processor_id()));
+ cpus_and(flush_cpumask, *mask, cpu_online_map);
+ cpu_clear(smp_processor_id(), flush_cpumask);
flush_va = va;
flush_flags = flags;
send_IPI_mask(&flush_cpumask, INVALIDATE_TLB_VECTOR);