[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Fix flush_area_mask() and on_selected_cpus() to not race updates
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1243502355 -3600 # Node ID 0e111bfd22d06ee0f05baedabc7928c3dfaf4c0a # Parent e95c4611a0ae38eadcc29268ac7f5e39457b651e x86: Fix flush_area_mask() and on_selected_cpus() to not race updates of the supplied cpumask (which is now passed by reference). Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/smp.c | 68 +++++++++++++++++++++++++---------------------------- 1 files changed, 33 insertions(+), 35 deletions(-) diff -r e95c4611a0ae -r 0e111bfd22d0 xen/arch/x86/smp.c --- a/xen/arch/x86/smp.c Thu May 28 10:06:01 2009 +0100 +++ b/xen/arch/x86/smp.c Thu May 28 10:19:15 2009 +0100 @@ -192,7 +192,7 @@ void flush_area_mask(const cpumask_t *ma cpus_andnot(flush_cpumask, *mask, *cpumask_of(smp_processor_id())); flush_va = va; flush_flags = flags; - send_IPI_mask(mask, INVALIDATE_TLB_VECTOR); + send_IPI_mask(&flush_cpumask, INVALIDATE_TLB_VECTOR); while ( !cpus_empty(flush_cpumask) ) cpu_relax(); spin_unlock(&flush_lock); @@ -223,18 +223,16 @@ void smp_send_event_check_mask(const cpu * Structure and data for smp_call_function()/on_selected_cpus(). */ -struct call_data_struct { +static void __smp_call_function_interrupt(void); +static DEFINE_SPINLOCK(call_lock); +static struct call_data_struct { void (*func) (void *info); void *info; int wait; atomic_t started; atomic_t finished; - const cpumask_t *selected; -}; - -static DEFINE_SPINLOCK(call_lock); -static struct call_data_struct *call_data; -static void __smp_call_function_interrupt(void); + cpumask_t selected; +} call_data; int smp_call_function( void (*func) (void *info), @@ -252,39 +250,39 @@ int on_selected_cpus( void *info, int wait) { - struct call_data_struct data; - unsigned int nr_cpus = cpus_weight(*selected); + unsigned int nr_cpus; ASSERT(local_irq_is_enabled()); + spin_lock(&call_lock); + + call_data.selected = *selected; + + nr_cpus = cpus_weight(call_data.selected); if ( nr_cpus == 0 ) - return 0; - - data.func = func; - data.info = info; - data.wait = wait; - atomic_set(&data.started, 0); - atomic_set(&data.finished, 0); - data.selected = selected; - - spin_lock(&call_lock); - - call_data = &data; - - send_IPI_mask(selected, CALL_FUNCTION_VECTOR); - - if ( cpu_isset(smp_processor_id(), *call_data->selected) ) + goto out; + + call_data.func = func; + call_data.info = info; + call_data.wait = wait; + atomic_set(&call_data.started, 0); + atomic_set(&call_data.finished, 0); + + send_IPI_mask(&call_data.selected, CALL_FUNCTION_VECTOR); + + if ( cpu_isset(smp_processor_id(), call_data.selected) ) { local_irq_disable(); __smp_call_function_interrupt(); local_irq_enable(); } - while ( atomic_read(wait ? &data.finished : &data.started) != nr_cpus ) + while ( atomic_read(wait ? &call_data.finished : &call_data.started) + != nr_cpus ) cpu_relax(); + out: spin_unlock(&call_lock); - return 0; } @@ -345,24 +343,24 @@ fastcall void smp_event_check_interrupt( static void __smp_call_function_interrupt(void) { - void (*func)(void *info) = call_data->func; - void *info = call_data->info; - - if ( !cpu_isset(smp_processor_id(), *call_data->selected) ) + void (*func)(void *info) = call_data.func; + void *info = call_data.info; + + if ( !cpu_isset(smp_processor_id(), call_data.selected) ) return; irq_enter(); - if ( call_data->wait ) + if ( call_data.wait ) { (*func)(info); mb(); - atomic_inc(&call_data->finished); + atomic_inc(&call_data.finished); } else { mb(); - atomic_inc(&call_data->started); + atomic_inc(&call_data.started); (*func)(info); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |