[PATCH] SMP: Fix start multitasking for some targets

Kinsey Moore kinsey.moore at oarcorp.com
Tue Mar 8 20:30:48 UTC 2022


The AArch64 changes look reasonable and resolve the bug I observed in 
both the test case you provided as well as the test where I initially 
discovered it.


Thanks,

Kinsey

On 3/8/2022 12:28, Sebastian Huber wrote:
> The previous SMP multitasking start assumed that the initial heir thread of a
> processor starts execution in _Thread_Handler().  The _Thread_Handler() sets
> the interrupt state explicitly by _ISR_Set_level() before it calls the thread
> entry.  Under certain timing conditions, processors may perform an initial
> context switch to a thread which already executes its thread body (see
> smptests/smpstart01).  In this case, interrupts are disabled after the context
> switch on targets which do not save/restore the interrupt state during a
> context switch (aarch64, arm, and riscv).
>
> Close #4627.
> ---
>   cpukit/score/cpu/aarch64/cpu_asm.S              | 17 +++++++++++++++++
>   .../score/cpu/aarch64/include/rtems/score/cpu.h |  4 ++++
>   cpukit/score/cpu/arm/cpu_asm.S                  | 12 ++++++++++++
>   cpukit/score/cpu/arm/include/rtems/score/cpu.h  |  4 ++++
>   .../score/cpu/riscv/include/rtems/score/cpu.h   |  4 ++++
>   cpukit/score/cpu/riscv/riscv-context-switch.S   | 15 +++++++++++++++
>   cpukit/score/src/threadstartmultitasking.c      |  3 +++
>   7 files changed, 59 insertions(+)
>
> diff --git a/cpukit/score/cpu/aarch64/cpu_asm.S b/cpukit/score/cpu/aarch64/cpu_asm.S
> index 2379698336..6321acde90 100644
> --- a/cpukit/score/cpu/aarch64/cpu_asm.S
> +++ b/cpukit/score/cpu/aarch64/cpu_asm.S
> @@ -202,5 +202,22 @@ DEFINE_FUNCTION_AARCH64(_CPU_Context_restore)
>   	str	x5, [x2, #PER_CPU_OFFSET_EXECUTING]
>   #endif
>   
> +	b	.L_check_is_executing
> +
> +DEFINE_FUNCTION_AARCH64(_AArch64_Start_multitasking)
> +#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
> +	/* Sanitize input for ILP32 ABI */
> +	mov	w0, w0
> +#endif
> +
> +	mov	x1, x0
> +	GET_SELF_CPU_CONTROL	reg_2
> +
> +	/* Switch the stack to the temporary interrupt stack of this processor */
> +	add	sp, x2, #(PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE)
> +
> +	/* Enable interrupts */
> +	msr	DAIFClr, #0x2
> +
>   	b	.L_check_is_executing
>   #endif
> diff --git a/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h b/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h
> index e1d9f0a5c2..fdc0e3d929 100644
> --- a/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h
> +++ b/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h
> @@ -285,6 +285,10 @@ void _CPU_Context_Initialize(
>     {
>       context->is_executing = is_executing;
>     }
> +
> +  RTEMS_NO_RETURN void _AArch64_Start_multitasking( Context_Control *heir );
> +
> +  #define _CPU_Start_multitasking( _heir ) _AArch64_Start_multitasking( _heir )
>   #endif
>   
>   #define _CPU_Context_Restart_self( _the_context ) \
> diff --git a/cpukit/score/cpu/arm/cpu_asm.S b/cpukit/score/cpu/arm/cpu_asm.S
> index 54d6f70b0d..d52a43f70d 100644
> --- a/cpukit/score/cpu/arm/cpu_asm.S
> +++ b/cpukit/score/cpu/arm/cpu_asm.S
> @@ -181,6 +181,18 @@ DEFINE_FUNCTION_ARM(_CPU_Context_restore)
>   	/* Update the executing */
>   	str	r5, [r2, #PER_CPU_OFFSET_EXECUTING]
>   
> +	b	.L_check_is_executing
> +
> +DEFINE_FUNCTION_ARM(_ARM_Start_multitasking)
> +	mov	r1, r0
> +	GET_SELF_CPU_CONTROL	r2
> +
> +	/* Switch the stack to the temporary interrupt stack of this processor */
> +	add	sp, r2, #(PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE)
> +
> +	/* Enable IRQ interrupts */
> +	cpsie	i
> +
>   	b	.L_check_is_executing
>   #endif
>   
> diff --git a/cpukit/score/cpu/arm/include/rtems/score/cpu.h b/cpukit/score/cpu/arm/include/rtems/score/cpu.h
> index da521528a4..7ac180ac26 100644
> --- a/cpukit/score/cpu/arm/include/rtems/score/cpu.h
> +++ b/cpukit/score/cpu/arm/include/rtems/score/cpu.h
> @@ -443,6 +443,10 @@ void _CPU_Context_Initialize(
>     {
>       context->is_executing = is_executing;
>     }
> +
> +  RTEMS_NO_RETURN void _ARM_Start_multitasking( Context_Control *heir );
> +
> +  #define _CPU_Start_multitasking( _heir ) _ARM_Start_multitasking( _heir )
>   #endif
>   
>   #define _CPU_Context_Restart_self( _the_context ) \
> diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
> index 05ef2709ba..471c6c6c3e 100644
> --- a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
> +++ b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
> @@ -509,6 +509,10 @@ static inline void _CPU_Context_Set_is_executing(
>     context->is_executing = is_executing;
>   }
>   
> +RTEMS_NO_RETURN void _RISCV_Start_multitasking( Context_Control *heir );
> +
> +#define _CPU_Start_multitasking( _heir ) _RISCV_Start_multitasking( _heir )
> +
>   #endif /* RTEMS_SMP */
>   
>   /** Type that can store a 32-bit integer or a pointer. */
> diff --git a/cpukit/score/cpu/riscv/riscv-context-switch.S b/cpukit/score/cpu/riscv/riscv-context-switch.S
> index 3c0368886e..cfaff444b0 100644
> --- a/cpukit/score/cpu/riscv/riscv-context-switch.S
> +++ b/cpukit/score/cpu/riscv/riscv-context-switch.S
> @@ -40,6 +40,9 @@
>   PUBLIC(_CPU_Context_switch)
>   PUBLIC(_CPU_Context_switch_no_return)
>   PUBLIC(_CPU_Context_restore)
> +#ifdef RTEMS_SMP
> +PUBLIC(_RISCV_Start_multitasking)
> +#endif
>   
>   SYM(_CPU_Context_switch):
>   SYM(_CPU_Context_switch_no_return):
> @@ -174,5 +177,17 @@ SYM(_CPU_Context_restore):
>   	/* Update the executing */
>   	sw	a5, PER_CPU_OFFSET_EXECUTING(a2)
>   
> +	j	.Ltry_update_is_executing
> +
> +SYM(_RISCV_Start_multitasking):
> +	mv	a1, a0
> +	GET_SELF_CPU_CONTROL	a2
> +
> +	/* Switch the stack to the temporary interrupt stack of this processor */
> +	addi	sp, a2, PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE
> +
> +	/* Enable interrupts */
> +	csrrs	zero, mstatus, RISCV_MSTATUS_MIE
> +
>   	j	.Ltry_update_is_executing
>   #endif
> diff --git a/cpukit/score/src/threadstartmultitasking.c b/cpukit/score/src/threadstartmultitasking.c
> index 5cc2051be4..d97d2e0c82 100644
> --- a/cpukit/score/src/threadstartmultitasking.c
> +++ b/cpukit/score/src/threadstartmultitasking.c
> @@ -64,6 +64,9 @@ void _Thread_Start_multitasking( void )
>   #if defined(_CPU_Start_multitasking)
>     _CPU_Start_multitasking( &heir->Registers );
>   #elif defined(RTEMS_SMP)
> +#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
> +#error "The CPU port has to provide _CPU_Start_multitasking()"
> +#endif
>     {
>       Context_Control trash;
>   


More information about the devel mailing list