aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xen/arch/x86/nmi.c12
-rw-r--r--xen/arch/x86/setup.c2
-rw-r--r--xen/common/cpu.c3
-rw-r--r--xen/common/notifier.c4
-rw-r--r--xen/common/sched_credit2.c13
-rw-r--r--xen/common/schedule.c25
-rw-r--r--xen/include/asm-x86/config.h1
-rw-r--r--xen/include/xen/sched-if.h2
8 files changed, 41 insertions, 21 deletions
diff --git a/xen/arch/x86/nmi.c b/xen/arch/x86/nmi.c
index f3155e8b76..6730f29a0a 100644
--- 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)
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 0478079dbc..de28445b6e 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1259,7 +1259,7 @@ void __init __start_xen(unsigned long mbi_p)
do_initcalls();
if ( opt_watchdog )
- watchdog_enable();
+ watchdog_setup();
if ( !tboot_protect_mem_regions() )
panic("Could not protect TXT memory regions\n");
diff --git a/xen/common/cpu.c b/xen/common/cpu.c
index 5cdfd0fb10..396eb58ad8 100644
--- a/xen/common/cpu.c
+++ b/xen/common/cpu.c
@@ -2,6 +2,7 @@
#include <xen/cpumask.h>
#include <xen/cpu.h>
#include <xen/event.h>
+#include <xen/init.h>
#include <xen/sched.h>
#include <xen/stop_machine.h>
@@ -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. */
diff --git a/xen/common/notifier.c b/xen/common/notifier.c
index ea1ebdeffe..5924b56deb 100644
--- 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);
diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c
index 12810c3ba4..792d662575 100644
--- 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_nfb = {
};
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<NR_CPUS; i++)
{
@@ -2120,6 +2126,7 @@ const struct scheduler sched_credit2_def = {
.dump_cpu_state = csched_dump_pcpu,
.dump_settings = csched_dump,
+ .global_init = csched_global_init,
.init = csched_init,
.deinit = csched_deinit,
.alloc_vdata = csched_alloc_vdata,
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 129abe44e4..5efb822a81 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -66,7 +66,6 @@ static const struct scheduler *schedulers[] = {
&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(unsigned int sched_id, int *perr)
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;
diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
index 27c766d2db..e3a7868caa 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -393,6 +393,7 @@ extern unsigned long xenheap_phys_end;
#ifndef __ASSEMBLY__
extern void watchdog_disable(void);
extern void watchdog_enable(void);
+extern void watchdog_setup(void);
#endif
#endif /* __X86_CONFIG_H__ */
diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h
index e8f0262a6b..486b9fd704 100644
--- a/xen/include/xen/sched-if.h
+++ b/xen/include/xen/sched-if.h
@@ -141,6 +141,8 @@ struct scheduler {
unsigned int sched_id; /* ID for this scheduler */
void *sched_data; /* global data pointer */
+ int (*global_init) (void);
+
int (*init) (struct scheduler *);
void (*deinit) (const struct scheduler *);