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