The SMP EDF scheduler supports a one-to-one and one-to-all thread to processor affinity. It accepted affinity sets which are a proper subset of the online processor containing at least two processors owned by the scheduler. In this case it used a one-to-one thread to processor affinity. This leads to undefined behaviour if a processor is removed since the higher level check in rtems_scheduler_remove_processor() does not account for this implementation detail.
Restrict the affinity set accepted by the SMP EDF scheduler to 1. all online processors, or 2. exactly one processor owned by the scheduler. Close #4545. --- cpukit/score/src/scheduleredfsmp.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/cpukit/score/src/scheduleredfsmp.c b/cpukit/score/src/scheduleredfsmp.c index 93c3c126f7..96b530e912 100644 --- a/cpukit/score/src/scheduleredfsmp.c +++ b/cpukit/score/src/scheduleredfsmp.c @@ -885,20 +885,38 @@ Status_Control _Scheduler_EDF_SMP_Set_affinity( { Scheduler_Context *context; Scheduler_EDF_SMP_Node *node; - Processor_mask local_affinity; uint8_t rqi; context = _Scheduler_Get_context( scheduler ); - _Processor_mask_And( &local_affinity, &context->Processors, affinity ); - if ( _Processor_mask_Is_zero( &local_affinity ) ) { - return STATUS_INVALID_NUMBER; - } + /* + * We support a thread to processor affinity to all online processors and an + * affinity to exactly one processor owned by the scheduler. This + * restriction is necessary to avoid issues if processors are added or + * removed to or from the scheduler. + */ if ( _Processor_mask_Is_equal( affinity, &_SMP_Online_processors ) ) { rqi = 0; } else { - rqi = _Processor_mask_Find_last_set( &local_affinity ); + Processor_mask local_affinity; + Processor_mask only_last_affinity; + uint32_t last; + + _Processor_mask_And( &local_affinity, &context->Processors, affinity ); + + if ( _Processor_mask_Is_zero( &local_affinity ) ) { + return STATUS_INVALID_NUMBER; + } + + last = _Processor_mask_Find_last_set( &local_affinity ); + _Processor_mask_From_index( &only_last_affinity, last - 1 ); + + if ( !_Processor_mask_Is_equal( &local_affinity, &only_last_affinity ) ) { + return STATUS_INVALID_NUMBER; + } + + rqi = last; } node = _Scheduler_EDF_SMP_Node_downcast( node_base ); -- 2.26.2 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel