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