diff options
author | Richard Braun <rbraun@sceen.net> | 2014-01-13 23:13:01 +0100 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2014-01-14 01:35:17 +0100 |
commit | 9d998f839452b005401b00c76fd8d03ca062e096 (patch) | |
tree | 6537e14ac3a031ac23ca909079003fd07f31abba /kern | |
parent | cbca7bb4f1f59aee176aeb79a69fafd51e17b267 (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.c | 28 | ||||
-rw-r--r-- | kern/thread.c | 22 | ||||
-rw-r--r-- | kern/thread.h | 4 |
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. |