1*36fd0130Shoumkh use core::{ 2*36fd0130Shoumkh ffi::c_void, 3*36fd0130Shoumkh fmt::Debug, 4*36fd0130Shoumkh sync::atomic::{AtomicBool, Ordering}, 5*36fd0130Shoumkh }; 6*36fd0130Shoumkh 7*36fd0130Shoumkh use alloc::{boxed::Box, collections::LinkedList, string::String, sync::Arc, vec::Vec}; 8*36fd0130Shoumkh use lazy_static::__Deref; 9*36fd0130Shoumkh 10*36fd0130Shoumkh use crate::{ 11*36fd0130Shoumkh include::bindings::bindings::run_watchdog_kthread, kdebug, kinfo, libs::spinlock::SpinLock, 12*36fd0130Shoumkh syscall::SystemError, 13*36fd0130Shoumkh }; 14*36fd0130Shoumkh 15*36fd0130Shoumkh use super::{ 16*36fd0130Shoumkh jiffies::clocksource_default_clock, 17*36fd0130Shoumkh timer::{clock, Timer, TimerFunction}, 18*36fd0130Shoumkh NSEC_PER_SEC, 19*36fd0130Shoumkh }; 20*36fd0130Shoumkh 21*36fd0130Shoumkh lazy_static! { 22*36fd0130Shoumkh /// linked list with the registered clocksources 23*36fd0130Shoumkh pub static ref CLOCKSOURCE_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> = 24*36fd0130Shoumkh SpinLock::new(LinkedList::new()); 25*36fd0130Shoumkh /// 被监视中的时钟源 26*36fd0130Shoumkh pub static ref WATCHDOG_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> = 27*36fd0130Shoumkh SpinLock::new(LinkedList::new()); 28*36fd0130Shoumkh 29*36fd0130Shoumkh pub static ref CLOCKSOUCE_WATCHDOG:SpinLock<ClocksouceWatchdog> = SpinLock::new(ClocksouceWatchdog::new()); 30*36fd0130Shoumkh 31*36fd0130Shoumkh pub static ref OVERRIDE_NAME: SpinLock<String> = SpinLock::new(String::from("")); 32*36fd0130Shoumkh 33*36fd0130Shoumkh 34*36fd0130Shoumkh } 35*36fd0130Shoumkh 36*36fd0130Shoumkh /// 正在被使用时钟源 37*36fd0130Shoumkh pub static CUR_CLOCKSOURCE: SpinLock<Option<Arc<dyn Clocksource>>> = SpinLock::new(None); 38*36fd0130Shoumkh /// 是否完成加载 39*36fd0130Shoumkh pub static mut FINISHED_BOOTING: AtomicBool = AtomicBool::new(false); 40*36fd0130Shoumkh 41*36fd0130Shoumkh /// Interval: 0.5sec Threshold: 0.0625s 42*36fd0130Shoumkh /// 系统节拍率 43*36fd0130Shoumkh pub const HZ: u64 = 1000; 44*36fd0130Shoumkh /// watchdog检查间隔 45*36fd0130Shoumkh pub const WATCHDOG_INTERVAL: u64 = HZ >> 1; 46*36fd0130Shoumkh /// 最大能接受的误差大小 47*36fd0130Shoumkh pub const WATCHDOG_THRESHOLD: u32 = NSEC_PER_SEC >> 4; 48*36fd0130Shoumkh 49*36fd0130Shoumkh // 时钟周期数 50*36fd0130Shoumkh #[derive(Debug, Clone, Copy)] 51*36fd0130Shoumkh #[repr(transparent)] 52*36fd0130Shoumkh pub struct CycleNum(pub u64); 53*36fd0130Shoumkh 54*36fd0130Shoumkh #[allow(dead_code)] 55*36fd0130Shoumkh impl CycleNum { 56*36fd0130Shoumkh #[inline(always)] 57*36fd0130Shoumkh pub fn new(cycle: u64) -> Self { 58*36fd0130Shoumkh Self(cycle) 59*36fd0130Shoumkh } 60*36fd0130Shoumkh #[inline(always)] 61*36fd0130Shoumkh pub fn data(&self) -> u64 { 62*36fd0130Shoumkh self.0 63*36fd0130Shoumkh } 64*36fd0130Shoumkh #[inline(always)] 65*36fd0130Shoumkh #[allow(dead_code)] 66*36fd0130Shoumkh pub fn add(&self, other: CycleNum) -> CycleNum { 67*36fd0130Shoumkh CycleNum(self.data() + other.data()) 68*36fd0130Shoumkh } 69*36fd0130Shoumkh #[inline(always)] 70*36fd0130Shoumkh pub fn div(&self, other: CycleNum) -> CycleNum { 71*36fd0130Shoumkh CycleNum(self.data() - other.data()) 72*36fd0130Shoumkh } 73*36fd0130Shoumkh } 74*36fd0130Shoumkh 75*36fd0130Shoumkh bitflags! { 76*36fd0130Shoumkh 77*36fd0130Shoumkh #[derive(Default)] 78*36fd0130Shoumkh pub struct ClocksourceMask: u64 { 79*36fd0130Shoumkh } 80*36fd0130Shoumkh /// 时钟状态标记 81*36fd0130Shoumkh #[derive(Default)] 82*36fd0130Shoumkh pub struct ClocksourceFlags: u64 { 83*36fd0130Shoumkh /// 表示时钟设备是连续的 84*36fd0130Shoumkh const CLOCK_SOURCE_IS_CONTINUOUS = 0x01; 85*36fd0130Shoumkh /// 表示该时钟源需要经过watchdog检查 86*36fd0130Shoumkh const CLOCK_SOURCE_MUST_VERIFY = 0x02; 87*36fd0130Shoumkh /// 表示该时钟源是watchdog 88*36fd0130Shoumkh const CLOCK_SOURCE_WATCHDOG = 0x10; 89*36fd0130Shoumkh /// 表示该时钟源是高分辨率的 90*36fd0130Shoumkh const CLOCK_SOURCE_VALID_FOR_HRES = 0x20; 91*36fd0130Shoumkh /// 表示该时钟源误差过大 92*36fd0130Shoumkh const CLOCK_SOURCE_UNSTABLE = 0x40; 93*36fd0130Shoumkh } 94*36fd0130Shoumkh } 95*36fd0130Shoumkh impl From<u64> for ClocksourceMask { 96*36fd0130Shoumkh fn from(value: u64) -> Self { 97*36fd0130Shoumkh if value < 64 { 98*36fd0130Shoumkh return Self::from_bits_truncate((1 << value) - 1); 99*36fd0130Shoumkh } 100*36fd0130Shoumkh return Self::from_bits_truncate(u64::MAX); 101*36fd0130Shoumkh } 102*36fd0130Shoumkh } 103*36fd0130Shoumkh impl ClocksourceMask { 104*36fd0130Shoumkh pub fn new(b: u64) -> Self { 105*36fd0130Shoumkh Self { bits: b } 106*36fd0130Shoumkh } 107*36fd0130Shoumkh } 108*36fd0130Shoumkh impl ClocksourceFlags { 109*36fd0130Shoumkh pub fn new(b: u64) -> Self { 110*36fd0130Shoumkh Self { bits: b } 111*36fd0130Shoumkh } 112*36fd0130Shoumkh } 113*36fd0130Shoumkh 114*36fd0130Shoumkh #[derive(Debug)] 115*36fd0130Shoumkh pub struct ClocksouceWatchdog { 116*36fd0130Shoumkh /// 监视器 117*36fd0130Shoumkh watchdog: Option<Arc<dyn Clocksource>>, 118*36fd0130Shoumkh /// 检查器是否在工作的标志 119*36fd0130Shoumkh is_running: bool, 120*36fd0130Shoumkh /// 上一次检查的时刻 121*36fd0130Shoumkh last_check: CycleNum, 122*36fd0130Shoumkh /// 定时监视器的过期时间 123*36fd0130Shoumkh timer_expires: u64, 124*36fd0130Shoumkh } 125*36fd0130Shoumkh impl ClocksouceWatchdog { 126*36fd0130Shoumkh pub fn new() -> Self { 127*36fd0130Shoumkh Self { 128*36fd0130Shoumkh watchdog: None, 129*36fd0130Shoumkh is_running: false, 130*36fd0130Shoumkh last_check: CycleNum(0), 131*36fd0130Shoumkh timer_expires: 0, 132*36fd0130Shoumkh } 133*36fd0130Shoumkh } 134*36fd0130Shoumkh 135*36fd0130Shoumkh /// 获取watchdog 136*36fd0130Shoumkh fn get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>> { 137*36fd0130Shoumkh &mut self.watchdog 138*36fd0130Shoumkh } 139*36fd0130Shoumkh 140*36fd0130Shoumkh /// 启用检查器 141*36fd0130Shoumkh pub fn clocksource_start_watchdog(&mut self) { 142*36fd0130Shoumkh // 如果watchdog未被设置或者已经启用了就退出 143*36fd0130Shoumkh let watchdog_list = &WATCHDOG_LIST.lock(); 144*36fd0130Shoumkh if self.is_running || self.watchdog.is_none() || watchdog_list.is_empty() { 145*36fd0130Shoumkh return; 146*36fd0130Shoumkh } 147*36fd0130Shoumkh // 生成一个定时器 148*36fd0130Shoumkh let wd_timer_func: Box<WatchdogTimerFunc> = Box::new(WatchdogTimerFunc {}); 149*36fd0130Shoumkh self.timer_expires += clock() + WATCHDOG_INTERVAL; 150*36fd0130Shoumkh self.last_check = self.watchdog.as_ref().unwrap().clone().read(); 151*36fd0130Shoumkh let wd_timer = Timer::new(wd_timer_func, self.timer_expires); 152*36fd0130Shoumkh wd_timer.activate(); 153*36fd0130Shoumkh self.is_running = true; 154*36fd0130Shoumkh } 155*36fd0130Shoumkh 156*36fd0130Shoumkh /// 停止检查器 157*36fd0130Shoumkh /// list_len WATCHDOG_LIST长度 158*36fd0130Shoumkh pub fn clocksource_stop_watchdog(&mut self, list_len: usize) { 159*36fd0130Shoumkh if !self.is_running || (self.watchdog.is_some() && list_len != 0) { 160*36fd0130Shoumkh return; 161*36fd0130Shoumkh } 162*36fd0130Shoumkh // TODO 当实现了周期性的定时器后 需要将监视用的定时器删除 163*36fd0130Shoumkh self.is_running = false; 164*36fd0130Shoumkh } 165*36fd0130Shoumkh } 166*36fd0130Shoumkh 167*36fd0130Shoumkh /// 定时检查器 168*36fd0130Shoumkh #[derive(Debug)] 169*36fd0130Shoumkh pub struct WatchdogTimerFunc; 170*36fd0130Shoumkh impl TimerFunction for WatchdogTimerFunc { 171*36fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError> { 172*36fd0130Shoumkh return clocksource_watchdog(); 173*36fd0130Shoumkh } 174*36fd0130Shoumkh } 175*36fd0130Shoumkh 176*36fd0130Shoumkh /// 时钟源的特性 177*36fd0130Shoumkh pub trait Clocksource: Send + Sync + Debug { 178*36fd0130Shoumkh // TODO 返回值类型可能需要改变 179*36fd0130Shoumkh /// returns a cycle value, passes clocksource as argument 180*36fd0130Shoumkh fn read(&self) -> CycleNum; 181*36fd0130Shoumkh /// optional function to enable the clocksource 182*36fd0130Shoumkh fn enable(&self) -> Result<i32, SystemError> { 183*36fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 184*36fd0130Shoumkh } 185*36fd0130Shoumkh /// optional function to disable the clocksource 186*36fd0130Shoumkh fn disable(&self) -> Result<(), SystemError> { 187*36fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 188*36fd0130Shoumkh } 189*36fd0130Shoumkh /// vsyscall based read 190*36fd0130Shoumkh fn vread(&self) -> Result<CycleNum, SystemError> { 191*36fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 192*36fd0130Shoumkh } 193*36fd0130Shoumkh /// suspend function for the clocksource, if necessary 194*36fd0130Shoumkh fn suspend(&self) -> Result<(), SystemError> { 195*36fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 196*36fd0130Shoumkh } 197*36fd0130Shoumkh /// resume function for the clocksource, if necessary 198*36fd0130Shoumkh fn resume(&self) -> Result<(), SystemError> { 199*36fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 200*36fd0130Shoumkh } 201*36fd0130Shoumkh // 获取时钟源数据 202*36fd0130Shoumkh fn clocksource_data(&self) -> ClocksourceData; 203*36fd0130Shoumkh 204*36fd0130Shoumkh fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> { 205*36fd0130Shoumkh return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 206*36fd0130Shoumkh } 207*36fd0130Shoumkh // 获取时钟源 208*36fd0130Shoumkh fn clocksource(&self) -> Arc<dyn Clocksource>; 209*36fd0130Shoumkh } 210*36fd0130Shoumkh 211*36fd0130Shoumkh /// # 实现整数log2的运算 212*36fd0130Shoumkh /// 213*36fd0130Shoumkh /// ## 参数 214*36fd0130Shoumkh /// 215*36fd0130Shoumkh /// * `x` - 要计算的数字 216*36fd0130Shoumkh /// 217*36fd0130Shoumkh /// ## 返回值 218*36fd0130Shoumkh /// 219*36fd0130Shoumkh /// * `u32` - 返回\log_2(x)的值 220*36fd0130Shoumkh fn log2(x: u32) -> u32 { 221*36fd0130Shoumkh let mut result = 0; 222*36fd0130Shoumkh let mut x = x; 223*36fd0130Shoumkh 224*36fd0130Shoumkh if x >= 1 << 16 { 225*36fd0130Shoumkh x >>= 16; 226*36fd0130Shoumkh result |= 16; 227*36fd0130Shoumkh } 228*36fd0130Shoumkh if x >= 1 << 8 { 229*36fd0130Shoumkh x >>= 8; 230*36fd0130Shoumkh result |= 8; 231*36fd0130Shoumkh } 232*36fd0130Shoumkh if x >= 1 << 4 { 233*36fd0130Shoumkh x >>= 4; 234*36fd0130Shoumkh result |= 4; 235*36fd0130Shoumkh } 236*36fd0130Shoumkh if x >= 1 << 2 { 237*36fd0130Shoumkh x >>= 2; 238*36fd0130Shoumkh result |= 2; 239*36fd0130Shoumkh } 240*36fd0130Shoumkh if x >= 1 << 1 { 241*36fd0130Shoumkh result |= 1; 242*36fd0130Shoumkh } 243*36fd0130Shoumkh 244*36fd0130Shoumkh result 245*36fd0130Shoumkh } 246*36fd0130Shoumkh 247*36fd0130Shoumkh impl dyn Clocksource { 248*36fd0130Shoumkh /// # 计算时钟源能记录的最大时间跨度 249*36fd0130Shoumkh pub fn clocksource_max_deferment(&self) -> u64 { 250*36fd0130Shoumkh let cs_data_guard = self.clocksource_data(); 251*36fd0130Shoumkh let max_nsecs: u64; 252*36fd0130Shoumkh let mut max_cycles: u64; 253*36fd0130Shoumkh max_cycles = (1 << (63 - (log2(cs_data_guard.mult) + 1))) as u64; 254*36fd0130Shoumkh max_cycles = max_cycles.min(cs_data_guard.mask.bits); 255*36fd0130Shoumkh max_nsecs = clocksource_cyc2ns( 256*36fd0130Shoumkh CycleNum(max_cycles), 257*36fd0130Shoumkh cs_data_guard.mult, 258*36fd0130Shoumkh cs_data_guard.shift, 259*36fd0130Shoumkh ); 260*36fd0130Shoumkh return max_nsecs - (max_nsecs >> 5); 261*36fd0130Shoumkh } 262*36fd0130Shoumkh 263*36fd0130Shoumkh /// # 注册时钟源 264*36fd0130Shoumkh /// 265*36fd0130Shoumkh /// ## 返回值 266*36fd0130Shoumkh /// 267*36fd0130Shoumkh /// * `Ok(0)` - 时钟源注册成功。 268*36fd0130Shoumkh /// * `Err(SystemError)` - 时钟源注册失败。 269*36fd0130Shoumkh pub fn register(&self) -> Result<i32, SystemError> { 270*36fd0130Shoumkh let ns = self.clocksource_max_deferment(); 271*36fd0130Shoumkh let mut cs_data = self.clocksource_data(); 272*36fd0130Shoumkh cs_data.max_idle_ns = ns as u32; 273*36fd0130Shoumkh self.update_clocksource_data(cs_data)?; 274*36fd0130Shoumkh // 将时钟源加入到时钟源队列中 275*36fd0130Shoumkh self.clocksource_enqueue(); 276*36fd0130Shoumkh // 将时钟源加入到监视队列中 277*36fd0130Shoumkh self.clocksource_enqueue_watchdog() 278*36fd0130Shoumkh .expect("register: failed to enqueue watchdog list"); 279*36fd0130Shoumkh // 选择一个最好的时钟源 280*36fd0130Shoumkh clocksource_select(); 281*36fd0130Shoumkh kdebug!("clocksource_register successfully"); 282*36fd0130Shoumkh return Ok(0); 283*36fd0130Shoumkh } 284*36fd0130Shoumkh 285*36fd0130Shoumkh /// # 将时钟源插入时钟源队列 286*36fd0130Shoumkh pub fn clocksource_enqueue(&self) { 287*36fd0130Shoumkh // 根据rating由大到小排序 288*36fd0130Shoumkh let cs_data = self.clocksource_data(); 289*36fd0130Shoumkh let list_guard = &mut CLOCKSOURCE_LIST.lock(); 290*36fd0130Shoumkh let mut spilt_pos: usize = 0; 291*36fd0130Shoumkh for (pos, ele) in list_guard.iter().enumerate() { 292*36fd0130Shoumkh if ele.clocksource_data().rating < cs_data.rating { 293*36fd0130Shoumkh spilt_pos = pos; 294*36fd0130Shoumkh break; 295*36fd0130Shoumkh } 296*36fd0130Shoumkh } 297*36fd0130Shoumkh let mut temp_list = list_guard.split_off(spilt_pos); 298*36fd0130Shoumkh let cs = self.clocksource(); 299*36fd0130Shoumkh list_guard.push_back(cs); 300*36fd0130Shoumkh list_guard.append(&mut temp_list); 301*36fd0130Shoumkh // kdebug!( 302*36fd0130Shoumkh // "CLOCKSOURCE_LIST len = {:?},clocksource_enqueue sccessfully", 303*36fd0130Shoumkh // list_guard.len() 304*36fd0130Shoumkh // ); 305*36fd0130Shoumkh } 306*36fd0130Shoumkh 307*36fd0130Shoumkh /// # 将时间源插入监控队列 308*36fd0130Shoumkh /// 309*36fd0130Shoumkh /// ## 返回值 310*36fd0130Shoumkh /// 311*36fd0130Shoumkh /// * `Ok(0)` - 时间源插入监控队列成功 312*36fd0130Shoumkh /// * `Err(SystemError)` - 时间源插入监控队列失败 313*36fd0130Shoumkh pub fn clocksource_enqueue_watchdog(&self) -> Result<i32, SystemError> { 314*36fd0130Shoumkh // BUG 可能需要lock irq 315*36fd0130Shoumkh let mut cs_data = self.clocksource_data(); 316*36fd0130Shoumkh 317*36fd0130Shoumkh let cs = self.clocksource(); 318*36fd0130Shoumkh if cs_data 319*36fd0130Shoumkh .flags 320*36fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY) 321*36fd0130Shoumkh { 322*36fd0130Shoumkh let mut list_guard = WATCHDOG_LIST.lock_irqsave(); 323*36fd0130Shoumkh // cs是被监视的 324*36fd0130Shoumkh cs_data 325*36fd0130Shoumkh .flags 326*36fd0130Shoumkh .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 327*36fd0130Shoumkh cs.update_clocksource_data(cs_data)?; 328*36fd0130Shoumkh list_guard.push_back(cs); 329*36fd0130Shoumkh } else { 330*36fd0130Shoumkh // cs是监视器 331*36fd0130Shoumkh if cs_data 332*36fd0130Shoumkh .flags 333*36fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS) 334*36fd0130Shoumkh { 335*36fd0130Shoumkh // 如果时钟设备是连续的 336*36fd0130Shoumkh cs_data 337*36fd0130Shoumkh .flags 338*36fd0130Shoumkh .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES); 339*36fd0130Shoumkh cs.update_clocksource_data(cs_data.clone())?; 340*36fd0130Shoumkh } 341*36fd0130Shoumkh 342*36fd0130Shoumkh // 将时钟源加入到监控队列中 343*36fd0130Shoumkh let mut list_guard = WATCHDOG_LIST.lock(); 344*36fd0130Shoumkh list_guard.push_back(cs.clone()); 345*36fd0130Shoumkh drop(list_guard); 346*36fd0130Shoumkh 347*36fd0130Shoumkh // 对比当前注册的时间源的精度和监视器的精度 348*36fd0130Shoumkh let cs_watchdog = &mut CLOCKSOUCE_WATCHDOG.lock(); 349*36fd0130Shoumkh if cs_watchdog.watchdog.is_none() 350*36fd0130Shoumkh || cs_data.rating 351*36fd0130Shoumkh > cs_watchdog 352*36fd0130Shoumkh .watchdog 353*36fd0130Shoumkh .clone() 354*36fd0130Shoumkh .unwrap() 355*36fd0130Shoumkh .clocksource_data() 356*36fd0130Shoumkh .rating 357*36fd0130Shoumkh { 358*36fd0130Shoumkh // 当前注册的时间源的精度更高或者没有监视器,替换监视器 359*36fd0130Shoumkh cs_watchdog.watchdog.replace(cs); 360*36fd0130Shoumkh clocksource_reset_watchdog(); 361*36fd0130Shoumkh } 362*36fd0130Shoumkh 363*36fd0130Shoumkh // 启动监视器 364*36fd0130Shoumkh cs_watchdog.clocksource_start_watchdog(); 365*36fd0130Shoumkh } 366*36fd0130Shoumkh return Ok(0); 367*36fd0130Shoumkh } 368*36fd0130Shoumkh 369*36fd0130Shoumkh /// # 将时钟源标记为unstable 370*36fd0130Shoumkh /// 371*36fd0130Shoumkh /// ## 参数 372*36fd0130Shoumkh /// * `delta` - 时钟源误差 373*36fd0130Shoumkh pub fn set_unstable(&self, delta: i64) -> Result<i32, SystemError> { 374*36fd0130Shoumkh let mut cs_data = self.clocksource_data(); 375*36fd0130Shoumkh // 打印出unstable的时钟源信息 376*36fd0130Shoumkh kdebug!( 377*36fd0130Shoumkh "clocksource :{:?} is unstable, its delta is {:?}", 378*36fd0130Shoumkh cs_data.name, 379*36fd0130Shoumkh delta 380*36fd0130Shoumkh ); 381*36fd0130Shoumkh cs_data.flags.remove( 382*36fd0130Shoumkh ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES | ClocksourceFlags::CLOCK_SOURCE_WATCHDOG, 383*36fd0130Shoumkh ); 384*36fd0130Shoumkh cs_data 385*36fd0130Shoumkh .flags 386*36fd0130Shoumkh .insert(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE); 387*36fd0130Shoumkh self.update_clocksource_data(cs_data)?; 388*36fd0130Shoumkh 389*36fd0130Shoumkh // 启动watchdog线程 进行后续处理 390*36fd0130Shoumkh if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } { 391*36fd0130Shoumkh // TODO 在实现了工作队列后,将启动线程换成schedule work 392*36fd0130Shoumkh unsafe { run_watchdog_kthread() } 393*36fd0130Shoumkh } 394*36fd0130Shoumkh return Ok(0); 395*36fd0130Shoumkh } 396*36fd0130Shoumkh 397*36fd0130Shoumkh /// # 将时间源从监视链表中弹出 398*36fd0130Shoumkh fn clocksource_dequeue_watchdog(&self) { 399*36fd0130Shoumkh let data = self.clocksource_data(); 400*36fd0130Shoumkh let mut locked_watchdog = CLOCKSOUCE_WATCHDOG.lock(); 401*36fd0130Shoumkh let watchdog = locked_watchdog 402*36fd0130Shoumkh .get_watchdog() 403*36fd0130Shoumkh .clone() 404*36fd0130Shoumkh .unwrap() 405*36fd0130Shoumkh .clocksource_data(); 406*36fd0130Shoumkh 407*36fd0130Shoumkh let mut list = WATCHDOG_LIST.lock(); 408*36fd0130Shoumkh let mut size = list.len(); 409*36fd0130Shoumkh 410*36fd0130Shoumkh let mut del_pos: usize = size; 411*36fd0130Shoumkh for (pos, ele) in list.iter().enumerate() { 412*36fd0130Shoumkh let ele_data = ele.clocksource_data(); 413*36fd0130Shoumkh if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) { 414*36fd0130Shoumkh // 记录要删除的时钟源在监视链表中的下标 415*36fd0130Shoumkh del_pos = pos; 416*36fd0130Shoumkh } 417*36fd0130Shoumkh } 418*36fd0130Shoumkh 419*36fd0130Shoumkh if data 420*36fd0130Shoumkh .flags 421*36fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY) 422*36fd0130Shoumkh { 423*36fd0130Shoumkh // 如果时钟源是需要被检查的,直接删除时钟源 424*36fd0130Shoumkh if del_pos != size { 425*36fd0130Shoumkh let mut temp_list = list.split_off(del_pos); 426*36fd0130Shoumkh temp_list.pop_front(); 427*36fd0130Shoumkh list.append(&mut temp_list); 428*36fd0130Shoumkh } 429*36fd0130Shoumkh } else if watchdog.name.eq(&data.name) && watchdog.rating.eq(&data.rating) { 430*36fd0130Shoumkh // 如果要删除的时钟源是监视器,则需要找到一个新的监视器 431*36fd0130Shoumkh // TODO 重新设置时钟源 432*36fd0130Shoumkh // 将链表解锁防止reset中双重加锁 并释放保存的旧的watchdog的数据 433*36fd0130Shoumkh 434*36fd0130Shoumkh // 代替了clocksource_reset_watchdog()的功能,将所有时钟源的watchdog标记清除 435*36fd0130Shoumkh for ele in list.iter() { 436*36fd0130Shoumkh ele.clocksource_data() 437*36fd0130Shoumkh .flags 438*36fd0130Shoumkh .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 439*36fd0130Shoumkh } 440*36fd0130Shoumkh 441*36fd0130Shoumkh // 遍历所有时间源,寻找新的监视器 442*36fd0130Shoumkh let mut clocksource_list = CLOCKSOURCE_LIST.lock(); 443*36fd0130Shoumkh let mut replace_pos: usize = clocksource_list.len(); 444*36fd0130Shoumkh for (pos, ele) in clocksource_list.iter().enumerate() { 445*36fd0130Shoumkh let ele_data = ele.clocksource_data(); 446*36fd0130Shoumkh 447*36fd0130Shoumkh if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) 448*36fd0130Shoumkh || ele_data 449*36fd0130Shoumkh .flags 450*36fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY) 451*36fd0130Shoumkh { 452*36fd0130Shoumkh // 当前时钟源是要被删除的时钟源或没被检查过的时钟源 453*36fd0130Shoumkh // 不适合成为监视器 454*36fd0130Shoumkh continue; 455*36fd0130Shoumkh } 456*36fd0130Shoumkh let watchdog = locked_watchdog.get_watchdog().clone(); 457*36fd0130Shoumkh if watchdog.is_none() 458*36fd0130Shoumkh || ele_data.rating > watchdog.unwrap().clocksource_data().rating 459*36fd0130Shoumkh { 460*36fd0130Shoumkh // 如果watchdog不存在或者当前时钟源的精度高于watchdog的精度,则记录当前时钟源的下标 461*36fd0130Shoumkh replace_pos = pos; 462*36fd0130Shoumkh } 463*36fd0130Shoumkh } 464*36fd0130Shoumkh // 使用刚刚找到的更好的时钟源替换旧的watchdog 465*36fd0130Shoumkh if replace_pos < clocksource_list.len() { 466*36fd0130Shoumkh let mut temp_list = clocksource_list.split_off(replace_pos); 467*36fd0130Shoumkh let new_wd = temp_list.front().unwrap().clone(); 468*36fd0130Shoumkh clocksource_list.append(&mut temp_list); 469*36fd0130Shoumkh // 替换watchdog 470*36fd0130Shoumkh locked_watchdog.watchdog.replace(new_wd); 471*36fd0130Shoumkh // drop(locked_watchdog); 472*36fd0130Shoumkh } 473*36fd0130Shoumkh // 删除时钟源 474*36fd0130Shoumkh if del_pos != size { 475*36fd0130Shoumkh let mut temp_list = list.split_off(del_pos); 476*36fd0130Shoumkh temp_list.pop_front(); 477*36fd0130Shoumkh list.append(&mut temp_list); 478*36fd0130Shoumkh } 479*36fd0130Shoumkh } 480*36fd0130Shoumkh 481*36fd0130Shoumkh // 清除watchdog标记 482*36fd0130Shoumkh let mut cs_data = self.clocksource_data(); 483*36fd0130Shoumkh cs_data 484*36fd0130Shoumkh .flags 485*36fd0130Shoumkh .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 486*36fd0130Shoumkh self.update_clocksource_data(cs_data) 487*36fd0130Shoumkh .expect("clocksource_dequeue_watchdog: failed to update clocksource data"); 488*36fd0130Shoumkh size = list.len(); 489*36fd0130Shoumkh // 停止当前的watchdog 490*36fd0130Shoumkh locked_watchdog.clocksource_stop_watchdog(size - 1); 491*36fd0130Shoumkh } 492*36fd0130Shoumkh 493*36fd0130Shoumkh /// # 将时钟源从时钟源链表中弹出 494*36fd0130Shoumkh fn clocksource_dequeue(&self) { 495*36fd0130Shoumkh let mut list = CLOCKSOURCE_LIST.lock(); 496*36fd0130Shoumkh let data = self.clocksource_data(); 497*36fd0130Shoumkh let mut del_pos: usize = list.len(); 498*36fd0130Shoumkh for (pos, ele) in list.iter().enumerate() { 499*36fd0130Shoumkh let ele_data = ele.clocksource_data(); 500*36fd0130Shoumkh if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) { 501*36fd0130Shoumkh // 记录时钟源在链表中的下标 502*36fd0130Shoumkh del_pos = pos; 503*36fd0130Shoumkh } 504*36fd0130Shoumkh } 505*36fd0130Shoumkh 506*36fd0130Shoumkh // 删除时钟源 507*36fd0130Shoumkh if del_pos != list.len() { 508*36fd0130Shoumkh let mut temp_list = list.split_off(del_pos); 509*36fd0130Shoumkh temp_list.pop_front(); 510*36fd0130Shoumkh list.append(&mut temp_list); 511*36fd0130Shoumkh } 512*36fd0130Shoumkh } 513*36fd0130Shoumkh 514*36fd0130Shoumkh /// # 注销时钟源 515*36fd0130Shoumkh #[allow(dead_code)] 516*36fd0130Shoumkh pub fn unregister(&self) { 517*36fd0130Shoumkh // 将时钟源从监视链表中弹出 518*36fd0130Shoumkh self.clocksource_dequeue_watchdog(); 519*36fd0130Shoumkh // 将时钟源从时钟源链表中弹出 520*36fd0130Shoumkh self.clocksource_dequeue(); 521*36fd0130Shoumkh // 检查是否有更好的时钟源 522*36fd0130Shoumkh clocksource_select(); 523*36fd0130Shoumkh } 524*36fd0130Shoumkh /// # 修改时钟源的精度 525*36fd0130Shoumkh /// 526*36fd0130Shoumkh /// ## 参数 527*36fd0130Shoumkh /// 528*36fd0130Shoumkh /// * `rating` - 指定的时钟精度 529*36fd0130Shoumkh fn clocksource_change_rating(&self, rating: i32) { 530*36fd0130Shoumkh // 将时钟源从链表中弹出 531*36fd0130Shoumkh self.clocksource_dequeue(); 532*36fd0130Shoumkh let mut data = self.clocksource_data(); 533*36fd0130Shoumkh // 修改时钟源的精度 534*36fd0130Shoumkh data.set_rating(rating); 535*36fd0130Shoumkh self.update_clocksource_data(data) 536*36fd0130Shoumkh .expect("clocksource_change_rating:updata clocksource failed"); 537*36fd0130Shoumkh // 插入时钟源到时钟源链表中 538*36fd0130Shoumkh self.clocksource_enqueue(); 539*36fd0130Shoumkh // 检查是否有更好的时钟源 540*36fd0130Shoumkh clocksource_select(); 541*36fd0130Shoumkh } 542*36fd0130Shoumkh } 543*36fd0130Shoumkh 544*36fd0130Shoumkh #[derive(Debug, Clone)] 545*36fd0130Shoumkh pub struct ClocksourceData { 546*36fd0130Shoumkh /// 时钟源名字 547*36fd0130Shoumkh pub name: String, 548*36fd0130Shoumkh /// 时钟精度 549*36fd0130Shoumkh pub rating: i32, 550*36fd0130Shoumkh pub mask: ClocksourceMask, 551*36fd0130Shoumkh pub mult: u32, 552*36fd0130Shoumkh pub shift: u32, 553*36fd0130Shoumkh pub max_idle_ns: u32, 554*36fd0130Shoumkh pub flags: ClocksourceFlags, 555*36fd0130Shoumkh pub watchdog_last: CycleNum, 556*36fd0130Shoumkh } 557*36fd0130Shoumkh 558*36fd0130Shoumkh impl ClocksourceData { 559*36fd0130Shoumkh #[allow(dead_code)] 560*36fd0130Shoumkh pub fn new( 561*36fd0130Shoumkh name: String, 562*36fd0130Shoumkh rating: i32, 563*36fd0130Shoumkh mask: ClocksourceMask, 564*36fd0130Shoumkh mult: u32, 565*36fd0130Shoumkh shift: u32, 566*36fd0130Shoumkh max_idle_ns: u32, 567*36fd0130Shoumkh flags: ClocksourceFlags, 568*36fd0130Shoumkh ) -> Self { 569*36fd0130Shoumkh let csd = ClocksourceData { 570*36fd0130Shoumkh name, 571*36fd0130Shoumkh rating, 572*36fd0130Shoumkh mask, 573*36fd0130Shoumkh mult, 574*36fd0130Shoumkh shift, 575*36fd0130Shoumkh max_idle_ns, 576*36fd0130Shoumkh flags, 577*36fd0130Shoumkh watchdog_last: CycleNum(0), 578*36fd0130Shoumkh }; 579*36fd0130Shoumkh return csd; 580*36fd0130Shoumkh } 581*36fd0130Shoumkh 582*36fd0130Shoumkh pub fn set_name(&mut self, name: String) { 583*36fd0130Shoumkh self.name = name; 584*36fd0130Shoumkh } 585*36fd0130Shoumkh pub fn set_rating(&mut self, rating: i32) { 586*36fd0130Shoumkh self.rating = rating; 587*36fd0130Shoumkh } 588*36fd0130Shoumkh pub fn set_mask(&mut self, mask: ClocksourceMask) { 589*36fd0130Shoumkh self.mask = mask; 590*36fd0130Shoumkh } 591*36fd0130Shoumkh pub fn set_mult(&mut self, mult: u32) { 592*36fd0130Shoumkh self.mult = mult; 593*36fd0130Shoumkh } 594*36fd0130Shoumkh pub fn set_shift(&mut self, shift: u32) { 595*36fd0130Shoumkh self.shift = shift; 596*36fd0130Shoumkh } 597*36fd0130Shoumkh pub fn set_max_idle_ns(&mut self, max_idle_ns: u32) { 598*36fd0130Shoumkh self.max_idle_ns = max_idle_ns; 599*36fd0130Shoumkh } 600*36fd0130Shoumkh pub fn set_flags(&mut self, flags: ClocksourceFlags) { 601*36fd0130Shoumkh self.flags = flags; 602*36fd0130Shoumkh } 603*36fd0130Shoumkh #[allow(dead_code)] 604*36fd0130Shoumkh pub fn remove_flags(&mut self, flags: ClocksourceFlags) { 605*36fd0130Shoumkh self.flags.remove(flags) 606*36fd0130Shoumkh } 607*36fd0130Shoumkh #[allow(dead_code)] 608*36fd0130Shoumkh pub fn insert_flags(&mut self, flags: ClocksourceFlags) { 609*36fd0130Shoumkh self.flags.insert(flags) 610*36fd0130Shoumkh } 611*36fd0130Shoumkh } 612*36fd0130Shoumkh 613*36fd0130Shoumkh /// converts clocksource cycles to nanoseconds 614*36fd0130Shoumkh /// 615*36fd0130Shoumkh pub fn clocksource_cyc2ns(cycles: CycleNum, mult: u32, shift: u32) -> u64 { 616*36fd0130Shoumkh return (cycles.data() * mult as u64) >> shift; 617*36fd0130Shoumkh } 618*36fd0130Shoumkh 619*36fd0130Shoumkh /// # 重启所有的时间源 620*36fd0130Shoumkh #[allow(dead_code)] 621*36fd0130Shoumkh pub fn clocksource_resume() { 622*36fd0130Shoumkh let list = CLOCKSOURCE_LIST.lock(); 623*36fd0130Shoumkh for ele in list.iter() { 624*36fd0130Shoumkh let data = ele.clocksource_data(); 625*36fd0130Shoumkh match ele.resume() { 626*36fd0130Shoumkh Ok(_) => continue, 627*36fd0130Shoumkh Err(_) => { 628*36fd0130Shoumkh kdebug!("clocksource {:?} resume failed", data.name) 629*36fd0130Shoumkh } 630*36fd0130Shoumkh } 631*36fd0130Shoumkh } 632*36fd0130Shoumkh clocksource_resume_watchdog(); 633*36fd0130Shoumkh } 634*36fd0130Shoumkh 635*36fd0130Shoumkh /// # 暂停所有的时间源 636*36fd0130Shoumkh #[allow(dead_code)] 637*36fd0130Shoumkh pub fn clocksource_suspend() { 638*36fd0130Shoumkh let list = CLOCKSOURCE_LIST.lock(); 639*36fd0130Shoumkh for ele in list.iter() { 640*36fd0130Shoumkh let data = ele.clocksource_data(); 641*36fd0130Shoumkh match ele.suspend() { 642*36fd0130Shoumkh Ok(_) => continue, 643*36fd0130Shoumkh Err(_) => { 644*36fd0130Shoumkh kdebug!("clocksource {:?} suspend failed", data.name) 645*36fd0130Shoumkh } 646*36fd0130Shoumkh } 647*36fd0130Shoumkh } 648*36fd0130Shoumkh } 649*36fd0130Shoumkh 650*36fd0130Shoumkh /// # 根据watchdog的精度,来检查被监视的时钟源的误差 651*36fd0130Shoumkh /// 652*36fd0130Shoumkh /// ## 返回值 653*36fd0130Shoumkh /// 654*36fd0130Shoumkh /// * `Ok()` - 检查完成 655*36fd0130Shoumkh /// * `Err(SystemError)` - 错误码 656*36fd0130Shoumkh pub fn clocksource_watchdog() -> Result<(), SystemError> { 657*36fd0130Shoumkh let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock(); 658*36fd0130Shoumkh 659*36fd0130Shoumkh // watchdog没有在运行的话直接退出 660*36fd0130Shoumkh if !cs_watchdog.is_running || cs_watchdog.watchdog.is_none() { 661*36fd0130Shoumkh return Ok(()); 662*36fd0130Shoumkh } 663*36fd0130Shoumkh let cur_watchdog = cs_watchdog.watchdog.as_ref().unwrap().clone(); 664*36fd0130Shoumkh let cur_wd_data = cur_watchdog.as_ref().clocksource_data(); 665*36fd0130Shoumkh let cur_wd_nowclock = cur_watchdog.as_ref().read().data(); 666*36fd0130Shoumkh 667*36fd0130Shoumkh let wd_last = cs_watchdog.last_check.data(); 668*36fd0130Shoumkh let wd_dev_nsec = clocksource_cyc2ns( 669*36fd0130Shoumkh CycleNum((cur_wd_nowclock - wd_last) & cur_wd_data.mask.bits), 670*36fd0130Shoumkh cur_wd_data.mult, 671*36fd0130Shoumkh cur_wd_data.shift, 672*36fd0130Shoumkh ); 673*36fd0130Shoumkh cs_watchdog.last_check = CycleNum(cur_wd_nowclock); 674*36fd0130Shoumkh drop(cs_watchdog); 675*36fd0130Shoumkh let watchdog_list = &mut WATCHDOG_LIST.lock(); 676*36fd0130Shoumkh for cs in watchdog_list.iter() { 677*36fd0130Shoumkh let mut cs_data = cs.clocksource_data(); 678*36fd0130Shoumkh // 判断时钟源是否已经被标记为不稳定 679*36fd0130Shoumkh if cs_data 680*36fd0130Shoumkh .flags 681*36fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) 682*36fd0130Shoumkh { 683*36fd0130Shoumkh // 启动watchdog_kthread 684*36fd0130Shoumkh unsafe { run_watchdog_kthread() }; 685*36fd0130Shoumkh continue; 686*36fd0130Shoumkh } 687*36fd0130Shoumkh // 读取时钟源现在的时间 688*36fd0130Shoumkh let cs_now_clock = cs.read(); 689*36fd0130Shoumkh 690*36fd0130Shoumkh // 如果时钟源没有被监视,则开始监视他 691*36fd0130Shoumkh if !cs_data 692*36fd0130Shoumkh .flags 693*36fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG) 694*36fd0130Shoumkh { 695*36fd0130Shoumkh cs_data 696*36fd0130Shoumkh .flags 697*36fd0130Shoumkh .insert(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 698*36fd0130Shoumkh // 记录此次检查的时刻 699*36fd0130Shoumkh cs_data.watchdog_last = cs_now_clock; 700*36fd0130Shoumkh cs.update_clocksource_data(cs_data.clone())?; 701*36fd0130Shoumkh continue; 702*36fd0130Shoumkh } 703*36fd0130Shoumkh 704*36fd0130Shoumkh // 计算时钟源的误差 705*36fd0130Shoumkh let cs_dev_nsec = clocksource_cyc2ns( 706*36fd0130Shoumkh CycleNum(cs_now_clock.div(cs_data.watchdog_last).data() & cs_data.mask.bits), 707*36fd0130Shoumkh cs_data.mult, 708*36fd0130Shoumkh cs_data.shift, 709*36fd0130Shoumkh ); 710*36fd0130Shoumkh // 记录此次检查的时刻 711*36fd0130Shoumkh cs_data.watchdog_last = cs_now_clock; 712*36fd0130Shoumkh cs.update_clocksource_data(cs_data.clone())?; 713*36fd0130Shoumkh if cs_dev_nsec.abs_diff(wd_dev_nsec) > WATCHDOG_THRESHOLD.into() { 714*36fd0130Shoumkh // 误差过大,标记为unstable 715*36fd0130Shoumkh cs.set_unstable((cs_dev_nsec - wd_dev_nsec).try_into().unwrap())?; 716*36fd0130Shoumkh continue; 717*36fd0130Shoumkh } 718*36fd0130Shoumkh 719*36fd0130Shoumkh // 判断是否要切换为高精度模式 720*36fd0130Shoumkh if !cs_data 721*36fd0130Shoumkh .flags 722*36fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES) 723*36fd0130Shoumkh && cs_data 724*36fd0130Shoumkh .flags 725*36fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS) 726*36fd0130Shoumkh && cur_wd_data 727*36fd0130Shoumkh .flags 728*36fd0130Shoumkh .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS) 729*36fd0130Shoumkh { 730*36fd0130Shoumkh cs_data 731*36fd0130Shoumkh .flags 732*36fd0130Shoumkh .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES); 733*36fd0130Shoumkh cs.update_clocksource_data(cs_data)?; 734*36fd0130Shoumkh // TODO 通知tick机制 切换为高精度模式 735*36fd0130Shoumkh } 736*36fd0130Shoumkh let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock(); 737*36fd0130Shoumkh // FIXME 需要保证所有cpu时间统一 738*36fd0130Shoumkh cs_watchdog.timer_expires += WATCHDOG_INTERVAL; 739*36fd0130Shoumkh //创建定时器执行watchdog 740*36fd0130Shoumkh let watchdog_func = Box::new(WatchdogTimerFunc {}); 741*36fd0130Shoumkh let watchdog_timer = Timer::new(watchdog_func, cs_watchdog.timer_expires); 742*36fd0130Shoumkh watchdog_timer.activate(); 743*36fd0130Shoumkh } 744*36fd0130Shoumkh return Ok(()); 745*36fd0130Shoumkh } 746*36fd0130Shoumkh 747*36fd0130Shoumkh /// # watchdog线程的逻辑,执行unstable的后续操作 748*36fd0130Shoumkh pub fn clocksource_watchdog_kthread() { 749*36fd0130Shoumkh let mut del_vec: Vec<usize> = Vec::new(); 750*36fd0130Shoumkh let mut del_clocks: Vec<Arc<dyn Clocksource>> = Vec::new(); 751*36fd0130Shoumkh let wd_list = &mut WATCHDOG_LIST.lock(); 752*36fd0130Shoumkh 753*36fd0130Shoumkh // 将不稳定的时钟源弹出监视链表 754*36fd0130Shoumkh for (pos, ele) in wd_list.iter().enumerate() { 755*36fd0130Shoumkh let data = ele.clocksource_data(); 756*36fd0130Shoumkh if data.flags.contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) { 757*36fd0130Shoumkh del_vec.push(pos); 758*36fd0130Shoumkh del_clocks.push(ele.clone()); 759*36fd0130Shoumkh } 760*36fd0130Shoumkh } 761*36fd0130Shoumkh for pos in del_vec { 762*36fd0130Shoumkh let mut temp_list = wd_list.split_off(pos); 763*36fd0130Shoumkh temp_list.pop_front(); 764*36fd0130Shoumkh wd_list.append(&mut temp_list); 765*36fd0130Shoumkh } 766*36fd0130Shoumkh 767*36fd0130Shoumkh // 检查是否需要停止watchdog 768*36fd0130Shoumkh CLOCKSOUCE_WATCHDOG 769*36fd0130Shoumkh .lock() 770*36fd0130Shoumkh .clocksource_stop_watchdog(wd_list.len()); 771*36fd0130Shoumkh // 将不稳定的时钟源精度都设置为最低 772*36fd0130Shoumkh for clock in del_clocks.iter() { 773*36fd0130Shoumkh clock.clocksource_change_rating(0); 774*36fd0130Shoumkh } 775*36fd0130Shoumkh } 776*36fd0130Shoumkh 777*36fd0130Shoumkh /// # 清空所有时钟源的watchdog标志位 778*36fd0130Shoumkh pub fn clocksource_reset_watchdog() { 779*36fd0130Shoumkh let list_guard = WATCHDOG_LIST.lock(); 780*36fd0130Shoumkh for ele in list_guard.iter() { 781*36fd0130Shoumkh ele.clocksource_data() 782*36fd0130Shoumkh .flags 783*36fd0130Shoumkh .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 784*36fd0130Shoumkh } 785*36fd0130Shoumkh } 786*36fd0130Shoumkh 787*36fd0130Shoumkh /// # 重启检查器 788*36fd0130Shoumkh pub fn clocksource_resume_watchdog() { 789*36fd0130Shoumkh clocksource_reset_watchdog(); 790*36fd0130Shoumkh } 791*36fd0130Shoumkh 792*36fd0130Shoumkh /// # 根据精度选择最优的时钟源,或者接受用户指定的时间源 793*36fd0130Shoumkh pub fn clocksource_select() { 794*36fd0130Shoumkh let list_guard = CLOCKSOURCE_LIST.lock(); 795*36fd0130Shoumkh if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } || list_guard.is_empty() { 796*36fd0130Shoumkh return; 797*36fd0130Shoumkh } 798*36fd0130Shoumkh let mut best = list_guard.front().unwrap().clone(); 799*36fd0130Shoumkh let override_name = OVERRIDE_NAME.lock(); 800*36fd0130Shoumkh // 判断是否有用户空间指定的时间源 801*36fd0130Shoumkh for ele in list_guard.iter() { 802*36fd0130Shoumkh if ele.clocksource_data().name.eq(override_name.deref()) { 803*36fd0130Shoumkh // TODO 判断是否是高精度模式 804*36fd0130Shoumkh // 暂时不支持高精度模式 805*36fd0130Shoumkh // 如果是高精度模式,但是时钟源不支持高精度模式的话,就要退出循环 806*36fd0130Shoumkh best = ele.clone(); 807*36fd0130Shoumkh break; 808*36fd0130Shoumkh } 809*36fd0130Shoumkh } 810*36fd0130Shoumkh // 对比当前的时钟源和记录到最好的时钟源的精度 811*36fd0130Shoumkh if CUR_CLOCKSOURCE.lock().as_ref().is_some() { 812*36fd0130Shoumkh // 当前时钟源不为空 813*36fd0130Shoumkh let cur_clocksource = CUR_CLOCKSOURCE.lock().as_ref().unwrap().clone(); 814*36fd0130Shoumkh let best_name = &best.clocksource_data().name; 815*36fd0130Shoumkh if cur_clocksource.clocksource_data().name.ne(best_name) { 816*36fd0130Shoumkh kinfo!("Switching to the clocksource {:?}\n", best_name); 817*36fd0130Shoumkh drop(cur_clocksource); 818*36fd0130Shoumkh CUR_CLOCKSOURCE.lock().replace(best); 819*36fd0130Shoumkh // TODO 通知timerkeeping 切换了时间源 820*36fd0130Shoumkh } 821*36fd0130Shoumkh } else { 822*36fd0130Shoumkh // 当前时钟源为空 823*36fd0130Shoumkh CUR_CLOCKSOURCE.lock().replace(best); 824*36fd0130Shoumkh } 825*36fd0130Shoumkh kdebug!(" clocksource_select finish"); 826*36fd0130Shoumkh } 827*36fd0130Shoumkh 828*36fd0130Shoumkh /// # clocksource模块加载完成 829*36fd0130Shoumkh pub fn clocksource_boot_finish() { 830*36fd0130Shoumkh let mut cur_clocksource = CUR_CLOCKSOURCE.lock(); 831*36fd0130Shoumkh cur_clocksource.replace(clocksource_default_clock()); 832*36fd0130Shoumkh unsafe { FINISHED_BOOTING.store(true, Ordering::Relaxed) }; 833*36fd0130Shoumkh // 清除不稳定的时钟源 834*36fd0130Shoumkh clocksource_watchdog_kthread(); 835*36fd0130Shoumkh kdebug!("clocksource_boot_finish"); 836*36fd0130Shoumkh } 837*36fd0130Shoumkh 838*36fd0130Shoumkh // ======== 以下为对C的接口 ======== 839*36fd0130Shoumkh /// # 完成对clocksource模块的加载 840*36fd0130Shoumkh #[no_mangle] 841*36fd0130Shoumkh pub extern "C" fn rs_clocksource_boot_finish() { 842*36fd0130Shoumkh clocksource_boot_finish(); 843*36fd0130Shoumkh } 844*36fd0130Shoumkh 845*36fd0130Shoumkh /// # 启动watchdog线程的辅助函数 846*36fd0130Shoumkh #[no_mangle] 847*36fd0130Shoumkh pub extern "C" fn rs_clocksource_watchdog_kthread(_data: c_void) -> i32 { 848*36fd0130Shoumkh clocksource_watchdog_kthread(); 849*36fd0130Shoumkh return 0; 850*36fd0130Shoumkh } 851