[rtems commit] score: Restrict affinity for EDF SMP scheduler

Sebastian Huber sebh at rtems.org
Tue Nov 23 13:34:54 UTC 2021


Module:    rtems
Branch:    master
Commit:    834a86fe212719735fd7ede8c60f78fedf70a758
Changeset: http://git.rtems.org/rtems/commit/?id=834a86fe212719735fd7ede8c60f78fedf70a758

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Nov 15 10:20:30 2021 +0100

score: Restrict affinity for EDF SMP scheduler

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 | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/cpukit/score/src/scheduleredfsmp.c b/cpukit/score/src/scheduleredfsmp.c
index 93c3c12..ef7f4bc 100644
--- a/cpukit/score/src/scheduleredfsmp.c
+++ b/cpukit/score/src/scheduleredfsmp.c
@@ -885,20 +885,41 @@ 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.  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 one_to_one;
+    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( affinity );
+    _Processor_mask_From_index( &one_to_one, last - 1 );
+
+    /*
+     * Use the global affinity set and not the affinity set local to the
+     * scheduler to check for a one-to-one affinity.
+     */
+    if ( !_Processor_mask_Is_equal( &one_to_one, affinity ) ) {
+      return STATUS_INVALID_NUMBER;
+    }
+
+    rqi = last;
   }
 
   node = _Scheduler_EDF_SMP_Node_downcast( node_base );



More information about the vc mailing list