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