[PATCH 06/17] score: Move _SMP_Request_other_cores_to_shutdown()

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Feb 17 15:51:31 UTC 2014


Move _SMP_Request_other_cores_to_shutdown() invocation from
rtems_shutdown_executive() to _Internal_error_Occurred() to allow a
proper shutdown on SMP configurations even in the error case.
---
 cpukit/sapi/src/exshutdown.c              |    8 --------
 cpukit/score/include/rtems/score/interr.h |    5 ++++-
 cpukit/score/include/rtems/score/smp.h    |   11 ++++++++---
 cpukit/score/src/interr.c                 |    3 +++
 cpukit/score/src/smp.c                    |   22 ++++++++++++++--------
 5 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/cpukit/sapi/src/exshutdown.c b/cpukit/sapi/src/exshutdown.c
index 41ee537..80848f0 100644
--- a/cpukit/sapi/src/exshutdown.c
+++ b/cpukit/sapi/src/exshutdown.c
@@ -17,10 +17,6 @@
 #include <rtems/score/sysstate.h>
 #include <rtems/score/interr.h>
 
-#if defined(RTEMS_SMP)
-  #include <rtems/score/smp.h>
-#endif
-
 void rtems_shutdown_executive( uint32_t result )
 {
   Internal_errors_Source  source;
@@ -28,10 +24,6 @@ void rtems_shutdown_executive( uint32_t result )
   Internal_errors_t       code;
 
   if ( _System_state_Is_up( _System_state_Get() ) ) {
-    #if defined(RTEMS_SMP)
-      _SMP_Request_other_cores_to_shutdown();
-    #endif
-
     source      = RTEMS_FATAL_SOURCE_EXIT;
     is_internal = false;
     code        = result;
diff --git a/cpukit/score/include/rtems/score/interr.h b/cpukit/score/include/rtems/score/interr.h
index 87abc7a..26fe154 100644
--- a/cpukit/score/include/rtems/score/interr.h
+++ b/cpukit/score/include/rtems/score/interr.h
@@ -186,7 +186,10 @@ extern Internal_errors_Information _Internal_errors_What_happened;
  * - valid read-only data.
  *
  * For the initial extensions the read-write data (including BSS segment) is
- * not required.
+ * not required on single processor configurations.  On SMP configurations
+ * however the read-write data must be initialized since this function must
+ * determine the state of the other processors and request them to shut-down if
+ * necessary.
  *
  * Non-initial extensions require in addition valid read-write data.  The BSP
  * may install an initial extension that performs a system reset.  In this case
diff --git a/cpukit/score/include/rtems/score/smp.h b/cpukit/score/include/rtems/score/smp.h
index 2fd9150..b97cced 100644
--- a/cpukit/score/include/rtems/score/smp.h
+++ b/cpukit/score/include/rtems/score/smp.h
@@ -88,14 +88,19 @@ void _SMP_Broadcast_message(
  */
 void _SMP_Request_other_cores_to_perform_first_context_switch(void);
 
+#endif /* defined( RTEMS_SMP ) */
+
 /**
  *  @brief Request other cores to shutdown.
  *
  *  Send message to other cores requesting them to shutdown.
  */
-void _SMP_Request_other_cores_to_shutdown(void);
-
-#endif /* defined( RTEMS_SMP ) */
+#if defined( RTEMS_SMP )
+  void _SMP_Request_other_cores_to_shutdown( void );
+#else
+  #define _SMP_Request_other_cores_to_shutdown() \
+    do { } while ( 0 )
+#endif
 
 #endif /* !defined( ASM ) */
 
diff --git a/cpukit/score/src/interr.c b/cpukit/score/src/interr.c
index 38ac455..d00a032 100644
--- a/cpukit/score/src/interr.c
+++ b/cpukit/score/src/interr.c
@@ -20,6 +20,7 @@
 
 #include <rtems/score/interr.h>
 #include <rtems/score/isrlevel.h>
+#include <rtems/score/smp.h>
 #include <rtems/score/sysstate.h>
 #include <rtems/score/userextimpl.h>
 
@@ -38,6 +39,8 @@ void _Internal_error_Occurred(
   _ISR_Disable( level );
   (void) level;
 
+  _SMP_Request_other_cores_to_shutdown();
+
   _User_extensions_Fatal( the_source, is_internal, the_error );
 
   _Internal_errors_What_happened.the_source  = the_source;
diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c
index df1c6d3..50ebc13 100644
--- a/cpukit/score/src/smp.c
+++ b/cpukit/score/src/smp.c
@@ -22,7 +22,7 @@
 #include <rtems/score/threaddispatch.h>
 #include <rtems/score/threadimpl.h>
 #include <rtems/score/smp.h>
-#include <rtems/score/sysstate.h>
+#include <rtems/config.h>
 
 #if defined(RTEMS_DEBUG)
   #include <rtems/bspIo.h>
@@ -137,17 +137,23 @@ void _SMP_Request_other_cores_to_perform_first_context_switch( void )
 void _SMP_Request_other_cores_to_shutdown( void )
 {
   uint32_t self = _SMP_Get_current_processor();
-  uint32_t ncpus = _SMP_Get_processor_count();
-  uint32_t cpu;
 
-  _SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );
+  /*
+   * Do not use _SMP_Get_processor_count() since this value might be not
+   * initialized yet.  For example due to a fatal error in the middle of
+   * bsp_smp_initialize().
+   */
+  uint32_t ncpus = rtems_configuration_get_maximum_processors();
+
+  uint32_t cpu;
 
   for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
     if ( cpu != self ) {
-      _Per_CPU_Wait_for_state(
-        _Per_CPU_Get_by_index( cpu ),
-        PER_CPU_STATE_SHUTDOWN
-      );
+      const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
+
+      if ( per_cpu->state != PER_CPU_STATE_BEFORE_INITIALIZATION ) {
+        _SMP_Send_message( cpu, RTEMS_BSP_SMP_SHUTDOWN );
+      }
     }
   }
 }
-- 
1.7.7




More information about the devel mailing list