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