[RTEMS Project] #3885: Context switch extension is broken in SMP configurations

RTEMS trac trac at rtems.org
Wed Feb 26 08:51:14 UTC 2020


#3885: Context switch extension is broken in SMP configurations
-----------------------------+------------------------------
 Reporter:  Sebastian Huber  |       Owner:  Sebastian Huber
     Type:  defect           |      Status:  assigned
 Priority:  normal           |   Milestone:  5.1
Component:  score            |     Version:  5
 Severity:  normal           |  Resolution:
 Keywords:                   |  Blocked By:
 Blocking:                   |
-----------------------------+------------------------------
Description changed by Sebastian Huber:

Old description:

> The context switch extensions are called during _Thread_Do_dispatch():
> {{{
> #!c
> void _Thread_Do_dispatch( Per_CPU_Control *cpu_self, ISR_Level level )
> {
>   Thread_Control *executing;
>
>   executing = cpu_self->executing;
>
>   ...
>   do {
>     Thread_Control *heir;
>
>     heir = _Thread_Get_heir_and_make_it_executing( cpu_self );
>     ...
>     _User_extensions_Thread_switch( executing, heir );
>     ...
>     _Context_Switch( &executing->Registers, &heir->Registers );
>     ...
>   } while ( cpu_self->dispatch_necessary );
>   ...
> }
> }}}
> In uniprocessor configurations, the context switch extensions are called
> for all thread switches except the very first thread switch to the
> initialization thread. However, in SMP configurations, the context switch
> may be invalidated and updated in the low-level _Context_Switch()
> routine. See:
>
> https://docs.rtems.org/branches/master/c-user/symmetric_multiprocessing_services.html
> #thread-dispatch-details
>
> In case such an update happens, a thread executes on the processor which
> was not visible to the context switch extensions. This can confuse for
> example event record consumers which use events generated by a context
> switch extension.
>
> Fixing this is not straight forward. The context switch extensions call
> must move after the low-level context switch. The problem here is that we
> may end up in _Thread_Handler(). Adding the context switch extensions
> call to _Thread_Handler() covers now also the thread switch to the
> initialization thread. We also have to save the last executing thread of
> the processor. Registers or the stack cannot be used for this purpose. We
> have to add it to the per-processor information. Existing extensions may
> be affected, since now context switch extensions use the stack of the
> heir thread.

New description:

 The context switch extensions are called during _Thread_Do_dispatch():
 {{{
 #!c
 void _Thread_Do_dispatch( Per_CPU_Control *cpu_self, ISR_Level level )
 {
   Thread_Control *executing;

   executing = cpu_self->executing;

   ...
   do {
     Thread_Control *heir;

     heir = _Thread_Get_heir_and_make_it_executing( cpu_self );
     ...
     _User_extensions_Thread_switch( executing, heir );
     ...
     _Context_Switch( &executing->Registers, &heir->Registers );
     ...
   } while ( cpu_self->dispatch_necessary );
   ...
 }
 }}}
 In uniprocessor configurations, the context switch extensions are called
 for all thread switches except the very first thread switch to the
 initialization thread. However, in SMP configurations, the context switch
 may be invalidated and updated in the low-level _Context_Switch() routine.
 See:

 https://docs.rtems.org/branches/master/c-user/symmetric_multiprocessing_services.html
 #thread-dispatch-details

 In case such an update happens, a thread executes on the processor which
 was not visible to the context switch extensions. This can confuse for
 example event record consumers which use events generated by a context
 switch extension.

 Fixing this is not straight forward. The context switch extensions call
 must move after the low-level context switch. The problem here is that we
 may end up in _Thread_Handler(). Adding the context switch extensions call
 to _Thread_Handler() covers now also the thread switch to the
 initialization thread. We also have to save the last executing thread of
 the processor. Registers or the stack cannot be used for this purpose. We
 have to add it to the per-processor information. Existing extensions may
 be affected, since now context switch extensions use the stack of the heir
 thread.

 Calling the thread switch extensions in the low level context switch is
 difficult since at this point an intermediate stack is used which is only
 large enough to enable servicing of interrupts.

--

--
Ticket URL: <http://devel.rtems.org/ticket/3885#comment:5>
RTEMS Project <http://www.rtems.org/>
RTEMS Project


More information about the bugs mailing list