136fd0130Shoumkh use core::{ 236fd0130Shoumkh ffi::c_void, 336fd0130Shoumkh fmt::Debug, 436fd0130Shoumkh sync::atomic::{AtomicBool, Ordering}, 536fd0130Shoumkh }; 636fd0130Shoumkh 736fd0130Shoumkh use alloc::{boxed::Box, collections::LinkedList, string::String, sync::Arc, vec::Vec}; 836fd0130Shoumkh use lazy_static::__Deref; 936fd0130Shoumkh 1036fd0130Shoumkh use crate::{ 1136fd0130Shoumkh include::bindings::bindings::run_watchdog_kthread, kdebug, kinfo, libs::spinlock::SpinLock, 1236fd0130Shoumkh syscall::SystemError, 1336fd0130Shoumkh }; 1436fd0130Shoumkh 1536fd0130Shoumkh use super::{ 1636fd0130Shoumkh jiffies::clocksource_default_clock, 1736fd0130Shoumkh timer::{clock, Timer, TimerFunction}, 1836fd0130Shoumkh NSEC_PER_SEC, 1936fd0130Shoumkh }; 2036fd0130Shoumkh 2136fd0130Shoumkh lazy_static! { 2236fd0130Shoumkh /// linked list with the registered clocksources 2336fd0130Shoumkh pub static ref CLOCKSOURCE_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> = 2436fd0130Shoumkh SpinLock::new(LinkedList::new()); 2536fd0130Shoumkh /// 被监视中的时钟源 2636fd0130Shoumkh pub static ref WATCHDOG_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> = 2736fd0130Shoumkh SpinLock::new(LinkedList::new()); 2836fd0130Shoumkh 2936fd0130Shoumkh pub static ref CLOCKSOUCE_WATCHDOG:SpinLock<ClocksouceWatchdog> = SpinLock::new(ClocksouceWatchdog::new()); 3036fd0130Shoumkh 3136fd0130Shoumkh pub static ref OVERRIDE_NAME: SpinLock<String> = SpinLock::new(String::from("")); 3236fd0130Shoumkh 3336fd0130Shoumkh 3436fd0130Shoumkh } 3536fd0130Shoumkh 3636fd0130Shoumkh /// 正在被使用时钟源 3736fd0130Shoumkh pub static CUR_CLOCKSOURCE: SpinLock<Option<Arc<dyn Clocksource>>> = SpinLock::new(None); 3836fd0130Shoumkh /// 是否完成加载 3936fd0130Shoumkh pub static mut FINISHED_BOOTING: AtomicBool = AtomicBool::new(false); 4036fd0130Shoumkh 4136fd0130Shoumkh /// Interval: 0.5sec Threshold: 0.0625s 4236fd0130Shoumkh /// 系统节拍率 43*be8cdf4bSLoGin pub const HZ: u64 = 250; 4436fd0130Shoumkh /// watchdog检查间隔 4536fd0130Shoumkh pub const WATCHDOG_INTERVAL: u64 = HZ >> 1; 4636fd0130Shoumkh /// 最大能接受的误差大小 4736fd0130Shoumkh pub const WATCHDOG_THRESHOLD: u32 = NSEC_PER_SEC >> 4; 4836fd0130Shoumkh 4936fd0130Shoumkh // 时钟周期数 5036fd0130Shoumkh #[derive(Debug, Clone, Copy)] 5136fd0130Shoumkh #[repr(transparent)] 5236fd0130Shoumkh pub struct CycleNum(pub u64); 5336fd0130Shoumkh 5436fd0130Shoumkh #[allow(dead_code)] 5536fd0130Shoumkh impl CycleNum { 5636fd0130Shoumkh #[inline(always)] 5736fd0130Shoumkh pub fn new(cycle: u64) -> Self { 5836fd0130Shoumkh Self(cycle) 5936fd0130Shoumkh } 6036fd0130Shoumkh #[inline(always)] 6136fd0130Shoumkh pub fn data(&self) -> u64 { 6236fd0130Shoumkh self.0 6336fd0130Shoumkh } 6436fd0130Shoumkh #[inline(always)] 6536fd0130Shoumkh #[allow(dead_code)] 6636fd0130Shoumkh pub fn add(&self, other: CycleNum) -> CycleNum { 6736fd0130Shoumkh CycleNum(self.data() + other.data()) 6836fd0130Shoumkh } 6936fd0130Shoumkh #[inline(always)] 7036fd0130Shoumkh pub fn div(&self, other: CycleNum) -> CycleNum { 7136fd0130Shoumkh CycleNum(self.data() - other.data()) 7236fd0130Shoumkh } 7336fd0130Shoumkh } 7436fd0130Shoumkh 7536fd0130Shoumkh bitflags! { 7636fd0130Shoumkh 7736fd0130Shoumkh #[derive(Default)] 7836fd0130Shoumkh pub struct ClocksourceMask: u64 { 7936fd0130Shoumkh } 8036fd0130Shoumkh /// 时钟状态标记 8136fd0130Shoumkh #[derive(Default)] 8236fd0130Shoumkh pub struct ClocksourceFlags: u64 { 8336fd0130Shoumkh /// 表示时钟设备是连续的 8436fd0130Shoumkh const CLOCK_SOURCE_IS_CONTINUOUS = 0x01; 8536fd0130Shoumkh /// 表示该时钟源需要经过watchdog检查 8636fd0130Shoumkh const CLOCK_SOURCE_MUST_VERIFY = 0x02; 8736fd0130Shoumkh /// 表示该时钟源是watchdog 8836fd0130Shoumkh const CLOCK_SOURCE_WATCHDOG = 0x10; 8936fd0130Shoumkh /// 表示该时钟源是高分辨率的 9036fd0130Shoumkh const CLOCK_SOURCE_VALID_FOR_HRES = 0x20; 9136fd0130Shoumkh /// 表示该时钟源误差过大 9236fd0130Shoumkh const CLOCK_SOURCE_UNSTABLE = 0x40; 9336fd0130Shoumkh } 9436fd0130Shoumkh } 9536fd0130Shoumkh impl From<u64> for ClocksourceMask { 9636fd0130Shoumkh fn from(value: u64) -> Self { 9736fd0130Shoumkh if value < 64 { 9836fd0130Shoumkh return Self::from_bits_truncate((1 << value) - 1); 9936fd0130Shoumkh } 10036fd0130Shoumkh return Self::from_bits_truncate(u64::MAX); 10136fd0130Shoumkh } 10236fd0130Shoumkh } 10336fd0130Shoumkh impl ClocksourceMask { 10436fd0130Shoumkh pub fn new(b: u64) -> Self { 10536fd0130Shoumkh Self { bits: b } 10636fd0130Shoumkh } 10736fd0130Shoumkh } 10836fd0130Shoumkh impl ClocksourceFlags { 10936fd0130Shoumkh pub fn new(b: u64) -> Self { 11036fd0130Shoumkh Self { bits: b } 11136fd0130Shoumkh } 11236fd0130Shoumkh } 11336fd0130Shoumkh 11436fd0130Shoumkh #[derive(Debug)] 11536fd0130Shoumkh pub struct ClocksouceWatchdog { 11636fd0130Shoumkh /// 监视器 11736fd0130Shoumkh watchdog: Option<Arc<dyn Clocksource>>, 11836fd0130Shoumkh /// 检查器是否在工作的标志 11936fd0130Shoumkh is_running: bool, 12036fd0130Shoumkh /// 上一次检查的时刻 12136fd0130Shoumkh last_check: CycleNum, 12236fd0130Shoumkh /// 定时监视器的过期时间 12336fd0130Shoumkh timer_expires: u64, 12436fd0130Shoumkh } 12536fd0130Shoumkh impl ClocksouceWatchdog { 12636fd0130Shoumkh pub fn new() -> Self { 12736fd0130Shoumkh Self { 12836fd0130Shoumkh watchdog: None, 12936fd0130Shoumkh is_running: false, 13036fd0130Shoumkh last_check: CycleNum(0), 13136fd0130Shoumkh timer_expires: 0, 13236fd0130Shoumkh } 13336fd0130Shoumkh } 13436fd0130Shoumkh 13536fd0130Shoumkh /// 获取watchdog 13636fd0130Shoumkh fn get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>> { 13736fd0130Shoumkh &mut self.watchdog 13836fd0130Shoumkh } 13936fd0130Shoumkh 14036fd0130Shoumkh /// 启用检查器 14136fd0130Shoumkh pub fn clocksource_start_watchdog(&mut self) { 14236fd0130Shoumkh // 如果watchdog未被设置或者已经启用了就退出 14336fd0130Shoumkh let watchdog_list = &WATCHDOG_LIST.lock(); 14436fd0130Shoumkh if self.is_running || self.watchdog.is_none() || watchdog_list.is_empty() { 14536fd0130Shoumkh return; 14636fd0130Shoumkh } 14736fd0130Shoumkh // 生成一个定时器 14836fd0130Shoumkh let wd_timer_func: Box<WatchdogTimerFunc> = Box::new(WatchdogTimerFunc {}); 14936fd0130Shoumkh self.timer_expires += clock() + WATCHDOG_INTERVAL; 15036fd0130Shoumkh self.last_check = self.watchdog.as_ref().unwrap().clone().read(); 15136fd0130Shoumkh let wd_timer = Timer::new(wd_timer_func, self.timer_expires); 15236fd0130Shoumkh wd_timer.activate(); 15336fd0130Shoumkh self.is_running = true; 15436fd0130Shoumkh } 15536fd0130Shoumkh 15636fd0130Shoumkh /// 停止检查器 15736fd0130Shoumkh /// list_len WATCHDOG_LIST长度 15836fd0130Shoumkh pub fn clocksource_stop_watchdog(&mut self, list_len: usize) { 15936fd0130Shoumkh if !self.is_running || (self.watchdog.is_some() && list_len != 0) { 16036fd0130Shoumkh return; 16136fd0130Shoumkh } 16236fd0130Shoumkh // TODO 当实现了周期性的定时器后 需要将监视用的定时器删除 16336fd0130Shoumkh self.is_running = false; 16436fd0130Shoumkh } 16536fd0130Shoumkh } 16636fd0130Shoumkh 16736fd0130Shoumkh /// 定时检查器 16836fd0130Shoumkh #[derive(Debug)] 16936fd0130Shoumkh pub struct WatchdogTimerFunc; 17036fd0130Shoumkh impl TimerFunction for WatchdogTimerFunc { 17136fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError> { 17236fd0130Shoumkh return clocksource_watchdog(); 17336fd0130Shoumkh } 17436fd0130Shoumkh } 17536fd0130Shoumkh 17636fd0130Shoumkh /// 时钟源的特性 17736fd0130Shoumkh pub trait Clocksource: Send + Sync + Debug { 17836fd0130Shoumkh // TODO 返回值类型可能需要改变 17936fd0130Shoumkh /// returns a cycle value, passes clocksource as argument 18036fd0130Shoumkh fn read(&self) -> CycleNum; 18136fd0130Shoumkh /// optional function to enable the clocksource 18236fd0130Shoumkh fn enable(&self) -> Result<i32, SystemError> { 18336fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 18436fd0130Shoumkh } 18536fd0130Shoumkh /// optional function to disable the clocksource 18636fd0130Shoumkh fn disable(&self) -> Result<(), SystemError> { 18736fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 18836fd0130Shoumkh } 18936fd0130Shoumkh /// vsyscall based read 19036fd0130Shoumkh fn vread(&self) -> Result<CycleNum, SystemError> { 19136fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 19236fd0130Shoumkh } 19336fd0130Shoumkh /// suspend function for the clocksource, if necessary 19436fd0130Shoumkh fn suspend(&self) -> Result<(), SystemError> { 19536fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 19636fd0130Shoumkh } 19736fd0130Shoumkh /// resume function for the clocksource, if necessary 19836fd0130Shoumkh fn resume(&self) -> Result<(), SystemError> { 19936fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 20036fd0130Shoumkh } 20136fd0130Shoumkh // 获取时钟源数据 20236fd0130Shoumkh fn clocksource_data(&self) -> ClocksourceData; 20336fd0130Shoumkh 20436fd0130Shoumkh fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> { 20536fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 20636fd0130Shoumkh } 20736fd0130Shoumkh // 获取时钟源 20836fd0130Shoumkh fn clocksource(&self) -> Arc<dyn Clocksource>; 20936fd0130Shoumkh } 21036fd0130Shoumkh 21136fd0130Shoumkh /// # 实现整数log2的运算 21236fd0130Shoumkh /// 21336fd0130Shoumkh /// ## 参数 21436fd0130Shoumkh /// 21536fd0130Shoumkh /// * `x` - 要计算的数字 21636fd0130Shoumkh /// 21736fd0130Shoumkh /// ## 返回值 21836fd0130Shoumkh /// 21936fd0130Shoumkh /// * `u32` - 返回\log_2(x)的值 22036fd0130Shoumkh fn log2(x: u32) -> u32 { 22136fd0130Shoumkh let mut result = 0; 22236fd0130Shoumkh let mut x = x; 22336fd0130Shoumkh 22436fd0130Shoumkh if x >= 1 << 16 { 22536fd0130Shoumkh x >>= 16; 22636fd0130Shoumkh result |= 16; 22736fd0130Shoumkh } 22836fd0130Shoumkh if x >= 1 << 8 { 22936fd0130Shoumkh x >>= 8; 23036fd0130Shoumkh result |= 8; 23136fd0130Shoumkh } 23236fd0130Shoumkh if x >= 1 << 4 { 23336fd0130Shoumkh x >>= 4; 23436fd0130Shoumkh result |= 4; 23536fd0130Shoumkh } 23636fd0130Shoumkh if x >= 1 << 2 { 23736fd0130Shoumkh x >>= 2; 23836fd0130Shoumkh result |= 2; 23936fd0130Shoumkh } 24036fd0130Shoumkh if x >= 1 << 1 { 24136fd0130Shoumkh result |= 1; 24236fd0130Shoumkh } 24336fd0130Shoumkh 24436fd0130Shoumkh result 24536fd0130Shoumkh } 24636fd0130Shoumkh 24736fd0130Shoumkh impl dyn Clocksource { 24836fd0130Shoumkh /// # 计算时钟源能记录的最大时间跨度 24936fd0130Shoumkh pub fn clocksource_max_deferment(&self) -> u64 { 25036fd0130Shoumkh let cs_data_guard = self.clocksource_data(); 25136fd0130Shoumkh let max_nsecs: u64; 25236fd0130Shoumkh let mut max_cycles: u64; 25336fd0130Shoumkh max_cycles = (1 << (63 - (log2(cs_data_guard.mult) + 1))) as u64; 25436fd0130Shoumkh max_cycles = max_cycles.min(cs_data_guard.mask.bits); 25536fd0130Shoumkh max_nsecs = clocksource_cyc2ns( 25636fd0130Shoumkh CycleNum(max_cycles), 25736fd0130Shoumkh cs_data_guard.mult, 25836fd0130Shoumkh cs_data_guard.shift, 25936fd0130Shoumkh ); 26036fd0130Shoumkh return max_nsecs - (max_nsecs >> 5); 26136fd0130Shoumkh } 26236fd0130Shoumkh 26336fd0130Shoumkh /// # 注册时钟源 26436fd0130Shoumkh /// 26536fd0130Shoumkh /// ## 返回值 26636fd0130Shoumkh /// 26736fd0130Shoumkh /// * `Ok(0)` - 时钟源注册成功。 26836fd0130Shoumkh /// * `Err(SystemError)` - 时钟源注册失败。 26936fd0130Shoumkh pub fn register(&self) -> Result<i32, SystemError> { 27036fd0130Shoumkh let ns = self.clocksource_max_deferment(); 27136fd0130Shoumkh let mut cs_data = self.clocksource_data(); 27236fd0130Shoumkh cs_data.max_idle_ns = ns as u32; 27336fd0130Shoumkh self.update_clocksource_data(cs_data)?; 27436fd0130Shoumkh // 将时钟源加入到时钟源队列中 27536fd0130Shoumkh self.clocksource_enqueue(); 27636fd0130Shoumkh // 将时钟源加入到监视队列中 27736fd0130Shoumkh self.clocksource_enqueue_watchdog() 27836fd0130Shoumkh .expect("register: failed to enqueue watchdog list"); 27936fd0130Shoumkh // 选择一个最好的时钟源 28036fd0130Shoumkh clocksource_select(); 28136fd0130Shoumkh kdebug!("clocksource_register successfully"); 28236fd0130Shoumkh return Ok(0); 28336fd0130Shoumkh } 28436fd0130Shoumkh 28536fd0130Shoumkh /// # 将时钟源插入时钟源队列 28636fd0130Shoumkh pub fn clocksource_enqueue(&self) { 28736fd0130Shoumkh // 根据rating由大到小排序 28836fd0130Shoumkh let cs_data = self.clocksource_data(); 28936fd0130Shoumkh let list_guard = &mut CLOCKSOURCE_LIST.lock(); 29036fd0130Shoumkh let mut spilt_pos: usize = 0; 29136fd0130Shoumkh for (pos, ele) in list_guard.iter().enumerate() { 29236fd0130Shoumkh if ele.clocksource_data().rating < cs_data.rating { 29336fd0130Shoumkh spilt_pos = pos; 29436fd0130Shoumkh break; 29536fd0130Shoumkh } 29636fd0130Shoumkh } 29736fd0130Shoumkh let mut temp_list = list_guard.split_off(spilt_pos); 29836fd0130Shoumkh let cs = self.clocksource(); 29936fd0130Shoumkh list_guard.push_back(cs); 30036fd0130Shoumkh list_guard.append(&mut temp_list); 30136fd0130Shoumkh // kdebug!( 30236fd0130Shoumkh // "CLOCKSOURCE_LIST len = {:?},clocksource_enqueue sccessfully", 30336fd0130Shoumkh // list_guard.len() 30436fd0130Shoumkh // ); 30536fd0130Shoumkh } 30636fd0130Shoumkh 30736fd0130Shoumkh /// # 将时间源插入监控队列 30836fd0130Shoumkh /// 30936fd0130Shoumkh /// ## 返回值 31036fd0130Shoumkh /// 31136fd0130Shoumkh /// * `Ok(0)` - 时间源插入监控队列成功 31236fd0130Shoumkh /// * `Err(SystemError)` - 时间源插入监控队列失败 31336fd0130Shoumkh pub fn clocksource_enqueue_watchdog(&self) -> Result<i32, SystemError> { 31436fd0130Shoumkh // BUG 可能需要lock irq 31536fd0130Shoumkh let mut cs_data = self.clocksource_data(); 31636fd0130Shoumkh 31736fd0130Shoumkh let cs = self.clocksource(); 31836fd0130Shoumkh if cs_data 31936fd0130Shoumkh .flags 32036fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY) 32136fd0130Shoumkh { 32236fd0130Shoumkh let mut list_guard = WATCHDOG_LIST.lock_irqsave(); 32336fd0130Shoumkh // cs是被监视的 32436fd0130Shoumkh cs_data 32536fd0130Shoumkh .flags 32636fd0130Shoumkh .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 32736fd0130Shoumkh cs.update_clocksource_data(cs_data)?; 32836fd0130Shoumkh list_guard.push_back(cs); 32936fd0130Shoumkh } else { 33036fd0130Shoumkh // cs是监视器 33136fd0130Shoumkh if cs_data 33236fd0130Shoumkh .flags 33336fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS) 33436fd0130Shoumkh { 33536fd0130Shoumkh // 如果时钟设备是连续的 33636fd0130Shoumkh cs_data 33736fd0130Shoumkh .flags 33836fd0130Shoumkh .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES); 33936fd0130Shoumkh cs.update_clocksource_data(cs_data.clone())?; 34036fd0130Shoumkh } 34136fd0130Shoumkh 34236fd0130Shoumkh // 将时钟源加入到监控队列中 34336fd0130Shoumkh let mut list_guard = WATCHDOG_LIST.lock(); 34436fd0130Shoumkh list_guard.push_back(cs.clone()); 34536fd0130Shoumkh drop(list_guard); 34636fd0130Shoumkh 34736fd0130Shoumkh // 对比当前注册的时间源的精度和监视器的精度 34836fd0130Shoumkh let cs_watchdog = &mut CLOCKSOUCE_WATCHDOG.lock(); 34936fd0130Shoumkh if cs_watchdog.watchdog.is_none() 35036fd0130Shoumkh || cs_data.rating 35136fd0130Shoumkh > cs_watchdog 35236fd0130Shoumkh .watchdog 35336fd0130Shoumkh .clone() 35436fd0130Shoumkh .unwrap() 35536fd0130Shoumkh .clocksource_data() 35636fd0130Shoumkh .rating 35736fd0130Shoumkh { 35836fd0130Shoumkh // 当前注册的时间源的精度更高或者没有监视器,替换监视器 35936fd0130Shoumkh cs_watchdog.watchdog.replace(cs); 36036fd0130Shoumkh clocksource_reset_watchdog(); 36136fd0130Shoumkh } 36236fd0130Shoumkh 36336fd0130Shoumkh // 启动监视器 36436fd0130Shoumkh cs_watchdog.clocksource_start_watchdog(); 36536fd0130Shoumkh } 36636fd0130Shoumkh return Ok(0); 36736fd0130Shoumkh } 36836fd0130Shoumkh 36936fd0130Shoumkh /// # 将时钟源标记为unstable 37036fd0130Shoumkh /// 37136fd0130Shoumkh /// ## 参数 37236fd0130Shoumkh /// * `delta` - 时钟源误差 37336fd0130Shoumkh pub fn set_unstable(&self, delta: i64) -> Result<i32, SystemError> { 37436fd0130Shoumkh let mut cs_data = self.clocksource_data(); 37536fd0130Shoumkh // 打印出unstable的时钟源信息 37636fd0130Shoumkh kdebug!( 37736fd0130Shoumkh "clocksource :{:?} is unstable, its delta is {:?}", 37836fd0130Shoumkh cs_data.name, 37936fd0130Shoumkh delta 38036fd0130Shoumkh ); 38136fd0130Shoumkh cs_data.flags.remove( 38236fd0130Shoumkh ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES | ClocksourceFlags::CLOCK_SOURCE_WATCHDOG, 38336fd0130Shoumkh ); 38436fd0130Shoumkh cs_data 38536fd0130Shoumkh .flags 38636fd0130Shoumkh .insert(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE); 38736fd0130Shoumkh self.update_clocksource_data(cs_data)?; 38836fd0130Shoumkh 38936fd0130Shoumkh // 启动watchdog线程 进行后续处理 39036fd0130Shoumkh if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } { 39136fd0130Shoumkh // TODO 在实现了工作队列后,将启动线程换成schedule work 39236fd0130Shoumkh unsafe { run_watchdog_kthread() } 39336fd0130Shoumkh } 39436fd0130Shoumkh return Ok(0); 39536fd0130Shoumkh } 39636fd0130Shoumkh 39736fd0130Shoumkh /// # 将时间源从监视链表中弹出 39836fd0130Shoumkh fn clocksource_dequeue_watchdog(&self) { 39936fd0130Shoumkh let data = self.clocksource_data(); 40036fd0130Shoumkh let mut locked_watchdog = CLOCKSOUCE_WATCHDOG.lock(); 40136fd0130Shoumkh let watchdog = locked_watchdog 40236fd0130Shoumkh .get_watchdog() 40336fd0130Shoumkh .clone() 40436fd0130Shoumkh .unwrap() 40536fd0130Shoumkh .clocksource_data(); 40636fd0130Shoumkh 40736fd0130Shoumkh let mut list = WATCHDOG_LIST.lock(); 40836fd0130Shoumkh let mut size = list.len(); 40936fd0130Shoumkh 41036fd0130Shoumkh let mut del_pos: usize = size; 41136fd0130Shoumkh for (pos, ele) in list.iter().enumerate() { 41236fd0130Shoumkh let ele_data = ele.clocksource_data(); 41336fd0130Shoumkh if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) { 41436fd0130Shoumkh // 记录要删除的时钟源在监视链表中的下标 41536fd0130Shoumkh del_pos = pos; 41636fd0130Shoumkh } 41736fd0130Shoumkh } 41836fd0130Shoumkh 41936fd0130Shoumkh if data 42036fd0130Shoumkh .flags 42136fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY) 42236fd0130Shoumkh { 42336fd0130Shoumkh // 如果时钟源是需要被检查的,直接删除时钟源 42436fd0130Shoumkh if del_pos != size { 42536fd0130Shoumkh let mut temp_list = list.split_off(del_pos); 42636fd0130Shoumkh temp_list.pop_front(); 42736fd0130Shoumkh list.append(&mut temp_list); 42836fd0130Shoumkh } 42936fd0130Shoumkh } else if watchdog.name.eq(&data.name) && watchdog.rating.eq(&data.rating) { 43036fd0130Shoumkh // 如果要删除的时钟源是监视器,则需要找到一个新的监视器 43136fd0130Shoumkh // TODO 重新设置时钟源 43236fd0130Shoumkh // 将链表解锁防止reset中双重加锁 并释放保存的旧的watchdog的数据 43336fd0130Shoumkh 43436fd0130Shoumkh // 代替了clocksource_reset_watchdog()的功能,将所有时钟源的watchdog标记清除 43536fd0130Shoumkh for ele in list.iter() { 43636fd0130Shoumkh ele.clocksource_data() 43736fd0130Shoumkh .flags 43836fd0130Shoumkh .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 43936fd0130Shoumkh } 44036fd0130Shoumkh 44136fd0130Shoumkh // 遍历所有时间源,寻找新的监视器 44236fd0130Shoumkh let mut clocksource_list = CLOCKSOURCE_LIST.lock(); 44336fd0130Shoumkh let mut replace_pos: usize = clocksource_list.len(); 44436fd0130Shoumkh for (pos, ele) in clocksource_list.iter().enumerate() { 44536fd0130Shoumkh let ele_data = ele.clocksource_data(); 44636fd0130Shoumkh 44736fd0130Shoumkh if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) 44836fd0130Shoumkh || ele_data 44936fd0130Shoumkh .flags 45036fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY) 45136fd0130Shoumkh { 45236fd0130Shoumkh // 当前时钟源是要被删除的时钟源或没被检查过的时钟源 45336fd0130Shoumkh // 不适合成为监视器 45436fd0130Shoumkh continue; 45536fd0130Shoumkh } 45636fd0130Shoumkh let watchdog = locked_watchdog.get_watchdog().clone(); 45736fd0130Shoumkh if watchdog.is_none() 45836fd0130Shoumkh || ele_data.rating > watchdog.unwrap().clocksource_data().rating 45936fd0130Shoumkh { 46036fd0130Shoumkh // 如果watchdog不存在或者当前时钟源的精度高于watchdog的精度,则记录当前时钟源的下标 46136fd0130Shoumkh replace_pos = pos; 46236fd0130Shoumkh } 46336fd0130Shoumkh } 46436fd0130Shoumkh // 使用刚刚找到的更好的时钟源替换旧的watchdog 46536fd0130Shoumkh if replace_pos < clocksource_list.len() { 46636fd0130Shoumkh let mut temp_list = clocksource_list.split_off(replace_pos); 46736fd0130Shoumkh let new_wd = temp_list.front().unwrap().clone(); 46836fd0130Shoumkh clocksource_list.append(&mut temp_list); 46936fd0130Shoumkh // 替换watchdog 47036fd0130Shoumkh locked_watchdog.watchdog.replace(new_wd); 47136fd0130Shoumkh // drop(locked_watchdog); 47236fd0130Shoumkh } 47336fd0130Shoumkh // 删除时钟源 47436fd0130Shoumkh if del_pos != size { 47536fd0130Shoumkh let mut temp_list = list.split_off(del_pos); 47636fd0130Shoumkh temp_list.pop_front(); 47736fd0130Shoumkh list.append(&mut temp_list); 47836fd0130Shoumkh } 47936fd0130Shoumkh } 48036fd0130Shoumkh 48136fd0130Shoumkh // 清除watchdog标记 48236fd0130Shoumkh let mut cs_data = self.clocksource_data(); 48336fd0130Shoumkh cs_data 48436fd0130Shoumkh .flags 48536fd0130Shoumkh .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 48636fd0130Shoumkh self.update_clocksource_data(cs_data) 48736fd0130Shoumkh .expect("clocksource_dequeue_watchdog: failed to update clocksource data"); 48836fd0130Shoumkh size = list.len(); 48936fd0130Shoumkh // 停止当前的watchdog 49036fd0130Shoumkh locked_watchdog.clocksource_stop_watchdog(size - 1); 49136fd0130Shoumkh } 49236fd0130Shoumkh 49336fd0130Shoumkh /// # 将时钟源从时钟源链表中弹出 49436fd0130Shoumkh fn clocksource_dequeue(&self) { 49536fd0130Shoumkh let mut list = CLOCKSOURCE_LIST.lock(); 49636fd0130Shoumkh let data = self.clocksource_data(); 49736fd0130Shoumkh let mut del_pos: usize = list.len(); 49836fd0130Shoumkh for (pos, ele) in list.iter().enumerate() { 49936fd0130Shoumkh let ele_data = ele.clocksource_data(); 50036fd0130Shoumkh if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) { 50136fd0130Shoumkh // 记录时钟源在链表中的下标 50236fd0130Shoumkh del_pos = pos; 50336fd0130Shoumkh } 50436fd0130Shoumkh } 50536fd0130Shoumkh 50636fd0130Shoumkh // 删除时钟源 50736fd0130Shoumkh if del_pos != list.len() { 50836fd0130Shoumkh let mut temp_list = list.split_off(del_pos); 50936fd0130Shoumkh temp_list.pop_front(); 51036fd0130Shoumkh list.append(&mut temp_list); 51136fd0130Shoumkh } 51236fd0130Shoumkh } 51336fd0130Shoumkh 51436fd0130Shoumkh /// # 注销时钟源 51536fd0130Shoumkh #[allow(dead_code)] 51636fd0130Shoumkh pub fn unregister(&self) { 51736fd0130Shoumkh // 将时钟源从监视链表中弹出 51836fd0130Shoumkh self.clocksource_dequeue_watchdog(); 51936fd0130Shoumkh // 将时钟源从时钟源链表中弹出 52036fd0130Shoumkh self.clocksource_dequeue(); 52136fd0130Shoumkh // 检查是否有更好的时钟源 52236fd0130Shoumkh clocksource_select(); 52336fd0130Shoumkh } 52436fd0130Shoumkh /// # 修改时钟源的精度 52536fd0130Shoumkh /// 52636fd0130Shoumkh /// ## 参数 52736fd0130Shoumkh /// 52836fd0130Shoumkh /// * `rating` - 指定的时钟精度 52936fd0130Shoumkh fn clocksource_change_rating(&self, rating: i32) { 53036fd0130Shoumkh // 将时钟源从链表中弹出 53136fd0130Shoumkh self.clocksource_dequeue(); 53236fd0130Shoumkh let mut data = self.clocksource_data(); 53336fd0130Shoumkh // 修改时钟源的精度 53436fd0130Shoumkh data.set_rating(rating); 53536fd0130Shoumkh self.update_clocksource_data(data) 53636fd0130Shoumkh .expect("clocksource_change_rating:updata clocksource failed"); 53736fd0130Shoumkh // 插入时钟源到时钟源链表中 53836fd0130Shoumkh self.clocksource_enqueue(); 53936fd0130Shoumkh // 检查是否有更好的时钟源 54036fd0130Shoumkh clocksource_select(); 54136fd0130Shoumkh } 54236fd0130Shoumkh } 54336fd0130Shoumkh 54436fd0130Shoumkh #[derive(Debug, Clone)] 54536fd0130Shoumkh pub struct ClocksourceData { 54636fd0130Shoumkh /// 时钟源名字 54736fd0130Shoumkh pub name: String, 54836fd0130Shoumkh /// 时钟精度 54936fd0130Shoumkh pub rating: i32, 55036fd0130Shoumkh pub mask: ClocksourceMask, 55136fd0130Shoumkh pub mult: u32, 55236fd0130Shoumkh pub shift: u32, 55336fd0130Shoumkh pub max_idle_ns: u32, 55436fd0130Shoumkh pub flags: ClocksourceFlags, 55536fd0130Shoumkh pub watchdog_last: CycleNum, 55636fd0130Shoumkh } 55736fd0130Shoumkh 55836fd0130Shoumkh impl ClocksourceData { 55936fd0130Shoumkh #[allow(dead_code)] 56036fd0130Shoumkh pub fn new( 56136fd0130Shoumkh name: String, 56236fd0130Shoumkh rating: i32, 56336fd0130Shoumkh mask: ClocksourceMask, 56436fd0130Shoumkh mult: u32, 56536fd0130Shoumkh shift: u32, 56636fd0130Shoumkh max_idle_ns: u32, 56736fd0130Shoumkh flags: ClocksourceFlags, 56836fd0130Shoumkh ) -> Self { 56936fd0130Shoumkh let csd = ClocksourceData { 57036fd0130Shoumkh name, 57136fd0130Shoumkh rating, 57236fd0130Shoumkh mask, 57336fd0130Shoumkh mult, 57436fd0130Shoumkh shift, 57536fd0130Shoumkh max_idle_ns, 57636fd0130Shoumkh flags, 57736fd0130Shoumkh watchdog_last: CycleNum(0), 57836fd0130Shoumkh }; 57936fd0130Shoumkh return csd; 58036fd0130Shoumkh } 58136fd0130Shoumkh 58236fd0130Shoumkh pub fn set_name(&mut self, name: String) { 58336fd0130Shoumkh self.name = name; 58436fd0130Shoumkh } 58536fd0130Shoumkh pub fn set_rating(&mut self, rating: i32) { 58636fd0130Shoumkh self.rating = rating; 58736fd0130Shoumkh } 58836fd0130Shoumkh pub fn set_mask(&mut self, mask: ClocksourceMask) { 58936fd0130Shoumkh self.mask = mask; 59036fd0130Shoumkh } 59136fd0130Shoumkh pub fn set_mult(&mut self, mult: u32) { 59236fd0130Shoumkh self.mult = mult; 59336fd0130Shoumkh } 59436fd0130Shoumkh pub fn set_shift(&mut self, shift: u32) { 59536fd0130Shoumkh self.shift = shift; 59636fd0130Shoumkh } 59736fd0130Shoumkh pub fn set_max_idle_ns(&mut self, max_idle_ns: u32) { 59836fd0130Shoumkh self.max_idle_ns = max_idle_ns; 59936fd0130Shoumkh } 60036fd0130Shoumkh pub fn set_flags(&mut self, flags: ClocksourceFlags) { 60136fd0130Shoumkh self.flags = flags; 60236fd0130Shoumkh } 60336fd0130Shoumkh #[allow(dead_code)] 60436fd0130Shoumkh pub fn remove_flags(&mut self, flags: ClocksourceFlags) { 60536fd0130Shoumkh self.flags.remove(flags) 60636fd0130Shoumkh } 60736fd0130Shoumkh #[allow(dead_code)] 60836fd0130Shoumkh pub fn insert_flags(&mut self, flags: ClocksourceFlags) { 60936fd0130Shoumkh self.flags.insert(flags) 61036fd0130Shoumkh } 61136fd0130Shoumkh } 61236fd0130Shoumkh 61336fd0130Shoumkh /// converts clocksource cycles to nanoseconds 61436fd0130Shoumkh /// 61536fd0130Shoumkh pub fn clocksource_cyc2ns(cycles: CycleNum, mult: u32, shift: u32) -> u64 { 61636fd0130Shoumkh return (cycles.data() * mult as u64) >> shift; 61736fd0130Shoumkh } 61836fd0130Shoumkh 61936fd0130Shoumkh /// # 重启所有的时间源 62036fd0130Shoumkh #[allow(dead_code)] 62136fd0130Shoumkh pub fn clocksource_resume() { 62236fd0130Shoumkh let list = CLOCKSOURCE_LIST.lock(); 62336fd0130Shoumkh for ele in list.iter() { 62436fd0130Shoumkh let data = ele.clocksource_data(); 62536fd0130Shoumkh match ele.resume() { 62636fd0130Shoumkh Ok(_) => continue, 62736fd0130Shoumkh Err(_) => { 62840fe15e0SLoGin kdebug!("clocksource {:?} resume failed", data.name); 62936fd0130Shoumkh } 63036fd0130Shoumkh } 63136fd0130Shoumkh } 63236fd0130Shoumkh clocksource_resume_watchdog(); 63336fd0130Shoumkh } 63436fd0130Shoumkh 63536fd0130Shoumkh /// # 暂停所有的时间源 63636fd0130Shoumkh #[allow(dead_code)] 63736fd0130Shoumkh pub fn clocksource_suspend() { 63836fd0130Shoumkh let list = CLOCKSOURCE_LIST.lock(); 63936fd0130Shoumkh for ele in list.iter() { 64036fd0130Shoumkh let data = ele.clocksource_data(); 64136fd0130Shoumkh match ele.suspend() { 64236fd0130Shoumkh Ok(_) => continue, 64336fd0130Shoumkh Err(_) => { 64440fe15e0SLoGin kdebug!("clocksource {:?} suspend failed", data.name); 64536fd0130Shoumkh } 64636fd0130Shoumkh } 64736fd0130Shoumkh } 64836fd0130Shoumkh } 64936fd0130Shoumkh 65036fd0130Shoumkh /// # 根据watchdog的精度,来检查被监视的时钟源的误差 65136fd0130Shoumkh /// 65236fd0130Shoumkh /// ## 返回值 65336fd0130Shoumkh /// 65436fd0130Shoumkh /// * `Ok()` - 检查完成 65536fd0130Shoumkh /// * `Err(SystemError)` - 错误码 65636fd0130Shoumkh pub fn clocksource_watchdog() -> Result<(), SystemError> { 65736fd0130Shoumkh let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock(); 65836fd0130Shoumkh 65936fd0130Shoumkh // watchdog没有在运行的话直接退出 66036fd0130Shoumkh if !cs_watchdog.is_running || cs_watchdog.watchdog.is_none() { 66136fd0130Shoumkh return Ok(()); 66236fd0130Shoumkh } 66336fd0130Shoumkh let cur_watchdog = cs_watchdog.watchdog.as_ref().unwrap().clone(); 66436fd0130Shoumkh let cur_wd_data = cur_watchdog.as_ref().clocksource_data(); 66536fd0130Shoumkh let cur_wd_nowclock = cur_watchdog.as_ref().read().data(); 66636fd0130Shoumkh 66736fd0130Shoumkh let wd_last = cs_watchdog.last_check.data(); 66836fd0130Shoumkh let wd_dev_nsec = clocksource_cyc2ns( 66936fd0130Shoumkh CycleNum((cur_wd_nowclock - wd_last) & cur_wd_data.mask.bits), 67036fd0130Shoumkh cur_wd_data.mult, 67136fd0130Shoumkh cur_wd_data.shift, 67236fd0130Shoumkh ); 67336fd0130Shoumkh cs_watchdog.last_check = CycleNum(cur_wd_nowclock); 67436fd0130Shoumkh drop(cs_watchdog); 67536fd0130Shoumkh let watchdog_list = &mut WATCHDOG_LIST.lock(); 67636fd0130Shoumkh for cs in watchdog_list.iter() { 67736fd0130Shoumkh let mut cs_data = cs.clocksource_data(); 67836fd0130Shoumkh // 判断时钟源是否已经被标记为不稳定 67936fd0130Shoumkh if cs_data 68036fd0130Shoumkh .flags 68136fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) 68236fd0130Shoumkh { 68336fd0130Shoumkh // 启动watchdog_kthread 68436fd0130Shoumkh unsafe { run_watchdog_kthread() }; 68536fd0130Shoumkh continue; 68636fd0130Shoumkh } 68736fd0130Shoumkh // 读取时钟源现在的时间 68836fd0130Shoumkh let cs_now_clock = cs.read(); 68936fd0130Shoumkh 69036fd0130Shoumkh // 如果时钟源没有被监视,则开始监视他 69136fd0130Shoumkh if !cs_data 69236fd0130Shoumkh .flags 69336fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG) 69436fd0130Shoumkh { 69536fd0130Shoumkh cs_data 69636fd0130Shoumkh .flags 69736fd0130Shoumkh .insert(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 69836fd0130Shoumkh // 记录此次检查的时刻 69936fd0130Shoumkh cs_data.watchdog_last = cs_now_clock; 70036fd0130Shoumkh cs.update_clocksource_data(cs_data.clone())?; 70136fd0130Shoumkh continue; 70236fd0130Shoumkh } 70336fd0130Shoumkh 70436fd0130Shoumkh // 计算时钟源的误差 70536fd0130Shoumkh let cs_dev_nsec = clocksource_cyc2ns( 70636fd0130Shoumkh CycleNum(cs_now_clock.div(cs_data.watchdog_last).data() & cs_data.mask.bits), 70736fd0130Shoumkh cs_data.mult, 70836fd0130Shoumkh cs_data.shift, 70936fd0130Shoumkh ); 71036fd0130Shoumkh // 记录此次检查的时刻 71136fd0130Shoumkh cs_data.watchdog_last = cs_now_clock; 71236fd0130Shoumkh cs.update_clocksource_data(cs_data.clone())?; 71336fd0130Shoumkh if cs_dev_nsec.abs_diff(wd_dev_nsec) > WATCHDOG_THRESHOLD.into() { 71436fd0130Shoumkh // 误差过大,标记为unstable 71536fd0130Shoumkh cs.set_unstable((cs_dev_nsec - wd_dev_nsec).try_into().unwrap())?; 71636fd0130Shoumkh continue; 71736fd0130Shoumkh } 71836fd0130Shoumkh 71936fd0130Shoumkh // 判断是否要切换为高精度模式 72036fd0130Shoumkh if !cs_data 72136fd0130Shoumkh .flags 72236fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES) 72336fd0130Shoumkh && cs_data 72436fd0130Shoumkh .flags 72536fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS) 72636fd0130Shoumkh && cur_wd_data 72736fd0130Shoumkh .flags 72836fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS) 72936fd0130Shoumkh { 73036fd0130Shoumkh cs_data 73136fd0130Shoumkh .flags 73236fd0130Shoumkh .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES); 73336fd0130Shoumkh cs.update_clocksource_data(cs_data)?; 73436fd0130Shoumkh // TODO 通知tick机制 切换为高精度模式 73536fd0130Shoumkh } 73636fd0130Shoumkh let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock(); 73736fd0130Shoumkh // FIXME 需要保证所有cpu时间统一 73836fd0130Shoumkh cs_watchdog.timer_expires += WATCHDOG_INTERVAL; 73936fd0130Shoumkh //创建定时器执行watchdog 74036fd0130Shoumkh let watchdog_func = Box::new(WatchdogTimerFunc {}); 74136fd0130Shoumkh let watchdog_timer = Timer::new(watchdog_func, cs_watchdog.timer_expires); 74236fd0130Shoumkh watchdog_timer.activate(); 74336fd0130Shoumkh } 74436fd0130Shoumkh return Ok(()); 74536fd0130Shoumkh } 74636fd0130Shoumkh 74736fd0130Shoumkh /// # watchdog线程的逻辑,执行unstable的后续操作 74836fd0130Shoumkh pub fn clocksource_watchdog_kthread() { 74936fd0130Shoumkh let mut del_vec: Vec<usize> = Vec::new(); 75036fd0130Shoumkh let mut del_clocks: Vec<Arc<dyn Clocksource>> = Vec::new(); 75136fd0130Shoumkh let wd_list = &mut WATCHDOG_LIST.lock(); 75236fd0130Shoumkh 75336fd0130Shoumkh // 将不稳定的时钟源弹出监视链表 75436fd0130Shoumkh for (pos, ele) in wd_list.iter().enumerate() { 75536fd0130Shoumkh let data = ele.clocksource_data(); 75636fd0130Shoumkh if data.flags.contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) { 75736fd0130Shoumkh del_vec.push(pos); 75836fd0130Shoumkh del_clocks.push(ele.clone()); 75936fd0130Shoumkh } 76036fd0130Shoumkh } 76136fd0130Shoumkh for pos in del_vec { 76236fd0130Shoumkh let mut temp_list = wd_list.split_off(pos); 76336fd0130Shoumkh temp_list.pop_front(); 76436fd0130Shoumkh wd_list.append(&mut temp_list); 76536fd0130Shoumkh } 76636fd0130Shoumkh 76736fd0130Shoumkh // 检查是否需要停止watchdog 76836fd0130Shoumkh CLOCKSOUCE_WATCHDOG 76936fd0130Shoumkh .lock() 77036fd0130Shoumkh .clocksource_stop_watchdog(wd_list.len()); 77136fd0130Shoumkh // 将不稳定的时钟源精度都设置为最低 77236fd0130Shoumkh for clock in del_clocks.iter() { 77336fd0130Shoumkh clock.clocksource_change_rating(0); 77436fd0130Shoumkh } 77536fd0130Shoumkh } 77636fd0130Shoumkh 77736fd0130Shoumkh /// # 清空所有时钟源的watchdog标志位 77836fd0130Shoumkh pub fn clocksource_reset_watchdog() { 77936fd0130Shoumkh let list_guard = WATCHDOG_LIST.lock(); 78036fd0130Shoumkh for ele in list_guard.iter() { 78136fd0130Shoumkh ele.clocksource_data() 78236fd0130Shoumkh .flags 78336fd0130Shoumkh .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 78436fd0130Shoumkh } 78536fd0130Shoumkh } 78636fd0130Shoumkh 78736fd0130Shoumkh /// # 重启检查器 78836fd0130Shoumkh pub fn clocksource_resume_watchdog() { 78936fd0130Shoumkh clocksource_reset_watchdog(); 79036fd0130Shoumkh } 79136fd0130Shoumkh 79236fd0130Shoumkh /// # 根据精度选择最优的时钟源,或者接受用户指定的时间源 79336fd0130Shoumkh pub fn clocksource_select() { 79436fd0130Shoumkh let list_guard = CLOCKSOURCE_LIST.lock(); 79536fd0130Shoumkh if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } || list_guard.is_empty() { 79636fd0130Shoumkh return; 79736fd0130Shoumkh } 79836fd0130Shoumkh let mut best = list_guard.front().unwrap().clone(); 79936fd0130Shoumkh let override_name = OVERRIDE_NAME.lock(); 80036fd0130Shoumkh // 判断是否有用户空间指定的时间源 80136fd0130Shoumkh for ele in list_guard.iter() { 80236fd0130Shoumkh if ele.clocksource_data().name.eq(override_name.deref()) { 80336fd0130Shoumkh // TODO 判断是否是高精度模式 80436fd0130Shoumkh // 暂时不支持高精度模式 80536fd0130Shoumkh // 如果是高精度模式,但是时钟源不支持高精度模式的话,就要退出循环 80636fd0130Shoumkh best = ele.clone(); 80736fd0130Shoumkh break; 80836fd0130Shoumkh } 80936fd0130Shoumkh } 81036fd0130Shoumkh // 对比当前的时钟源和记录到最好的时钟源的精度 81136fd0130Shoumkh if CUR_CLOCKSOURCE.lock().as_ref().is_some() { 81236fd0130Shoumkh // 当前时钟源不为空 81336fd0130Shoumkh let cur_clocksource = CUR_CLOCKSOURCE.lock().as_ref().unwrap().clone(); 81436fd0130Shoumkh let best_name = &best.clocksource_data().name; 81536fd0130Shoumkh if cur_clocksource.clocksource_data().name.ne(best_name) { 81636fd0130Shoumkh kinfo!("Switching to the clocksource {:?}\n", best_name); 81736fd0130Shoumkh drop(cur_clocksource); 81836fd0130Shoumkh CUR_CLOCKSOURCE.lock().replace(best); 81936fd0130Shoumkh // TODO 通知timerkeeping 切换了时间源 82036fd0130Shoumkh } 82136fd0130Shoumkh } else { 82236fd0130Shoumkh // 当前时钟源为空 82336fd0130Shoumkh CUR_CLOCKSOURCE.lock().replace(best); 82436fd0130Shoumkh } 82536fd0130Shoumkh kdebug!(" clocksource_select finish"); 82636fd0130Shoumkh } 82736fd0130Shoumkh 82836fd0130Shoumkh /// # clocksource模块加载完成 82936fd0130Shoumkh pub fn clocksource_boot_finish() { 83036fd0130Shoumkh let mut cur_clocksource = CUR_CLOCKSOURCE.lock(); 83136fd0130Shoumkh cur_clocksource.replace(clocksource_default_clock()); 83236fd0130Shoumkh unsafe { FINISHED_BOOTING.store(true, Ordering::Relaxed) }; 83336fd0130Shoumkh // 清除不稳定的时钟源 83436fd0130Shoumkh clocksource_watchdog_kthread(); 83536fd0130Shoumkh kdebug!("clocksource_boot_finish"); 83636fd0130Shoumkh } 83736fd0130Shoumkh 83836fd0130Shoumkh // ======== 以下为对C的接口 ======== 83936fd0130Shoumkh /// # 完成对clocksource模块的加载 84036fd0130Shoumkh #[no_mangle] 84136fd0130Shoumkh pub extern "C" fn rs_clocksource_boot_finish() { 84236fd0130Shoumkh clocksource_boot_finish(); 84336fd0130Shoumkh } 84436fd0130Shoumkh 84536fd0130Shoumkh /// # 启动watchdog线程的辅助函数 84636fd0130Shoumkh #[no_mangle] 84736fd0130Shoumkh pub extern "C" fn rs_clocksource_watchdog_kthread(_data: c_void) -> i32 { 84836fd0130Shoumkh clocksource_watchdog_kthread(); 84936fd0130Shoumkh return 0; 85036fd0130Shoumkh } 851