On 03.03.2022 01:40, Andrew Cooper wrote:
> When only one scheduler is compiled in, function pointers can be optimised to
> direct calls, and the hooks hardened against controlflow hijacking.
> 
> RFC for several reasons.
> 
> 1) There's an almost beautiful way of not introducing MAYBE_SCHED() and hiding
>    the magic in REGISTER_SCHEDULER(), except it falls over
>    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91765 which has no comment or
>    resolution at all.
> 
> 2) A different alternative which almost works is to remove the indirection in
>    .data.schedulers, but the singleton scheduler object can't be both there
>    and in .init.rodata.cf_clobber.

Couldn't we name the section differently when there's just one member,
placing that section inside __initdata_cf_clobber_{start,end} in the
linker script?

> 3) I can't think of a way of build time check to enforce that new schedulers
>    get added to the preprocessor magic.

An assertion in the linker script, checking that .data.schedulers has a
single entry when the sched_ops symbol exists? This may involve a
PROVIDE(sched_ops = 0) as there doesn't look to be a way to probe for
symbol defined-ness in expressions.

> And the blocker:
> 4) This isn't compatible with how sched_idle_ops get used for granularity > 1.

Special case it just like we special case plt_tsc in x86/time.c?

> --- a/xen/common/sched/private.h
> +++ b/xen/common/sched/private.h
> @@ -271,6 +271,33 @@ static inline spinlock_t *pcpu_schedule_trylock(unsigned 
> int cpu)
>      return NULL;
>  }
>  
> +#if 1 ==                                                                \
> +    defined(CONFIG_SCHED_CREDIT) + defined(CONFIG_SCHED_CREDIT2) +      \
> +    defined(CONFIG_SCHED_RTDS) + defined(CONFIG_SCHED_ARINC653) +       \
> +    defined(CONFIG_SCHED_NULL)
> +
> +extern const struct scheduler sched_ops;
> +#define MAYBE_SCHED(x) __initdata_cf_clobber sched_ops

__initconst_cf_clobber, seeing that all use sites also use const?

> @@ -333,39 +360,48 @@ struct scheduler {
>      void         (*dump_cpu_state) (const struct scheduler *, int);
>  };
>  
> +static inline int sched_global_init(const struct scheduler *s)
> +{
> +    if ( s->global_init )
> +        return sched_call(s, global_init);
> +    return 0;
> +}

Is it really a good idea to expose this here when it's supposed to be
used from core.c only, and even there in just a single place?

Jan


Reply via email to