Skip to content

Commit

Permalink
boot: remove redundant initialization
Browse files Browse the repository at this point in the history
All architectures run the same generic kernel init.

Signed-off-by: Axel Heider <[email protected]>
  • Loading branch information
axel-h committed Jun 21, 2023
1 parent 04688ec commit 2f2fbb9
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 116 deletions.
18 changes: 6 additions & 12 deletions include/kernel/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,9 @@ static inline BOOT_CODE pptr_t it_alloc_paging(void)
/* return the amount of paging structures required to cover v_reg */
word_t arch_get_n_paging(v_region_t it_veg);

#ifdef ENABLE_SMP_CLOCK_SYNC_TEST_ON_BOOT
/* Test whether clocks are synchronised across nodes */
void clock_sync_test(void);
#define SMP_CLOCK_SYNC_TEST_UPDATE_TIME() \
do { \
NODE_STATE(ksCurTime) = getCurrentTime(); \
__atomic_thread_fence(__ATOMIC_RELEASE); \
} while(0)
#else
#define clock_sync_test()
#define SMP_CLOCK_SYNC_TEST_UPDATE_TIME() ((void)0)
#endif
bool_t finalize_init_kernel(void);

#ifdef ENABLE_SMP_SUPPORT
void release_secondary_cores(void);
bool_t finalize_init_kernel_on_secondary_core(void);
#endif /* ENABLE_SMP_SUPPORT*/
33 changes: 3 additions & 30 deletions src/arch/arm/kernel/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,17 +277,11 @@ BOOT_CODE static bool_t try_init_kernel_secondary_core(void)
setIRQState(IRQReserved, CORE_IRQ_TO_IRQT(getCurrentCPUIndex(), INTERRUPT_VGIC_MAINTENANCE));
setIRQState(IRQReserved, CORE_IRQ_TO_IRQT(getCurrentCPUIndex(), INTERRUPT_VTIMER_EVENT));
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
NODE_LOCK_SYS;

clock_sync_test();
ksNumCPUs++;

init_core_state(SchedulerAction_ResumeCurrentThread);

return true;
return finalize_init_kernel_on_secondary_core();
}

