@@ -350,6 +350,8 @@ void start_secondary(unsigned long boot_phys_offset,
setup_cpu_sibling_map(cpuid);
+ scheduler_percpu_init(cpuid);
+
/* Run local notifiers */
notify_cpu_starting(cpuid);
/*
@@ -382,6 +382,8 @@ void start_secondary(void *unused)
set_cpu_sibling_map(cpu);
+ scheduler_percpu_init(cpu);
+
init_percpu_time();
setup_secondary_APIC_clock();
@@ -2040,6 +2040,15 @@ static void cpu_schedule_down(unsigned int cpu)
xfree(sd);
}
+void scheduler_percpu_init(unsigned int cpu)
+{
+ struct scheduler *sched = per_cpu(scheduler, cpu);
+ struct sched_resource *sd = get_sched_res(cpu);
+
+ if ( system_state != SYS_STATE_resume )
+ sched_init_pdata(sched, sd->sched_priv, cpu);
+}
+
static int cpu_schedule_callback(
struct notifier_block *nfb, unsigned long action, void *hcpu)
{
@@ -2058,8 +2067,8 @@ static int cpu_schedule_callback(
* data can avoid implementing alloc_pdata. init_pdata may, however, be
* necessary/useful in this case too (e.g., it can contain the "register
* the pCPU to the scheduler" part). alloc_pdata (if present) is called
- * during CPU_UP_PREPARE. init_pdata (if present) is called during
- * CPU_STARTING.
+ * during CPU_UP_PREPARE. init_pdata (if present) is called before
+ * CPU_STARTING in scheduler_percpu_init().
*
* On the other hand, at teardown, we need to reverse what has been done
* during initialization, and then free the per-pCPU specific data. This
@@ -2082,10 +2091,6 @@ static int cpu_schedule_callback(
*/
switch ( action )
{
- case CPU_STARTING:
- if ( system_state != SYS_STATE_resume )
- sched_init_pdata(sched, sd->sched_priv, cpu);
- break;
case CPU_UP_PREPARE:
if ( system_state != SYS_STATE_resume )
rc = cpu_schedule_up(cpu);
@@ -2206,7 +2211,7 @@ void __init scheduler_init(void)
get_sched_res(0)->curr = idle_vcpu[0]->sched_unit;
get_sched_res(0)->sched_priv = sched_alloc_pdata(&ops, 0);
BUG_ON(IS_ERR(get_sched_res(0)->sched_priv));
- sched_init_pdata(&ops, get_sched_res(0)->sched_priv, 0);
+ scheduler_percpu_init(0);
}
/*
@@ -675,6 +675,7 @@ void __domain_crash(struct domain *d);
void noreturn asm_domain_crash_synchronous(unsigned long addr);
void scheduler_init(void);
+void scheduler_percpu_init(unsigned int cpu);
int sched_init_vcpu(struct vcpu *v);
void sched_destroy_vcpu(struct vcpu *v);
int sched_init_domain(struct domain *d, int poolid);
For support of core scheduling the scheduler cpu callback for CPU_STARTING has to be moved into a dedicated function called by start_secondary() as it needs to run before spin_debug_enable() then due to potentially calling xfree(). Signed-off-by: Juergen Gross <jgross@suse.com> --- RFC V2: fix ARM build --- xen/arch/arm/smpboot.c | 2 ++ xen/arch/x86/smpboot.c | 2 ++ xen/common/schedule.c | 19 ++++++++++++------- xen/include/xen/sched.h | 1 + 4 files changed, 17 insertions(+), 7 deletions(-)