summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-11-15 10:20:30 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-11-23 11:00:28 +0100
commit834a86fe212719735fd7ede8c60f78fedf70a758 (patch)
tree04c96796563867fd584611d985dd9f325a4e24a0 /cpukit/score
parentrtems: Fix rtems_scheduler_remove_processor() (diff)
downloadrtems-834a86fe212719735fd7ede8c60f78fedf70a758.tar.bz2
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.
Diffstat (limited to 'cpukit/score')
-rw-r--r--cpukit/score/src/scheduleredfsmp.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/cpukit/score/src/scheduleredfsmp.c b/cpukit/score/src/scheduleredfsmp.c
index 93c3c126f7..ef7f4bca7c 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 );