BOOT_CODE static void release_secondary_cpus(void)
BOOT_CODE void release_secondary_cores(void)
{
SMP_CLOCK_SYNC_TEST_UPDATE_TIME();

Expand Down Expand Up @@ -606,21 +600,7 @@ static BOOT_CODE bool_t try_init_kernel(

ksNumCPUs = 1;

/* initialize BKL before booting up other cores */
SMP_COND_STATEMENT(clh_lock_init());
SMP_COND_STATEMENT(release_secondary_cpus());

/* All cores are up now, so there can be concurrency. The kernel booting is
* supposed to be finished before the secondary cores are released, all the
* primary has to do now is schedule the initial thread. Currently there is
* nothing that touches any global data structures, nevertheless we grab the
* BKL here to play safe. It is released when the kernel is left. */
NODE_LOCK_SYS;

printf("Booting all finished, dropped to user space\n");

/* kernel successfully initialized */
return true;
return finalize_init_kernel();
}

BOOT_CODE VISIBLE void init_kernel(
Expand Down Expand Up @@ -659,11 +639,4 @@ BOOT_CODE VISIBLE void init_kernel(
fail("ERROR: kernel init failed");
UNREACHABLE();
}

#ifdef CONFIG_KERNEL_MCS
NODE_STATE(ksCurTime) = getCurrentTime();
NODE_STATE(ksConsumed) = 0;
#endif
schedule();
activateThread();
}
30 changes: 3 additions & 27 deletions src/arch/riscv/kernel/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,11 @@ BOOT_CODE static bool_t try_init_kernel_secondary_core(word_t hart_id, word_t co
fence_r_rw();

init_cpu();
NODE_LOCK_SYS;

clock_sync_test();
ksNumCPUs++;
init_core_state(SchedulerAction_ResumeCurrentThread);
ifence_local();
return true;
return finalize_init_kernel_on_secondary_core();
}

BOOT_CODE static void release_secondary_cores(void)
BOOT_CODE void release_secondary_cores(void)
{
SMP_CLOCK_SYNC_TEST_UPDATE_TIME();

Expand Down Expand Up @@ -450,18 +445,7 @@ static BOOT_CODE bool_t try_init_kernel(

ksNumCPUs = 1;

SMP_COND_STATEMENT(clh_lock_init());
SMP_COND_STATEMENT(release_secondary_cores());

/* All cores are up now, so there can be concurrency. The kernel booting is
* supposed to be finished before the secondary cores are released, all the
* primary has to do now is schedule the initial thread. Currently there is
* nothing that touches any global data structures, nevertheless we grab the
* BKL here to play safe. It is released when the kernel is left. */
NODE_LOCK_SYS;

printf("Booting all finished, dropped to user space\n");
return true;
return finalize_init_kernel();
}

BOOT_CODE VISIBLE void init_kernel(
Expand Down Expand Up @@ -504,12 +488,4 @@ BOOT_CODE VISIBLE void init_kernel(
fail("ERROR: kernel init failed");
UNREACHABLE();
}

#ifdef CONFIG_KERNEL_MCS
NODE_STATE(ksCurTime) = getCurrentTime();
NODE_STATE(ksConsumed) = 0;
#endif

schedule();
activateThread();
}
24 changes: 4 additions & 20 deletions src/arch/x86/kernel/boot_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,16 +500,7 @@ static BOOT_CODE bool_t try_boot_sys(void)
ioapic_init(1, boot_state.cpus, boot_state.num_ioapic);
}

/* initialize BKL before booting up APs */
SMP_COND_STATEMENT(clh_lock_init());
SMP_COND_STATEMENT(start_boot_aps());

/* grab BKL before leaving the kernel */
NODE_LOCK_SYS;

printf("Booting all finished, dropped to user space\n");

return true;
return finalize_init_kernel();
}

