[PATCH 27/27] score: Restrict affinity for EDF SMP scheduler

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Nov 15 17:12:59 UTC 2021


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



More information about the devel mailing list