[PATCH 06/18] score: Simplify _SMP_Multicast_action()

Sebastian Huber sebastian.huber at embedded-brains.de
Mon May 20 07:33:32 UTC 2019


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 <rtems/score/smpimpl.h>
+#include <rtems/score/threaddispatch.h>
 #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 <rtems/score/smpimpl.h>
 #include <rtems/score/assert.h>
-#include <rtems/score/threaddispatch.h>
 
 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);
-- 
2.16.4



More information about the devel mailing list