Changeset 834a86fe in rtems


Ignore:
Timestamp:
11/15/21 09:20:30 (9 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
cd791039
Parents:
c69a70a
git-author:
Sebastian Huber <sebastian.huber@…> (11/15/21 09:20:30)
git-committer:
Sebastian Huber <sebastian.huber@…> (11/23/21 10:00:28)
Message:

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
  1. exactly one processor owned by the scheduler.

Close #4545.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/src/scheduleredfsmp.c

    rc69a70a r834a86fe  
    886886  Scheduler_Context      *context;
    887887  Scheduler_EDF_SMP_Node *node;
    888   Processor_mask          local_affinity;
    889888  uint8_t                 rqi;
    890889
    891890  context = _Scheduler_Get_context( scheduler );
    892   _Processor_mask_And( &local_affinity, &context->Processors, affinity );
    893 
    894   if ( _Processor_mask_Is_zero( &local_affinity ) ) {
    895     return STATUS_INVALID_NUMBER;
    896   }
     891
     892  /*
     893   * We support a thread to processor affinity to all online processors and an
     894   * affinity to exactly one processor.  This restriction is necessary to avoid
     895   * issues if processors are added or removed to or from the scheduler.
     896   */
    897897
    898898  if ( _Processor_mask_Is_equal( affinity, &_SMP_Online_processors ) ) {
    899899    rqi = 0;
    900900  } else {
    901     rqi = _Processor_mask_Find_last_set( &local_affinity );
     901    Processor_mask local_affinity;
     902    Processor_mask one_to_one;
     903    uint32_t       last;
     904
     905    _Processor_mask_And( &local_affinity, &context->Processors, affinity );
     906
     907    if ( _Processor_mask_Is_zero( &local_affinity ) ) {
     908      return STATUS_INVALID_NUMBER;
     909    }
     910
     911    last = _Processor_mask_Find_last_set( affinity );
     912    _Processor_mask_From_index( &one_to_one, last - 1 );
     913
     914    /*
     915     * Use the global affinity set and not the affinity set local to the
     916     * scheduler to check for a one-to-one affinity.
     917     */
     918    if ( !_Processor_mask_Is_equal( &one_to_one, affinity ) ) {
     919      return STATUS_INVALID_NUMBER;
     920    }
     921
     922    rqi = last;
    902923  }
    903924
Note: See TracChangeset for help on using the changeset viewer.