Partitioned/clustered scheduling

Gedare Bloom gedare at rtems.org
Tue Nov 19 20:17:04 UTC 2013


On Tue, Nov 19, 2013 at 12:36 PM, Gedare Bloom <gedare at rtems.org> wrote:
> On Tue, Nov 19, 2013 at 8:39 AM, Sebastian Huber
> <sebastian.huber at embedded-brains.de> wrote:
>> Hello,
>>
>> we would like to implement partitioned/clustered scheduling for SMP RTEMS.
>> The reasons for this are highlighted in
>>
>> Björn B. Brandenburg, Scheduling and Locking in Multiprocessor Real-Time
>> Operating Systems, 2011
>>
>> Partitioned/clustered scheduling means that the set of processors of a
>> system can be partitioned into pairwise disjoint subsets.  Each subset of
>> processors will be owned by one scheduler instance.
>>
> Great!
>
>> The following proposal covers the processor configuration, high-level
>> scheduler implementation and RTEMS API changes.
>>
>> ==== Scheduler Configuration ====
>>
>> There are two options for the scheduler instance configuration
>>
>> # static configuration by means of global data structures, and
>> # configuration at run-time via function calls.
>>
>> For a configuration at run-time the system must start with a default
>> scheduler.
>> The global constructors are called in this environment.  The order of global
>> constructor invocation is unpredictable so it is difficult to create threads
>> in
>> this context since the run-time scheduler configuration may not exist yet.
I don't understand what constructors have to do with the scheduler
configuration. Can you explain this a little more or provide an
example?

>> Since scheduler data structures are allocated from the workspace the
>> configuration must take a later run-time setup of schedulers into account
>> for
>> the workspace size estimate.  In case the default scheduler is not
We already do this for the UP scheduling, right? Is the SMP scheduling
a lot harder to estimate for some reasons?

>> appropriate
>> it must be replaced which gives raise to some implementation difficulties.
>> Since the processor availability is determined by hardware constraints it is
>> unclear which benefits a run-time configuration has.  For now run-time
>> configuration of scheduler instances will be not implemented.
>>
> That's fine. I think scheduler run-time (re)configuration is
> unnecessary except in some extreme cases for debugging.
>
>> The focus is now on static configuration.  Every scheduler needs a control
>> context.  The scheduler API must provide a macro which creates a global
>> scheduler instance specific data structure with a designator name as a
>> mandatory parameter.  The scheduler instance creation macro may require
>> additional scheduler specific configuration options.  For example a
>> fixed-priority scheduler instance must know the maximum priority level to
>> allocate the ready chain control table.
>>
>> Once the scheduler instances are configured it must be specified for each
>> processor in the system which scheduler instance owns this processor.
>>
>> For each processor except the initialization processor a scheduler instance
>> is
>> optional so that other operating systems can run independent of this RTEMS
>> system on this processor.  It is a fatal error to omit a scheduler instance
>> for
>> the initialization processor.  The initialization processor is the processor
>> which executes the boot_card() function.
>>
>>  /**
>>   * @brief Processor configuration.
>>   *
>>   * Use RTEMS_CPU_CONFIG_INIT() to initialize this structure.
>>   */
>>  typedef struct {
>>    /**
>>     * @brief Scheduler instance for this processor.
>>     *
>>     * It is possible to omit a scheduler instance for this processor by
>> using
>>     * the @c NULL pointer.  In this case RTEMS will not use this processor
>> and
>>     * other operating systems may claim it.
>>     */
>>    Scheduler_Control *scheduler;
>>  } rtems_cpu_config;
>>
>>  /**
>>   * @brief Processor configuration initializer.
>>   *
>>   * @param scheduler The reference to a scheduler instance or @c NULL.
>>   *
>>   * @see rtems_cpu_config.
>>   */
>>  #define RTEMS_CPU_CONFIG_INIT(scheduler) \
>>    { ( scheduler ) }
>>
>> Scheduler and processor configuration example:
>>
>>  RTEMS_SCHED_DEFINE_FP_SMP(sched_fp0, 256);
>>  RTEMS_SCHED_DEFINE_FP_SMP(sched_fp1, 64);
>>  RTEMS_SCHED_DEFINE_EDF_SMP(sched_edf0);
>>
>>  const rtems_cpu_config rtems_cpu_config_table[] = {
>>    RTEMS_CPU_CONFIG_INIT(RTEMS_SCHED_REF_FP_SMP(sched_fp0)),
>>    RTEMS_CPU_CONFIG_INIT(RTEMS_SCHED_REF_FP_SMP(sched_fp1)),
>>    RTEMS_CPU_CONFIG_INIT(RTEMS_SCHED_REF_FP_SMP(sched_fp1)),
>>    RTEMS_CPU_CONFIG_INIT(RTEMS_SCHED_REF_FP_SMP(sched_fp1)),
>>    RTEMS_CPU_CONFIG_INIT(NULL),
>>    RTEMS_CPU_CONFIG_INIT(NULL),
>>    RTEMS_CPU_CONFIG_INIT(RTEMS_SCHED_REF_EDF_SMP(sched_edf0)),
>>    RTEMS_CPU_CONFIG_INIT(RTEMS_SCHED_REF_EDF_SMP(sched_edf0)
>>  };
>>
>>  const size_t rtems_cpu_config_count =
>>    RTEMS_ARRAY_SIZE(rtems_cpu_config_table);
>>
> This looks good to me. I guess the user must define the table. We
> should offer some logical/safe defaults, especially for
> single-processor.
>
I've had some more time to think about this. Can you make it so the
static table-driven approach might be extended in the future to a
dynamic run-time configuration approach? I find it reasonable in the
future that someone might want the ability to add/remove processors to
their RTEMS system. Example scenarios where dynamic processor
management would be wanted include for fault recovery and power
management.

I'm not asking that you make the run-time configuration possible, just
that you keep it in mind as you design the static table-driven
solution. For example, could there possibly be a hook before the
initialization code reads the cpu_config_table that allows for
modifying that table?

-Gedare




More information about the devel mailing list