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