static BOOT_CODE bool_t try_boot_sys_mbi1(
Expand Down Expand Up @@ -710,7 +701,7 @@ BOOT_CODE VISIBLE void boot_sys(
unsigned long multiboot_magic,
void *mbi)
{
switch(multiboot_magic) {
switch (multiboot_magic) {
case MULTIBOOT_MAGIC:
if (!try_boot_sys_mbi1(mbi)) {
fail("try_boot_sys_mbi1 failed\n");
Expand All @@ -726,15 +717,8 @@ BOOT_CODE VISIBLE void boot_sys(
break;
}

if (!try_boot_sys())
if (!try_boot_sys()) {
fail("boot_sys failed for some reason :(\n");
UNREACHABLE();
}

#ifdef CONFIG_KERNEL_MCS
NODE_STATE(ksCurTime) = getCurrentTime();
NODE_STATE(ksConsumed) = 0;
#endif

schedule();
activateThread();
}
36 changes: 10 additions & 26 deletions src/arch/x86/kernel/smp_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ BOOT_CODE static void start_cpu(cpu_id_t cpu_id, paddr_t boot_fun_paddr)
apic_send_startup_ipi(cpu_id, boot_fun_paddr);
}

BOOT_CODE void start_boot_aps(void)
BOOT_CODE void release_secondary_cores(void)
{
/* update cpu mapping for BSP, cpus[0] is always assumed to be BSP */
cpu_mapping.index_to_cpu_id[getCurrentCPUIndex()] = boot_state.cpus[0];
Expand Down Expand Up @@ -96,46 +96,30 @@ BOOT_CODE bool_t copy_boot_code_aps(uint32_t mem_lower)
return true;
}

static BOOT_CODE bool_t try_boot_node(void)
/* This is the entry function for APs. However, it is not a BOOT_CODE as
* there is a race between exiting this function and root task running on
* node #0 to possibly reallocate this memory */
VISIBLE void boot_node(void)
{
mode_init_tls(ksNumCPUs);

setCurrentVSpaceRoot(kpptr_to_paddr(X86_KERNEL_VSPACE_ROOT), 0);
/* Sync up the compilers view of the world here to force the PD to actually
* be set *right now* instead of delayed */
x86_mfence();

/* initialise the CPU, make sure legacy interrupts are disabled */
if (!init_cpu(1)) {
return false;
fail("init_cpu failed\n");
}

#ifdef CONFIG_USE_LOGICAL_IDS
update_logical_id_mappings();
#endif /* CONFIG_USE_LOGICAL_IDS */
return true;
}

/* This is the entry function for APs. However, it is not a BOOT_CODE as
* there is a race between exiting this function and root task running on
* node #0 to possibly reallocate this memory */
VISIBLE void boot_node(void)
{
mode_init_tls(ksNumCPUs);

if (!try_boot_node()) {
fail("boot_node failed for some reason :(\n");
if (!finalize_init_kernel_on_secondary_core()) {
fail("finalize_init_kernel_on_secondary_core failed for some reason :(\n");
}

clock_sync_test();

ksNumCPUs++;
__atomic_thread_fence(__ATOMIC_RELEASE);

/* grab BKL before leaving the kernel */
NODE_LOCK_SYS;

init_core_state(SchedulerAction_ChooseNewThread);
schedule();
activateThread();
}

#endif /* ENABLE_SMP_SUPPORT */
63 changes: 62 additions & 1 deletion src/kernel/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ BOOT_CODE tcb_t *create_initial_thread(cap_t root_cnode_cap, cap_t it_pd_cap, vp
}

#ifdef ENABLE_SMP_CLOCK_SYNC_TEST_ON_BOOT
BOOT_CODE void clock_sync_test(void)
static BOOT_CODE void clock_sync_test(void)
{
/* This must be called on secondary cores only. */
word_t core_idx = getCurrentCPUIndex();
Expand Down Expand Up @@ -1059,3 +1059,64 @@ BOOT_CODE bool_t init_freemem(word_t n_available, const p_region_t *available,
"objects, need size/alignment of 2^%"SEL4_PRIu_word"\n", max);
return false;
}

static BOOT_CODE bool_t run_kernel(void)
{
#ifdef CONFIG_KERNEL_MCS
/* Ensure the most recent timestamp is used. */
NODE_STATE(ksCurTime) = getCurrentTime();
#endif
schedule();
activateThread();
return true;
}

BOOT_CODE bool_t finalize_init_kernel()
{
SMP_COND_STATEMENT(clh_lock_init());
/* grab the BKL before releasing the secondary cores, so they cannot
* overtake the primary core
*/
NODE_LOCK_SYS;
SMP_COND_STATEMENT(release_secondary_cores());
printf("Booting all finished, dropped to user space\n");
return run_kernel();
}

#ifdef ENABLE_SMP_SUPPORT

BOOT_CODE bool_t finalize_init_kernel_on_secondary_core(void)
{

#ifdef ENABLE_SMP_CLOCK_SYNC_TEST_ON_BOOT
clock_sync_test();
#endif

/* The primary core spins waiting for this value to increase. Ensure the
* values is also visible in the primary core. */
ksNumCPUs++;
__atomic_thread_fence(__ATOMIC_RELEASE);

/* Now there can be concurrency, as other secondary cores are also starting
* up. Everything that affects global data should only be done with the
* BLK held.
*/

init_core_state(SchedulerAction_ResumeCurrentThread);


#ifdef CONFIG_ARCH_RISCV
/* ToDo: Is this really needed? Should this be generic? */
ifence_local();
#endif
/* The primary core holds the BKL until is has finished booting, Grabbing
* the BKL here ensure secondary cores will not drop to userland before
* the primary core did this. However, there is a change that userland my
* issues a kernel call that grabs the BLK again before a secondary cores
* finished booting.
*/
NODE_LOCK_SYS;
return run_kernel();
}

#endif /* ENABLE_SMP_SUPPORT */

0 comments on commit 2f2fbb9

Please sign in to comment.