[PATCH 7/7] xen/sched: remove old scheduler registration, shrink struct scheduler

Furkan Caliskan <[email protected]> Mon, 3 Aug 2026 08:06:14 +0300
Newsgroups org.xenproject.lists.xen-devel
Message-ID <[email protected]>
Every in-tree scheduler now registers through sched_ops instead of
the original struct-scheduler-as-vtable path, so schedulers[],
REGISTER_SCHEDULER() and NUM_SCHEDULERS have no remaining users.
Remove them and finish the change struct sched_ops was introduced
for: struct scheduler is shrunk down to just its per-cpupool
fields - a pointer to a shared sched_ops, plus sched_data and
cpupool.

scheduler_alloc() now stores a pointer to the matching sched_ops
instance instead of copying every field into a fresh allocation.
Cpupools sharing a scheduler type now share one dispatch table
instead of each holding a private copy of it.

Every accessor in private.h is updated from s->field to
s->ops->field to match. sched_idle_ops is split the same way
every other scheduler was.

A handful of call sites elsewhere read a scheduler's name,
opt_name or sched_id directly and are updated to go through
->ops as well.

Signed-off-by: Furkan Caliskan <[email protected]>
---
 xen/arch/arm/xen.lds.S     |   1 -
 xen/arch/ppc/xen.lds.S     |   1 -
 xen/arch/riscv/xen.lds.S   |   1 -
 xen/arch/x86/xen.lds.S     |   1 -
 xen/common/sched/core.c    | 144 +++++-----------------------------
 xen/common/sched/cpupool.c |   6 +-
 xen/common/sched/private.h | 155 ++++++++++---------------------------
 xen/include/xen/xen.lds.h  |   6 --
 8 files changed, 67 insertions(+), 248 deletions(-)

diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S
index 9a63fa36a0..07bf875599 100644
--- a/xen/arch/arm/xen.lds.S
+++ b/xen/arch/arm/xen.lds.S
@@ -93,7 +93,6 @@ SECTIONS
   .data : {                    /* Data */
        *(.data.page_aligned)
 
-       SCHEDULER_ARRAY
        SCHED_OPS_ARRAY
        HYPFS_PARAM
 
diff --git a/xen/arch/ppc/xen.lds.S b/xen/arch/ppc/xen.lds.S
index da8f73d85b..1f4e200693 100644
--- a/xen/arch/ppc/xen.lds.S
+++ b/xen/arch/ppc/xen.lds.S
@@ -84,7 +84,6 @@ SECTIONS
     DECL_SECTION(.data) {                    /* Data */
         *(.data.page_aligned)
 
-        SCHEDULER_ARRAY
         SCHED_OPS_ARRAY
         HYPFS_PARAM
 
diff --git a/xen/arch/riscv/xen.lds.S b/xen/arch/riscv/xen.lds.S
index 01f202e504..97f2db1dfd 100644
--- a/xen/arch/riscv/xen.lds.S
+++ b/xen/arch/riscv/xen.lds.S
@@ -89,7 +89,6 @@ SECTIONS
     .data : {                    /* Data */
         *(.data.page_aligned)
 
-        SCHEDULER_ARRAY
         SCHED_OPS_ARRAY
         HYPFS_PARAM
 
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index d128a30440..0f506ff1f6 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -306,7 +306,6 @@ SECTIONS
   DECL_SECTION(.data.read_mostly) {
        *(.data.read_mostly)
 
-       SCHEDULER_ARRAY
        SCHED_OPS_ARRAY
        HYPFS_PARAM
   } PHDR(text)
diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index fb2d1d5314..4e5f78e84d 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -87,10 +87,6 @@ DEFINE_PER_CPU(cpumask_t, cpumask_scratch);
 /* How many urgent vcpus. */
 DEFINE_PER_CPU(atomic_t, sched_urgent_count);
 
-extern const struct scheduler *__start_schedulers_array[], *__end_schedulers_array[];
-#define NUM_SCHEDULERS (__end_schedulers_array - __start_schedulers_array)
-#define schedulers __start_schedulers_array
-
 extern const struct sched_ops *__start_sched_ops_array[], *__end_sched_ops_array[];
 #define NUM_SCHED_OPS (__end_sched_ops_array - __start_sched_ops_array)
 #define sched_ops_array __start_sched_ops_array
@@ -103,42 +99,6 @@ static void sched_set_affinity(
     struct sched_unit *unit, const cpumask_t *hard, const cpumask_t *soft);
 
 
-static void sched_ops_to_scheduler(
-        struct scheduler *sched, const struct sched_ops *ops)
-{
-    sched->name            = ops->name;
-    sched->opt_name        = ops->opt_name;
-    sched->sched_id        = ops->sched_id;
-    sched->global_init     = ops->global_init;
-    sched->init            = ops->init;
-    sched->deinit          = ops->deinit;
-    sched->free_udata      = ops->free_udata;
-    sched->alloc_udata     = ops->alloc_udata;
-    sched->free_pdata      = ops->free_pdata;
-    sched->alloc_pdata     = ops->alloc_pdata;
-    sched->deinit_pdata    = ops->deinit_pdata;
-    sched->alloc_domdata   = ops->alloc_domdata;
-    sched->free_domdata    = ops->free_domdata;
-    sched->switch_sched    = ops->switch_sched;
-    sched->insert_unit     = ops->insert_unit;
-    sched->remove_unit     = ops->remove_unit;
-    sched->sleep           = ops->sleep;
-    sched->wake            = ops->wake;
-    sched->yield           = ops->yield;
-    sched->context_saved   = ops->context_saved;
-    sched->do_schedule     = ops->do_schedule;
-    sched->pick_resource   = ops->pick_resource;
-    sched->migrate         = ops->migrate;
-    sched->adjust          = ops->adjust;
-    sched->adjust_affinity = ops->adjust_affinity;
-#ifdef CONFIG_SYSCTL
-    sched->adjust_global   = ops->adjust_global;
-#endif
-    sched->dump_settings   = ops->dump_settings;
-    sched->dump_cpu_state  = ops->dump_cpu_state;
-    sched->move_timers     = ops->move_timers;
-}
-
 static struct sched_resource *cf_check
 sched_idle_res_pick(const struct scheduler *ops, const struct sched_unit *unit)
 {
@@ -168,10 +128,9 @@ static void cf_check sched_idle_schedule(
     unit->next_task = sched_idle_unit(cpu);
 }
 
-static struct scheduler sched_idle_ops = {
+static struct sched_ops sched_idle_sched_ops = {
     .name           = "Idle Scheduler",
     .opt_name       = "idle",
-    .sched_data     = NULL,
 
     .pick_resource  = sched_idle_res_pick,
     .do_schedule    = sched_idle_schedule,
@@ -180,6 +139,11 @@ static struct scheduler sched_idle_ops = {
     .free_udata     = sched_idle_free_udata,
 };
 
+static struct scheduler sched_idle_ops = {
+    .ops         = &sched_idle_sched_ops,
+    .sched_data = NULL,
+};
+
 static inline struct vcpu *unit2vcpu_cpu(const struct sched_unit *unit,
                                          unsigned int cpu)
 {
@@ -2122,7 +2086,7 @@ long do_set_timer_op(s_time_t timeout)
 /* scheduler_id - fetch ID of current scheduler */
 int scheduler_id(void)
 {
-    return operations.sched_id;
+    return operations.ops->sched_id;
 }
 #endif
 
@@ -2131,7 +2095,7 @@ long sched_adjust(struct domain *d, struct xen_domctl_scheduler_op *op)
 {
     long ret;
 
-    if ( op->sched_id != dom_scheduler(d)->sched_id )
+    if ( op->sched_id != dom_scheduler(d)->ops->sched_id )
         return -EINVAL;
 
     switch ( op->cmd )
@@ -2177,7 +2141,7 @@ long sched_adjust_global(struct xen_sysctl_scheduler_op *op)
 
     rcu_read_lock(&sched_res_rculock);
 
-    rc = ((op->sched_id == pool->sched->sched_id)
+    rc = ((op->sched_id == pool->sched->ops->sched_id)
           ? sched_adjust_cpupool(pool->sched, op) : -EINVAL);
 
     rcu_read_unlock(&sched_res_rculock);
@@ -2344,7 +2308,7 @@ static struct sched_unit *do_schedule(struct sched_unit *prev, s_time_t now,
     struct sched_unit *next;
 
     /* get policy-specific decision on scheduling... */
-    sched->do_schedule(sched, prev, now, sched_tasklet_check(cpu));
+    sched->ops->do_schedule(sched, prev, now, sched_tasklet_check(cpu));
 
     next = prev->next_task;
 
@@ -3033,18 +2997,6 @@ void scheduler_enable(void)
     scheduler_active = true;
 }
 
-static inline
-const struct scheduler *__init sched_get_by_name(const char *sched_name)
-{
-    unsigned int i;
-
-    for ( i = 0; i < NUM_SCHEDULERS; i++ )
-        if ( schedulers[i] && !strcmp(schedulers[i]->opt_name, sched_name) )
-            return schedulers[i];
-
-    return NULL;
-}
-
 static inline
 const struct sched_ops *__init sched_ops_get_by_name(const char* sched_name)
 {
@@ -3058,13 +3010,7 @@ const struct sched_ops *__init sched_ops_get_by_name(const char* sched_name)
 
 int __init sched_get_id_by_name(const char *sched_name)
 {
-    const struct scheduler *scheduler = sched_get_by_name(sched_name);
-    const struct sched_ops *ops;
-
-    if ( scheduler )
-        return scheduler->sched_id;
-
-    ops = sched_ops_get_by_name(sched_name);
+    const struct sched_ops *ops = sched_ops_get_by_name(sched_name);
     return ops ? ops->sched_id : -1;
 }
 
@@ -3072,40 +3018,11 @@ int __init sched_get_id_by_name(const char *sched_name)
 void __init scheduler_init(void)
 {
     struct domain *idle_domain;
-    const struct scheduler *scheduler;
     const struct sched_ops *ops;
     int i;
 
     scheduler_enable();
 
-    for ( i = 0; i < NUM_SCHEDULERS; i++)
-    {
-#define sched_test_func(f)                               \
-        if ( !schedulers[i]->f )                         \
-        {                                                \
-            printk("scheduler %s misses .%s, dropped\n", \
-                   schedulers[i]->opt_name, #f);         \
-            schedulers[i] = NULL;                        \
-        }
-
-        sched_test_func(init);
-        sched_test_func(deinit);
-        sched_test_func(pick_resource);
-        sched_test_func(alloc_udata);
-        sched_test_func(free_udata);
-        sched_test_func(switch_sched);
-        sched_test_func(do_schedule);
-
-#undef sched_test_func
-
-        if ( schedulers[i]->global_init && schedulers[i]->global_init() < 0 )
-        {
-            printk("scheduler %s failed initialization, dropped\n",
-                   schedulers[i]->opt_name);
-            schedulers[i] = NULL;
-        }
-    }
-
     for ( i = 0; i < NUM_SCHED_OPS; i++)
     {
 #define sched_test_func(f)                               \
@@ -3134,30 +3051,22 @@ void __init scheduler_init(void)
         }
     }
 
-    scheduler = sched_get_by_name(opt_sched);
-    ops = scheduler ? NULL : sched_ops_get_by_name(opt_sched);
-    if ( !scheduler && !ops )
+    ops = sched_ops_get_by_name(opt_sched);
+    if ( !ops )
     {
         printk("Could not find scheduler: %s\n", opt_sched);
-        scheduler = sched_get_by_name(CONFIG_SCHED_DEFAULT);
-        ops = scheduler ? NULL : sched_ops_get_by_name(CONFIG_SCHED_DEFAULT);
-        BUG_ON(!scheduler && !ops);
-        if ( scheduler )
-            printk("Using '%s' (%s)\n", scheduler->name, scheduler->opt_name);
-        else
-            printk("Using '%s' (%s)\n", ops->name, ops->opt_name);
+        ops = sched_ops_get_by_name(CONFIG_SCHED_DEFAULT);
+        BUG_ON(!ops);
+        printk("Using '%s' (%s)\n", ops->name, ops->opt_name);
     }
 
-    if ( scheduler )
-        operations = *scheduler;
-    else
-        sched_ops_to_scheduler(&operations, ops);
+    operations.ops = ops;
 
     if ( cpu_schedule_up(0) )
         BUG();
     register_cpu_notifier(&cpu_schedule_nfb);
 
-    printk("Using scheduler: %s (%s)\n", operations.name, operations.opt_name);
+    printk("Using scheduler: %s (%s)\n", operations.ops->name, operations.ops->opt_name);
     if ( sched_init(&operations) )
         panic("scheduler returned error on init\n");
 
@@ -3507,28 +3416,17 @@ struct scheduler *scheduler_alloc(unsigned int sched_id)
     int ret;
     struct scheduler *sched;
 
-    for ( i = 0; i < NUM_SCHEDULERS; i++ )
-        if ( schedulers[i] && schedulers[i]->sched_id == sched_id )
-            goto found;
-
     for ( i = 0; i < NUM_SCHED_OPS; i++ )
         if ( sched_ops_array[i] && sched_ops_array[i]->sched_id == sched_id )
-            goto found_new;
+            goto found;
 
     return ERR_PTR(-ENOENT);
 
  found:
-    if ( (sched = xmalloc(struct scheduler)) == NULL )
-        return ERR_PTR(-ENOMEM);
-    memcpy(sched, schedulers[i], sizeof(*sched));
-    goto init;
-
- found_new:
     if ( (sched = xzalloc(struct scheduler)) == NULL )
         return ERR_PTR(-ENOMEM);
-    sched_ops_to_scheduler(sched, sched_ops_array[i]);
+    sched->ops = sched_ops_array[i];
 
- init:
     if ( (ret = sched_init(sched)) != 0 )
     {
         xfree(sched);
@@ -3559,7 +3457,7 @@ void schedule_dump(struct cpupool *c)
     {
         sched = c->sched;
         cpus = c->res_valid;
-        printk("Scheduler: %s (%s)\n", sched->name, sched->opt_name);
+        printk("Scheduler: %s (%s)\n", sched->ops->name, sched->ops->opt_name);
         sched_dump_settings(sched);
     }
     else
diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 081e1053eb..1c70b58409 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -338,7 +338,7 @@ static struct cpupool *cpupool_create(unsigned int poolid,
     spin_unlock(&cpupool_lock);
 
     debugtrace_printk("Created cpupool %u with scheduler %s (%s)\n",
-                      c->cpupool_id, c->sched->name, c->sched->opt_name);
+                      c->cpupool_id, c->sched->ops->name, c->sched->ops->opt_name);
 
     return c;
 
@@ -862,7 +862,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
         if ( c == NULL )
             break;
         op->cpupool_id = c->cpupool_id;
-        op->sched_id = c->sched->sched_id;
+        op->sched_id = c->sched->ops->sched_id;
         op->n_dom = c->n_dom;
         ret = cpumask_to_xenctl_bitmap(&op->cpumap, c->cpu_valid);
         cpupool_put(c);
@@ -1294,7 +1294,7 @@ struct cpupool *__init cpupool_create_pool(unsigned int pool_id, int sched_id)
     struct cpupool *pool;
 
     if ( sched_id < 0 )
-        sched_id = scheduler_get_default()->sched_id;
+        sched_id = scheduler_get_default()->ops->sched_id;
 
     pool = cpupool_create(pool_id, sched_id);
 
diff --git a/xen/common/sched/private.h b/xen/common/sched/private.h
index 4dd5c99b87..c03063befe 100644
--- a/xen/common/sched/private.h
+++ b/xen/common/sched/private.h
@@ -365,198 +365,132 @@ struct sched_ops {
 };
 
 struct scheduler {
-    const char *name;       /* full name for this scheduler      */
-    const char *opt_name;   /* option name for this scheduler    */
-    unsigned int sched_id;  /* ID for this scheduler             */
-    void *sched_data;       /* global data pointer               */
-    struct cpupool *cpupool;/* points to this scheduler's pool   */
-
-    int          (*global_init)    (void);
-
-    int          (*init)           (struct scheduler *ops);
-    void         (*deinit)         (struct scheduler *ops);
-
-    void         (*free_udata)     (const struct scheduler *ops, void *priv);
-    void *       (*alloc_udata)    (const struct scheduler *ops,
-                                    struct sched_unit *unit, void *dd);
-
-    void         (*free_pdata)     (const struct scheduler *ops,
-                                    void *pcpu, int cpu);
-    void *       (*alloc_pdata)    (const struct scheduler *ops, int cpu);
-    void         (*deinit_pdata)   (const struct scheduler *ops,
-                                    void *pcpu, int cpu);
-
-    /* Returns ERR_PTR(-err) for error, NULL for 'nothing needed'. */
-    void *       (*alloc_domdata)  (const struct scheduler *ops,
-                                    struct domain *dom);
-    /* Idempotent. */
-    void         (*free_domdata)   (const struct scheduler *ops, void *data);
-
-    spinlock_t * (*switch_sched)   (struct scheduler *new_ops, unsigned int cpu,
-                                    void *pdata, void *vdata);
-
-    /* Activate / deactivate units in a cpu pool */
-    void         (*insert_unit)    (const struct scheduler *ops,
-                                    struct sched_unit *unit);
-    void         (*remove_unit)    (const struct scheduler *ops,
-                                    struct sched_unit *unit);
-
-    void         (*sleep)          (const struct scheduler *ops,
-                                    struct sched_unit *unit);
-    void         (*wake)           (const struct scheduler *ops,
-                                    struct sched_unit *unit);
-    void         (*yield)          (const struct scheduler *ops,
-                                    struct sched_unit *unit);
-    void         (*context_saved)  (const struct scheduler *ops,
-                                    struct sched_unit *unit);
-
-    void         (*do_schedule)    (const struct scheduler *ops,
-                                    struct sched_unit *currunit, s_time_t now,
-                                    bool tasklet_work_scheduled);
-
-    struct sched_resource *(*pick_resource)(const struct scheduler *ops,
-                                            const struct sched_unit *unit);
-    void         (*migrate)        (const struct scheduler *ops,
-                                    struct sched_unit *unit,
-                                    unsigned int new_cpu);
-    int          (*adjust)         (const struct scheduler *ops,
-                                    struct domain *d,
-                                    struct xen_domctl_scheduler_op *op);
-    void         (*adjust_affinity)(const struct scheduler *ops,
-                                    struct sched_unit *unit,
-                                    const struct cpumask *hard,
-                                    const struct cpumask *soft);
-#ifdef CONFIG_SYSCTL
-    int          (*adjust_global)  (const struct scheduler *ops,
-                                    struct xen_sysctl_scheduler_op *sc);
-#endif
-    void         (*dump_settings)  (const struct scheduler *ops);
-    void         (*dump_cpu_state) (const struct scheduler *ops, int cpu);
-    void         (*move_timers)    (const struct scheduler *ops,
-                                    struct sched_resource *sr);
+    const struct sched_ops *ops; /* shared, read-only dispatch table */
+    void *sched_data;            /* global data pointer               */
+    struct cpupool *cpupool;     /* points to this scheduler's pool   */
 };
 
 static inline int sched_init(struct scheduler *s)
 {
-    return s->init(s);
+    return s->ops->init(s);
 }
 
 static inline void sched_deinit(struct scheduler *s)
 {
-    s->deinit(s);
+    s->ops->deinit(s);
 }
 
 static inline spinlock_t *sched_switch_sched(struct scheduler *s,
                                              unsigned int cpu,
                                              void *pdata, void *vdata)
 {
-    return s->switch_sched(s, cpu, pdata, vdata);
+    return s->ops->switch_sched(s, cpu, pdata, vdata);
 }
 
 static inline void sched_dump_settings(const struct scheduler *s)
 {
-    if ( s->dump_settings )
-        s->dump_settings(s);
+    if ( s->ops->dump_settings )
+        s->ops->dump_settings(s);
 }
 
 static inline void sched_dump_cpu_state(const struct scheduler *s, int cpu)
 {
-    if ( s->dump_cpu_state )
-        s->dump_cpu_state(s, cpu);
+    if ( s->ops->dump_cpu_state )
+        s->ops->dump_cpu_state(s, cpu);
 }
 
 static inline void *sched_alloc_domdata(const struct scheduler *s,
                                         struct domain *d)
 {
-    return s->alloc_domdata ? s->alloc_domdata(s, d) : NULL;
+    return s->ops->alloc_domdata ? s->ops->alloc_domdata(s, d) : NULL;
 }
 
 static inline void sched_free_domdata(const struct scheduler *s,
                                       void *data)
 {
-    ASSERT(s->free_domdata || !data);
-    if ( s->free_domdata )
-        s->free_domdata(s, data);
+    ASSERT(s->ops->free_domdata || !data);
+    if ( s->ops->free_domdata )
+        s->ops->free_domdata(s, data);
 }
 
 static inline void *sched_alloc_pdata(const struct scheduler *s, int cpu)
 {
-    return s->alloc_pdata ? s->alloc_pdata(s, cpu) : NULL;
+    return s->ops->alloc_pdata ? s->ops->alloc_pdata(s, cpu) : NULL;
 }
 
 static inline void sched_free_pdata(const struct scheduler *s, void *data,
                                     int cpu)
 {
-    ASSERT(s->free_pdata || !data);
-    if ( s->free_pdata )
-        s->free_pdata(s, data, cpu);
+    ASSERT(s->ops->free_pdata || !data);
+    if ( s->ops->free_pdata )
+        s->ops->free_pdata(s, data, cpu);
 }
 
 static inline void sched_deinit_pdata(const struct scheduler *s, void *data,
                                       int cpu)
 {
-    if ( s->deinit_pdata )
-        s->deinit_pdata(s, data, cpu);
+    if ( s->ops->deinit_pdata )
+        s->ops->deinit_pdata(s, data, cpu);
 }
 
 static inline void *sched_alloc_udata(const struct scheduler *s,
                                       struct sched_unit *unit, void *dom_data)
 {
-    return s->alloc_udata(s, unit, dom_data);
+    return s->ops->alloc_udata(s, unit, dom_data);
 }
 
 static inline void sched_free_udata(const struct scheduler *s, void *data)
 {
-    s->free_udata(s, data);
+    s->ops->free_udata(s, data);
 }
 
 static inline void sched_insert_unit(const struct scheduler *s,
                                      struct sched_unit *unit)
 {
-    if ( s->insert_unit )
-        s->insert_unit(s, unit);
+    if ( s->ops->insert_unit )
+        s->ops->insert_unit(s, unit);
 }
 
 static inline void sched_remove_unit(const struct scheduler *s,
                                      struct sched_unit *unit)
 {
-    if ( s->remove_unit )
-        s->remove_unit(s, unit);
+    if ( s->ops->remove_unit )
+        s->ops->remove_unit(s, unit);
 }
 
 static inline void sched_sleep(const struct scheduler *s,
                                struct sched_unit *unit)
 {
-    if ( s->sleep )
-        s->sleep(s, unit);
+    if ( s->ops->sleep )
+        s->ops->sleep(s, unit);
 }
 
 static inline void sched_wake(const struct scheduler *s,
                               struct sched_unit *unit)
 {
-    if ( s->wake )
-        s->wake(s, unit);
+    if ( s->ops->wake )
+        s->ops->wake(s, unit);
 }
 
 static inline void sched_yield(const struct scheduler *s,
                                struct sched_unit *unit)
 {
-    if ( s->yield )
-        s->yield(s, unit);
+    if ( s->ops->yield )
+        s->ops->yield(s, unit);
 }
 
 static inline void sched_context_saved(const struct scheduler *s,
                                        struct sched_unit *unit)
 {
-    if ( s->context_saved )
-        s->context_saved(s, unit);
+    if ( s->ops->context_saved )
+        s->ops->context_saved(s, unit);
 }
 
 static inline void sched_migrate(const struct scheduler *s,
                                  struct sched_unit *unit, unsigned int cpu)
 {
-    if ( s->migrate )
-        s->migrate(s, unit, cpu);
+    if ( s->ops->migrate )
+        s->ops->migrate(s, unit, cpu);
     else
         sched_set_res(unit, get_sched_res(cpu));
 }
@@ -564,7 +498,7 @@ static inline void sched_migrate(const struct scheduler *s,
 static inline struct sched_resource *sched_pick_resource(
     const struct scheduler *s, const struct sched_unit *unit)
 {
-    return s->pick_resource(s, unit);
+    return s->ops->pick_resource(s, unit);
 }
 
 static inline void sched_adjust_affinity(const struct scheduler *s,
@@ -572,29 +506,29 @@ static inline void sched_adjust_affinity(const struct scheduler *s,
                                          const cpumask_t *hard,
                                          const cpumask_t *soft)
 {
-    if ( s->adjust_affinity )
-        s->adjust_affinity(s, unit, hard, soft);
+    if ( s->ops->adjust_affinity )
+        s->ops->adjust_affinity(s, unit, hard, soft);
 }
 
 static inline int sched_adjust_dom(const struct scheduler *s, struct domain *d,
                                    struct xen_domctl_scheduler_op *op)
 {
-    return s->adjust ? s->adjust(s, d, op) : 0;
+    return s->ops->adjust ? s->ops->adjust(s, d, op) : 0;
 }
 
 #ifdef CONFIG_SYSCTL
 static inline int sched_adjust_cpupool(const struct scheduler *s,
                                        struct xen_sysctl_scheduler_op *op)
 {
-    return s->adjust_global ? s->adjust_global(s, op) : 0;
+    return s->ops->adjust_global ? s->ops->adjust_global(s, op) : 0;
 }
 #endif
 
 static inline void sched_move_timers(const struct scheduler *s,
                                      struct sched_resource *sr)
 {
-    if ( s->move_timers )
-        s->move_timers(s, sr);
+    if ( s->ops->move_timers )
+        s->ops->move_timers(s, sr);
 }
 
 static inline void sched_unit_pause_nosync(const struct sched_unit *unit)
@@ -613,9 +547,6 @@ static inline void sched_unit_unpause(const struct sched_unit *unit)
         vcpu_unpause(v);
 }
 
-#define REGISTER_SCHEDULER(x) static const struct scheduler *x##_entry \
-  __used_section(".data.schedulers") = &(x)
-
 #define REGISTER_SCHED_OPS(x) static const struct sched_ops *x##_entry \
   __used_section(".data.sched_ops") = &(x)
 
diff --git a/xen/include/xen/xen.lds.h b/xen/include/xen/xen.lds.h
index 157d48eabd..0005c38486 100644
--- a/xen/include/xen/xen.lds.h
+++ b/xen/include/xen/xen.lds.h
@@ -173,12 +173,6 @@
        _edevice = .;        \
   } :text
 
-#define SCHEDULER_ARRAY              \
-       . = ALIGN(POINTER_ALIGN);     \
-       __start_schedulers_array = .; \
-       *(.data.schedulers)           \
-       __end_schedulers_array = .;
-
 #define SCHED_OPS_ARRAY              \
        . = ALIGN(POINTER_ALIGN);     \
        __start_sched_ops_array = .;  \
-- 
2.34.1