On 2014-03-07 03:25, Chris Johns wrote:
On 6/03/2014 9:04 pm, Sebastian Huber wrote:
Hello,
there is a potential problem in the SMP initialization procedure.
One processor in the system has a special role, the so called boot
processor. Currently this is the processor with index zero. The way to
select the boot processor may change in the future, but what will not
change is that we have a boot processor.
The boot processors initializes the data and BSS sections. It performs
also the sequential part of the RTEMS initialization.
During the sequential initialization the function
/**
* @brief Performs CPU specific SMP initialization in the context of
the boot
* processor.
*
* This function is invoked on the boot processor by RTEMS during
* initialization. All interrupt stacks are allocated at this point in
case
* the CPU port allocates the interrupt stacks.
*
* The CPU port should start secondary processors now.
*
* @param[in] configured_cpu_count The count of processors requested by
the
* application configuration.
*
* @return The count of processors available for the application in the
system.
* This value is less than or equal to the configured count of processors.
*/
uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
called. This function is currently implemented by the BSPs. An example
which starts the processor on its own:
http://git.rtems.org/rtems/tree/c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c#n38
An example which uses U-Boot to start the second processor:
http://git.rtems.org/rtems/tree/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c#n144
The return value of _CPU_SMP_Initialize() will tell the RTEMS system how
many processors are present.
void _SMP_Handler_initialize( void )
{
uint32_t max_cpus = rtems_configuration_get_maximum_processors();
uint32_t cpu;
[...]
/*
* Discover and initialize the secondary cores in an SMP system.
*/
max_cpus = _CPU_SMP_Initialize( max_cpus );
_SMP_Processor_count = max_cpus;
}
If the BSP says "you have three processors", and one of them is actually
not available, then we have a problem later.
Before the system starts multitasking there is a synchronization
barrier. This synchronization barrier is necessary to have a defined
starting point for the scheduler.
Just to be clear here I assume this means when the scheduler starts the defined
resources are present and there is no degraded mode to be supported by RTEMS.
Getting the processors to the same point means the application can assume a
specific runtime scheduling profile from the start. What happens after this is
the application's problem and RTEMS makes no further checks. It also means
RTEMS cannot be started with cores in a powered down state and enable them on
demand at the application level.
Yes, exactly.
[...]
I am in favor of 1. in combination with 2.1 and 2.2.2.2. For BSPs with
unreliably start of secondary processors we should add a support
function, e.g.
/**
* @brief Waits for all other processors to enter the ready to start
* multitasking state with a timeout in microseconds.
*
* In case one processor enters the shutdown state, this function does not
* return.
*
* This function should be called only in _CPU_SMP_Initialize() if
required by
* the CPU port or BSP.
*
* @param[in] processor_count The processor count which will later
returned by
* _CPU_SMP_Initialize().
* @param[in] timeout_in_us The timeout in microseconds.
*
* @retval true All other processors entered the ready to start
multitasking
* state.
* @retval false Not all the other processors entered the ready to start
* multitasking state and the timeout expired.
*/
bool _Per_CPU_State_wait_for_ready_to_start_multitasking(
uint32_t processor_count,
uint32_t timeout_in_us
);
This avoids the burden for the application developer to know about the
timeout configuration option and to select a proper value.
+1
It moves the
responsibility to deal with issue to the BSP which knows best what to
do. In case false is returned it can either issue a fatal error or
reduce the processor count.
Can I assume the BSP can use a call to see which cores are present and which
are not, eg state of a cpu ? Peeking the per CPU struct is not a good idea.
The approach seems reasonable.
Chris
Please have a look at the attached patch.
--
Sebastian Huber, embedded brains GmbH
Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail : sebastian.hu...@embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
>From 79ac410ac739472316e823cb360408388d0a6cad Mon Sep 17 00:00:00 2001
From: Sebastian Huber <sebastian.hu...@embedded-brains.de>
Date: Thu, 6 Mar 2014 11:11:59 +0100
Subject: [PATCH] score: Add per-CPU state function
Add _Per_CPU_State_wait_for_ready_to_start_multitasking(). Add new
fatal SMP error SMP_FATAL_SHUTDOWN_EARLY.
---
cpukit/score/include/rtems/score/percpu.h | 39 ++++++++++++++++++++++++++++
cpukit/score/include/rtems/score/smpimpl.h | 3 +-
2 files changed, 41 insertions(+), 1 deletions(-)
diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h
index 4b7fd62..1fd4fa3 100644
--- a/cpukit/score/include/rtems/score/percpu.h
+++ b/cpukit/score/include/rtems/score/percpu.h
@@ -337,6 +337,45 @@ void _Per_CPU_State_change(
Per_CPU_State new_state
);
+/**
+ * @brief Waits for all other processors to enter the ready to start
+ * multitasking state with a timeout in microseconds.
+ *
+ * In case one processor enters the shutdown state, this function does not
+ * return and terminates the system with the SMP_FATAL_SHUTDOWN_EARLY fatal SMP
+ * error.
+ *
+ * This function should be called only in _CPU_SMP_Initialize() if required by
+ * the CPU port or BSP.
+ *
+ * @code
+ * uint32_t _CPU_SMP_Initialize(uint32_t configured_cpu_count)
+ * {
+ * uint32_t cnt = MIN(get_hardware_cpu_count(), configured_cpu_count);
+ * uint32_t timeout = 123456;
+ *
+ * do_some_stuff();
+ *
+ * return _Per_CPU_State_wait_for_ready_to_start_multitasking(cnt, timeout);
+ * }
+ * @endcode
+ *
+ * In case the timeout expires the count of processors is reduced to reflect
+ * the set of processors which is actually available at this point in time.
+ *
+ * @param[in] processor_count The processor count is the minimum value of the
+ * configured count of processors and the processor count offered by the actual
+ * hardware.
+ * @param[in] timeout_in_us The timeout in microseconds.
+ *
+ * @return The count of processors available for the application in the system.
+ * This value is less than or equal to the processor count.
+ */
+uint32_t _Per_CPU_State_wait_for_ready_to_start_multitasking(
+ uint32_t processor_count,
+ uint32_t timeout_in_us
+);
+
#endif /* defined( RTEMS_SMP ) */
/*
diff --git a/cpukit/score/include/rtems/score/smpimpl.h b/cpukit/score/include/rtems/score/smpimpl.h
index da08cf5..6c74e7b 100644
--- a/cpukit/score/include/rtems/score/smpimpl.h
+++ b/cpukit/score/include/rtems/score/smpimpl.h
@@ -47,7 +47,8 @@ extern "C" {
* @brief SMP fatal codes.
*/
typedef enum {
- SMP_FATAL_SHUTDOWN
+ SMP_FATAL_SHUTDOWN,
+ SMP_FATAL_SHUTDOWN_EARLY
} SMP_Fatal_code;
/**
--
1.7.7
_______________________________________________
rtems-devel mailing list
rtems-devel@rtems.org
http://www.rtems.org/mailman/listinfo/rtems-devel