Skip to content

feature(smp): improve hart booting, TLS setup and per-core stack initialization #1678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
3 changes: 3 additions & 0 deletions src/arch/riscv64/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,12 @@ fn finish_processor_init() {
pub fn boot_next_processor() {
let new_hart_mask = HART_MASK.load(Ordering::Relaxed);

debug!("Current HART_MASK: 0x{new_hart_mask:x}");
let next_hart_index = lsb(new_hart_mask);

if let Some(next_hart_id) = next_hart_index {
debug!("Preparing to start HART {next_hart_id}");

{
let stack = physicalmem::allocate(KERNEL_STACK_SIZE)
.expect("Failed to allocate boot stack for new core");
Expand Down
4 changes: 2 additions & 2 deletions src/arch/riscv64/kernel/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ impl TaskTLS {
let tls_start = VirtAddr::new(tls_info.start);
// Yes, it does, so we have to allocate TLS memory.
// Allocate enough space for the given size and one more variable of type usize, which holds the tls_pointer.
let tls_allocation_size = tls_size.align_up(32usize); // + mem::size_of::<usize>();
let tls_allocation_size = tls_size.align_up(tls_info.align as usize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not convinced that this is correct. According to the comment above, this increases the size of the allocation size to hold a pointer. Aligning up by 32 bytes is a bad way to do this, but aligning the size up by the required alignment is more wrong than before.

The memory is overaligned by 128 bytes anyway further down.

What do you think?

// We allocate in 128 byte granularity (= cache line size) to avoid false sharing
let memory_size = tls_allocation_size.align_up(128usize);
let layout =
Expand Down Expand Up @@ -311,7 +311,7 @@ impl TaskTLS {
}

debug!(
"Set up TLS at 0x{tls_pointer:x}, tdata_size 0x{tdata_size:x}, tls_size 0x{tls_size:x}"
"Set up TLS at {tls_pointer:#x}, tdata_size {tdata_size:#x}, tls_size {tls_size:#x}"
);

Some(Box::new(Self {
Expand Down
35 changes: 21 additions & 14 deletions src/arch/riscv64/kernel/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,26 @@ unsafe extern "C" fn pre_init(hart_id: usize, boot_info: Option<&'static RawBoot
CURRENT_BOOT_ID.store(hart_id as u32, Ordering::Relaxed);

if CPU_ONLINE.load(Ordering::Acquire) == 0 {
unsafe {
env::set_boot_info(*boot_info.unwrap());
let fdt = Fdt::from_ptr(get_dtb_ptr()).expect("FDT is invalid");
// Init HART_MASK
let mut hart_mask = 0;
for cpu in fdt.cpus() {
let hart_id = cpu.property("reg").unwrap().as_usize().unwrap();
let status = cpu.property("status").unwrap().as_str().unwrap();
// Boot CPU Initialization
env::set_boot_info(*boot_info.unwrap());
let fdt = unsafe { Fdt::from_ptr(get_dtb_ptr()) }.expect("FDT is invalid");

if status != "disabled\u{0}" {
hart_mask |= 1 << hart_id;
}
// Build HART_MASK using readable conditional checks
let mut hart_mask = 0u64;
for cpu in fdt.cpus() {
if let Some(cpu_id) = cpu.property("reg").and_then(|p| p.as_usize())
&& cpu
.property("status")
.and_then(|p| p.as_str())
.is_some_and(|s| s != "disabled\u{0}")
{
hart_mask |= 1 << cpu_id;
}
NUM_CPUS.store(fdt.cpus().count().try_into().unwrap(), Ordering::Relaxed);
HART_MASK.store(hart_mask, Ordering::Relaxed);
}

NUM_CPUS.store(fdt.cpus().count().try_into().unwrap(), Ordering::Relaxed);
HART_MASK.store(hart_mask, Ordering::Relaxed);

crate::boot_processor_main()
} else {
#[cfg(not(feature = "smp"))]
Expand All @@ -76,6 +80,9 @@ unsafe extern "C" fn pre_init(hart_id: usize, boot_info: Option<&'static RawBoot
}
}
#[cfg(feature = "smp")]
crate::application_processor_main();
{
// Optimized Secondary-HART initialization
crate::application_processor_main()
}
}
}