summaryrefslogtreecommitdiff
path: root/kern
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2014-01-13 23:13:01 +0100
committerRichard Braun <rbraun@sceen.net>2014-01-14 01:35:17 +0100
commit9d998f839452b005401b00c76fd8d03ca062e096 (patch)
tree6537e14ac3a031ac23ca909079003fd07f31abba /kern
parentcbca7bb4f1f59aee176aeb79a69fafd51e17b267 (diff)
Rework bootstrapping
Start application processors once the kernel is completely initialized, right before starting the scheduler. This simplifies the procedure with regard to inter-processor pmap updates.
Diffstat (limited to 'kern')
-rw-r--r--kern/kernel.c28
-rw-r--r--kern/thread.c22
-rw-r--r--kern/thread.h4
3 files changed, 21 insertions, 33 deletions
diff --git a/kern/kernel.c b/kern/kernel.c
index d636d54a..ea11bf2b 100644
--- a/kern/kernel.c
+++ b/kern/kernel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, 2013 Richard Braun.
+ * Copyright (c) 2011-2014 Richard Braun.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,10 +31,6 @@ kernel_main(void)
{
assert(!cpu_intr_enabled());
- /* Enable interrupts to allow inter-processor pmap updates */
- cpu_intr_enable();
-
- /* Initialize the kernel */
rdxtree_setup();
cpumap_setup();
task_setup();
@@ -42,11 +38,13 @@ kernel_main(void)
work_setup();
llsync_setup();
- /* Rendezvous with APs */
- cpu_mp_sync();
+ /*
+ * Enabling application processors must be the last step before starting
+ * the scheduler.
+ */
+ cpu_mp_setup();
- /* Run the scheduler */
- thread_run();
+ thread_run_scheduler();
/* Never reached */
}
@@ -56,17 +54,7 @@ kernel_ap_main(void)
{
assert(!cpu_intr_enabled());
- /*
- * Enable interrupts to allow inter-processor pmap updates while the BSP
- * is initializing the kernel.
- */
- cpu_intr_enable();
-
- /* Wait for the BSP to complete kernel initialization */
- cpu_ap_sync();
-
- /* Run the scheduler */
- thread_run();
+ thread_run_scheduler();
/* Never reached */
}
diff --git a/kern/thread.c b/kern/thread.c
index 1d679bb6..3606279d 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -1324,17 +1324,14 @@ thread_bootstrap_common(unsigned int cpu)
cpumap_set(&thread_active_runqs, cpu);
- booter = &thread_booters[cpu];
-
/* Initialize only what's needed during bootstrap */
+ booter = &thread_booters[cpu];
booter->flags = 0;
booter->preempt = 1;
booter->sched_class = THREAD_SCHED_CLASS_IDLE;
cpumap_fill(&booter->cpumap);
booter->task = kernel_task;
-
thread_runq_init(&thread_runqs[cpu], booter);
- tcb_set_current(&booter->tcb);
}
void __init
@@ -1380,12 +1377,13 @@ thread_bootstrap(void)
thread_ts_highest_round = THREAD_TS_INITIAL_ROUND;
thread_bootstrap_common(0);
+ tcb_set_current(&thread_booters[0].tcb);
}
void __init
thread_ap_bootstrap(void)
{
- thread_bootstrap_common(cpu_id());
+ tcb_set_current(&thread_booters[cpu_id()].tcb);
}
static void
@@ -1706,7 +1704,10 @@ thread_setup_runq(struct thread_runq *runq)
void __init
thread_setup(void)
{
- int i;
+ int cpu;
+
+ for (cpu = 1; (unsigned int)cpu < cpu_count(); cpu++)
+ thread_bootstrap_common(cpu);
kmem_cache_init(&thread_cache, "thread", sizeof(struct thread),
CPU_L1_SIZE, NULL, NULL, NULL, 0);
@@ -1715,8 +1716,8 @@ thread_setup(void)
thread_setup_reaper();
- cpumap_for_each(&thread_active_runqs, i)
- thread_setup_runq(&thread_runqs[i]);
+ cpumap_for_each(&thread_active_runqs, cpu)
+ thread_setup_runq(&thread_runqs[cpu]);
}
int
@@ -1878,12 +1879,12 @@ thread_wakeup(struct thread *thread)
}
void __init
-thread_run(void)
+thread_run_scheduler(void)
{
struct thread_runq *runq;
struct thread *thread;
- assert(cpu_intr_enabled());
+ assert(!cpu_intr_enabled());
runq = thread_runq_local();
llsync_register_cpu(thread_runq_id(runq));
@@ -1891,7 +1892,6 @@ thread_run(void)
assert(thread == runq->current);
assert(thread->preempt == 1);
- cpu_intr_disable();
spinlock_lock(&runq->lock);
thread = thread_runq_get_next(thread_runq_local());
diff --git a/kern/thread.h b/kern/thread.h
index ea6c82e4..0efb8268 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -239,9 +239,9 @@ void thread_wakeup(struct thread *thread);
/*
* Start running threads on the local processor.
*
- * Interrupts must be enabled when calling this function.
+ * Interrupts must be disabled when calling this function.
*/
-void __noreturn thread_run(void);
+void __noreturn thread_run_scheduler(void);
/*
* Make the calling thread release the processor.