With no modular drivers, all CPU notifier setup is supposed to happen during boot. There also is a respective comment in the function. Signed-off-by: Jan Beulich --- a/xen/arch/x86/nmi.c +++ b/xen/arch/x86/nmi.c @@ -389,12 +389,12 @@ void watchdog_disable(void) void watchdog_enable(void) { - static unsigned long heartbeat_initialised; - unsigned int cpu; + atomic_dec(&watchdog_disable_count); +} - if ( !atomic_dec_and_test(&watchdog_disable_count) || - test_and_set_bit(0, &heartbeat_initialised) ) - return; +void __init watchdog_setup(void) +{ + unsigned int cpu; /* * Activate periodic heartbeats. We cannot do this earlier during @@ -403,6 +403,8 @@ void watchdog_enable(void) for_each_online_cpu ( cpu ) cpu_nmi_callback(&cpu_nmi_nfb, CPU_UP_PREPARE, (void *)(long)cpu); register_cpu_notifier(&cpu_nmi_nfb); + + watchdog_enable(); } void nmi_watchdog_tick(struct cpu_user_regs * regs) --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1259,7 +1259,7 @@ void __init __start_xen(unsigned long mb do_initcalls(); if ( opt_watchdog ) - watchdog_enable(); + watchdog_setup(); if ( !tboot_protect_mem_regions() ) panic("Could not protect TXT memory regions\n"); --- a/xen/common/cpu.c +++ b/xen/common/cpu.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -53,7 +54,7 @@ void cpu_hotplug_done(void) static NOTIFIER_HEAD(cpu_chain); -void register_cpu_notifier(struct notifier_block *nb) +void __init register_cpu_notifier(struct notifier_block *nb) { if ( !spin_trylock(&cpu_add_remove_lock) ) BUG(); /* Should never fail as we are called only during boot. */ --- a/xen/common/notifier.c +++ b/xen/common/notifier.c @@ -19,7 +19,7 @@ * Adds a notifier to a raw notifier chain. * All locking must be provided by the caller. */ -void notifier_chain_register( +void __init notifier_chain_register( struct notifier_head *nh, struct notifier_block *n) { struct list_head *chain = &nh->head.chain; @@ -44,7 +44,7 @@ void notifier_chain_register( * Removes a notifier from a raw notifier chain. * All locking must be provided by the caller. */ -void notifier_chain_unregister( +void __init notifier_chain_unregister( struct notifier_head *nh, struct notifier_block *n) { list_del(&n->chain); --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -66,7 +66,6 @@ static const struct scheduler *scheduler &sched_credit_def, &sched_credit2_def, &sched_arinc653_def, - NULL }; static struct scheduler __read_mostly ops; @@ -1324,17 +1323,25 @@ void __init scheduler_init(void) open_softirq(SCHEDULE_SOFTIRQ, schedule); - for ( i = 0; schedulers[i] != NULL; i++ ) + for ( i = 0; i < ARRAY_SIZE(schedulers); i++ ) { - ops = *schedulers[i]; - if ( strcmp(ops.opt_name, opt_sched) == 0 ) - break; + if ( schedulers[i]->global_init && schedulers[i]->global_init() < 0 ) + schedulers[i] = NULL; + else if ( !ops.name && !strcmp(schedulers[i]->opt_name, opt_sched) ) + ops = *schedulers[i]; } - if ( schedulers[i] == NULL ) + if ( !ops.name ) { printk("Could not find scheduler: %s\n", opt_sched); - ops = *schedulers[0]; + for ( i = 0; i < ARRAY_SIZE(schedulers); i++ ) + if ( schedulers[i] ) + { + ops = *schedulers[i]; + break; + } + BUG_ON(!ops.name); + printk("Using '%s' (%s)\n", ops.name, ops.opt_name); } if ( cpu_schedule_up(0) ) @@ -1407,8 +1414,8 @@ struct scheduler *scheduler_alloc(unsign int i; struct scheduler *sched; - for ( i = 0; schedulers[i] != NULL; i++ ) - if ( schedulers[i]->sched_id == sched_id ) + for ( i = 0; i < ARRAY_SIZE(schedulers); i++ ) + if ( schedulers[i] && schedulers[i]->sched_id == sched_id ) goto found; *perr = -ENOENT; return NULL; --- a/xen/common/sched_credit2.c +++ b/xen/common/sched_credit2.c @@ -2010,7 +2010,8 @@ csched_cpu_starting(int cpu) /* Hope this is safe from cpupools switching things around. :-) */ ops = per_cpu(scheduler, cpu); - init_pcpu(ops, cpu); + if ( ops->alloc_pdata == csched_alloc_pdata ) + init_pcpu(ops, cpu); return NOTIFY_DONE; } @@ -2038,6 +2039,13 @@ static struct notifier_block cpu_credit2 }; static int +csched_global_init(void) +{ + register_cpu_notifier(&cpu_credit2_nfb); + return 0; +} + +static int csched_init(struct scheduler *ops) { int i; @@ -2070,8 +2078,6 @@ csched_init(struct scheduler *ops) spin_lock_init(&prv->lock); INIT_LIST_HEAD(&prv->sdom); - register_cpu_notifier(&cpu_credit2_nfb); - /* But un-initialize all runqueues */ for ( i=0; i