chore: move setup_arch_post timepoint to before clocksource_boot_finish (#820)

This commit adjusts the timing of the setup_arch_post event to occur before the clocksource_boot_finish event, allowing the time subsystem to properly register architecture-specific clock sources.
This commit is contained in:
LoGin 2024-05-16 14:06:23 +08:00 committed by GitHub
parent 236e88d5ef
commit 92deae638b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 29 deletions

View File

@ -12,7 +12,7 @@ pub const ACPI_PM_MASK: u64 = 0xffffff;
pub fn acpi_pm_read_early() -> u32 {
use crate::driver::clocksource::acpi_pm::{acpi_pm_read_verified, PMTMR_IO_PORT};
use core::sync::atomic::Ordering;
let port = unsafe { PMTMR_IO_PORT.load(Ordering::SeqCst) };
let port = PMTMR_IO_PORT.load(Ordering::SeqCst);
// 如果端口为零直接返回
if port == 0 {

View File

@ -20,7 +20,7 @@ use system_error::SystemError;
// 参考https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/clocksource/acpi_pm.c
/// acpi_pmtmr所在的I/O端口
pub static mut PMTMR_IO_PORT: AtomicU32 = AtomicU32::new(0);
pub static PMTMR_IO_PORT: AtomicU32 = AtomicU32::new(0);
/// # 读取acpi_pmtmr当前值并对齐进行掩码操作
#[inline(always)]
@ -206,12 +206,13 @@ fn find_acpi_pm_clock() -> Result<(), SystemError> {
let pm_timer_block = fadt.pm_timer_block().map_err(|_| SystemError::ENODEV)?;
let pm_timer_block = pm_timer_block.ok_or(SystemError::ENODEV)?;
let pmtmr_addr = pm_timer_block.address;
unsafe {
PMTMR_IO_PORT.store(pmtmr_addr as u32, Ordering::SeqCst);
}
kinfo!("apic_pmtmr I/O port: {}", unsafe {
kinfo!(
"apic_pmtmr I/O port: {}",
PMTMR_IO_PORT.load(Ordering::SeqCst)
});
);
return Ok(());
}
@ -222,18 +223,19 @@ fn find_acpi_pm_clock() -> Result<(), SystemError> {
#[allow(dead_code)]
pub fn init_acpi_pm_clocksource() -> Result<(), SystemError> {
let acpi_pm = Acpipm::new();
unsafe {
CLOCKSOURCE_ACPI_PM = Some(acpi_pm);
}
// 解析fadt
find_acpi_pm_clock()?;
// 检查pmtmr_io_port是否被设置
if unsafe { PMTMR_IO_PORT.load(Ordering::SeqCst) } == 0 {
if PMTMR_IO_PORT.load(Ordering::SeqCst) == 0 {
return Err(SystemError::ENODEV);
}
unsafe {
CLOCKSOURCE_ACPI_PM = Some(acpi_pm);
}
// 验证ACPI PM Timer作为时钟源的稳定性和一致性
for j in 0..ACPI_PM_MONOTONIC_CHECKS {
let mut cnt = 100 * j;
@ -256,26 +258,24 @@ pub fn init_acpi_pm_clocksource() -> Result<(), SystemError> {
break;
}
kinfo!("PM Timer had inconsistens results: {} {}", value1, value2);
unsafe {
PMTMR_IO_PORT.store(0, Ordering::SeqCst);
}
return Err(SystemError::EINVAL);
}
if i == ACPI_PM_READ_CHECKS {
kinfo!("PM Timer failed consistency check: {}", value1);
unsafe {
PMTMR_IO_PORT.store(0, Ordering::SeqCst);
}
return Err(SystemError::EINVAL);
}
}
// 检查ACPI PM Timer的频率是否正确
if !verify_pmtmr_rate() {
unsafe {
PMTMR_IO_PORT.store(0, Ordering::SeqCst);
}
}
// 检查TSC时钟源的监视器是否被禁用如果被禁用则将时钟源的标志设置为CLOCK_SOURCE_MUST_VERIFY
// 没有实现clocksource_selecet_watchdog函数所以这里设置为false

View File

@ -75,12 +75,11 @@ fn do_start_kernel() {
time_init();
timer_init();
kthread_init();
setup_arch_post().expect("setup_arch_post failed");
clocksource_boot_finish();
Futex::init();
setup_arch_post().expect("setup_arch_post failed");
#[cfg(all(target_arch = "x86_64", feature = "kvm"))]
crate::virt::kvm::kvm_init();
}

View File

@ -53,7 +53,7 @@ static mut WATCHDOG_KTHREAD: Option<Arc<ProcessControlBlock>> = None;
/// 正在被使用时钟源
pub static CUR_CLOCKSOURCE: SpinLock<Option<Arc<dyn Clocksource>>> = SpinLock::new(None);
/// 是否完成加载
pub static mut FINISHED_BOOTING: AtomicBool = AtomicBool::new(false);
pub static FINISHED_BOOTING: AtomicBool = AtomicBool::new(false);
/// Interval: 0.5sec Threshold: 0.0625s
/// 系统节拍率
@ -487,7 +487,7 @@ impl dyn Clocksource {
self.update_clocksource_data(cs_data)?;
// 启动watchdog线程 进行后续处理
if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } {
if FINISHED_BOOTING.load(Ordering::Relaxed) {
// TODO 在实现了工作队列后将启动线程换成schedule work
run_watchdog_kthread();
}
@ -948,7 +948,7 @@ pub fn clocksource_resume_watchdog() {
/// # 根据精度选择最优的时钟源,或者接受用户指定的时间源
pub fn clocksource_select() {
let list_guard = CLOCKSOURCE_LIST.lock();
if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } || list_guard.is_empty() {
if FINISHED_BOOTING.load(Ordering::Relaxed) || list_guard.is_empty() {
return;
}
let mut best = list_guard.front().unwrap().clone();
@ -971,21 +971,21 @@ pub fn clocksource_select() {
if cur_clocksource.clocksource_data().name.ne(best_name) {
kinfo!("Switching to the clocksource {:?}\n", best_name);
drop(cur_clocksource);
CUR_CLOCKSOURCE.lock().replace(best);
CUR_CLOCKSOURCE.lock().replace(best.clone());
// TODO 通知timerkeeping 切换了时间源
}
} else {
// 当前时钟源为空
CUR_CLOCKSOURCE.lock().replace(best);
CUR_CLOCKSOURCE.lock().replace(best.clone());
}
kdebug!(" clocksource_select finish");
kdebug!("clocksource_select finish, CUR_CLOCKSOURCE = {best:?}");
}
/// # clocksource模块加载完成
pub fn clocksource_boot_finish() {
let mut cur_clocksource = CUR_CLOCKSOURCE.lock();
cur_clocksource.replace(clocksource_default_clock());
unsafe { FINISHED_BOOTING.store(true, Ordering::Relaxed) };
FINISHED_BOOTING.store(true, Ordering::Relaxed);
// 清除不稳定的时钟源
__clocksource_watchdog_kthread();
kdebug!("clocksource_boot_finish");