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