aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/smp.c
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 /xen/arch/x86/smp.c
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>
Diffstat (limited to 'xen/arch/x86/smp.c')
-rw-r--r--xen/arch/x86/smp.c3
1 files changed, 2 insertions, 1 deletions
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);