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