From 3b2481f9a7c7e9926b221acdca3678d80c6c9ec7 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 18 Apr 2019 07:08:32 +0200 Subject: score: Simplify _SMP_Multicast_action() Move resposibility to disable thread dispatching to the caller of _SMP_Multicast_action(). Using an interrupt disable for this purpose is questionable. --- bsps/shared/cache/cacheimpl.h | 25 +++++++++++++++++++++++-- cpukit/include/rtems/score/smpimpl.h | 8 +++++--- cpukit/score/src/smpmulticastaction.c | 25 +++++-------------------- testsuites/smptests/smpmulticast01/init.c | 14 ++++---------- 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/bsps/shared/cache/cacheimpl.h b/bsps/shared/cache/cacheimpl.h index a91230d22a..42ccdc14a7 100644 --- a/bsps/shared/cache/cacheimpl.h +++ b/bsps/shared/cache/cacheimpl.h @@ -85,6 +85,7 @@ #if defined(RTEMS_SMP) && defined(CPU_CACHE_NO_INSTRUCTION_CACHE_SNOOPING) #include +#include #endif #if CPU_DATA_CACHE_ALIGNMENT > CPU_CACHE_LINE_BYTES @@ -283,6 +284,26 @@ static void smp_cache_inst_inv_all(void *arg) _CPU_cache_invalidate_entire_instruction(); } +static void smp_cache_broadcast( SMP_Action_handler handler, void *arg ) +{ + uint32_t isr_level; + Per_CPU_Control *cpu_self; + + isr_level = _ISR_Get_level(); + + if ( isr_level == 0 ) { + cpu_self = _Thread_Dispatch_disable(); + } else { + cpu_self = _Per_CPU_Get(); + } + + _SMP_Broadcast_action( handler, arg ); + + if ( isr_level == 0 ) { + _Thread_Dispatch_enable( cpu_self ); + } +} + #endif /* @@ -329,7 +350,7 @@ rtems_cache_invalidate_multiple_instruction_lines( #if defined(RTEMS_SMP) && defined(CPU_CACHE_NO_INSTRUCTION_CACHE_SNOOPING) smp_cache_area area = { i_addr, n_bytes }; - _SMP_Broadcast_action( smp_cache_inst_inv, &area ); + smp_cache_broadcast( smp_cache_inst_inv, &area ); #else _CPU_cache_invalidate_instruction_range( i_addr, n_bytes ); #endif @@ -345,7 +366,7 @@ rtems_cache_invalidate_entire_instruction( void ) { #if defined(CPU_INSTRUCTION_CACHE_ALIGNMENT) #if defined(RTEMS_SMP) && defined(CPU_CACHE_NO_INSTRUCTION_CACHE_SNOOPING) - _SMP_Broadcast_action( smp_cache_inst_inv_all, NULL ); + smp_cache_broadcast( smp_cache_inst_inv_all, NULL ); #else _CPU_cache_invalidate_entire_instruction(); #endif diff --git a/cpukit/include/rtems/score/smpimpl.h b/cpukit/include/rtems/score/smpimpl.h index 452f39a3b5..ecea1fda43 100644 --- a/cpukit/include/rtems/score/smpimpl.h +++ b/cpukit/include/rtems/score/smpimpl.h @@ -255,9 +255,11 @@ typedef void ( *SMP_Action_handler )( void *arg ); /** * @brief Initiates an SMP multicast action to the set of target processors. * - * The current processor may be part of the set. In case a target processor is - * in a wrong state to process per-processor jobs, then this function results - * in an SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS fatal SMP error. + * The current processor may be part of the set. The caller must ensure that + * no thread dispatch can happen during the call of this function, otherwise + * the behaviour is undefined. In case a target processor is in a wrong state + * to process per-processor jobs, then this function results in an + * SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS fatal SMP error. * * @param targets The set of target processors for the action. * @param handler The multicast action handler. diff --git a/cpukit/score/src/smpmulticastaction.c b/cpukit/score/src/smpmulticastaction.c index f7dd503fae..a525289842 100644 --- a/cpukit/score/src/smpmulticastaction.c +++ b/cpukit/score/src/smpmulticastaction.c @@ -31,7 +31,6 @@ #include #include -#include typedef struct Per_CPU_Job Per_CPU_Job; @@ -178,8 +177,7 @@ static void _SMP_Issue_action_jobs( static void _SMP_Wait_for_action_jobs( const Processor_mask *targets, const Per_CPU_Jobs *jobs, - uint32_t cpu_max, - Per_CPU_Control *cpu_self + uint32_t cpu_max ) { uint32_t cpu_index; @@ -208,7 +206,7 @@ static void _SMP_Wait_for_action_jobs( * We have to perform our own jobs here in case inter-processor * interrupts are not working. */ - _Per_CPU_Try_perform_jobs( cpu_self ); + _Per_CPU_Try_perform_jobs( _Per_CPU_Get() ); break; default: _SMP_Fatal( SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS ); @@ -225,30 +223,17 @@ void _SMP_Multicast_action( void *arg ) { - Per_CPU_Jobs jobs; - uint32_t cpu_max; - Per_CPU_Control *cpu_self; - uint32_t isr_level; + Per_CPU_Jobs jobs; + uint32_t cpu_max; cpu_max = _SMP_Get_processor_maximum(); _Assert( cpu_max <= CPU_MAXIMUM_PROCESSORS ); jobs.handler = handler; jobs.arg = arg; - isr_level = _ISR_Get_level(); - - if ( isr_level == 0 ) { - cpu_self = _Thread_Dispatch_disable(); - } else { - cpu_self = _Per_CPU_Get(); - } _SMP_Issue_action_jobs( targets, &jobs, cpu_max ); - _SMP_Wait_for_action_jobs( targets, &jobs, cpu_max, cpu_self ); - - if ( isr_level == 0 ) { - _Thread_Dispatch_enable( cpu_self ); - } + _SMP_Wait_for_action_jobs( targets, &jobs, cpu_max ); } void _SMP_Broadcast_action( diff --git a/testsuites/smptests/smpmulticast01/init.c b/testsuites/smptests/smpmulticast01/init.c index 7b2556d5e9..5f10400ce6 100644 --- a/testsuites/smptests/smpmulticast01/init.c +++ b/testsuites/smptests/smpmulticast01/init.c @@ -227,8 +227,12 @@ static void test_broadcast_body( ctx = (test_context *) base; while (!rtems_test_parallel_stop_job(&ctx->base)) { + Per_CPU_Control *cpu_self; + clear_ids_by_worker(ctx, worker_index); + cpu_self = _Thread_Dispatch_disable(); _SMP_Multicast_action(NULL, action, &ctx->id[worker_index][0]); + _Thread_Dispatch_enable(cpu_self); } } @@ -347,11 +351,6 @@ static void test_wrong_cpu_state_to_perform_jobs(void) rtems_fatal(RTEMS_FATAL_SOURCE_APPLICATION, 0); } -T_TEST_CASE(UnicastDuringMultitasking) -{ - test_unicast(&test_instance, _SMP_Multicast_action); -} - T_TEST_CASE(UnicastDuringMultitaskingIRQDisabled) { test_unicast(&test_instance, multicast_action_irq_disabled); @@ -362,11 +361,6 @@ T_TEST_CASE(UnicastDuringMultitaskingDispatchDisabled) test_unicast(&test_instance, multicast_action_dispatch_disabled); } -T_TEST_CASE(BroadcastDuringMultitasking) -{ - test_broadcast(&test_instance, _SMP_Broadcast_action); -} - T_TEST_CASE(BroadcastDuringMultitaskingIRQDisabled) { test_broadcast(&test_instance, broadcast_action_irq_disabled); -- cgit v1.2.3