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 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 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 debug!("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 // debug!( 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 debug!( 477 "clocksource :{:?} is unstable, its delta is {:?}", 478 cs_data.name, delta 479 ); 480 cs_data.flags.remove( 481 ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES | ClocksourceFlags::CLOCK_SOURCE_WATCHDOG, 482 ); 483 cs_data 484 .flags 485 .insert(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE); 486 self.update_clocksource_data(cs_data)?; 487 488 // 启动watchdog线程 进行后续处理 489 if FINISHED_BOOTING.load(Ordering::Relaxed) { 490 // TODO 在实现了工作队列后,将启动线程换成schedule work 491 run_watchdog_kthread(); 492 } 493 return Ok(0); 494 } 495 496 /// # 将时间源从监视链表中弹出 497 fn clocksource_dequeue_watchdog(&self) { 498 let data = self.clocksource_data(); 499 let mut locked_watchdog = CLOCKSOUCE_WATCHDOG.lock_irqsave(); 500 let watchdog = locked_watchdog 501 .get_watchdog() 502 .clone() 503 .unwrap() 504 .clocksource_data(); 505 506 let mut list = WATCHDOG_LIST.lock_irqsave(); 507 let mut size = list.len(); 508 509 let mut del_pos: usize = size; 510 for (pos, ele) in list.iter().enumerate() { 511 let ele_data = ele.clocksource_data(); 512 if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) { 513 // 记录要删除的时钟源在监视链表中的下标 514 del_pos = pos; 515 } 516 } 517 518 if data 519 .flags 520 .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY) 521 { 522 // 如果时钟源是需要被检查的,直接删除时钟源 523 if del_pos != size { 524 let mut temp_list = list.split_off(del_pos); 525 temp_list.pop_front(); 526 list.append(&mut temp_list); 527 } 528 } else if watchdog.name.eq(&data.name) && watchdog.rating.eq(&data.rating) { 529 // 如果要删除的时钟源是监视器,则需要找到一个新的监视器 530 // TODO 重新设置时钟源 531 // 将链表解锁防止reset中双重加锁 并释放保存的旧的watchdog的数据 532 533 // 代替了clocksource_reset_watchdog()的功能,将所有时钟源的watchdog标记清除 534 for ele in list.iter() { 535 ele.clocksource_data() 536 .flags 537 .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 538 } 539 540 // 遍历所有时间源,寻找新的监视器 541 let mut clocksource_list = CLOCKSOURCE_LIST.lock(); 542 let mut replace_pos: usize = clocksource_list.len(); 543 for (pos, ele) in clocksource_list.iter().enumerate() { 544 let ele_data = ele.clocksource_data(); 545 546 if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) 547 || ele_data 548 .flags 549 .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY) 550 { 551 // 当前时钟源是要被删除的时钟源或没被检查过的时钟源 552 // 不适合成为监视器 553 continue; 554 } 555 let watchdog = locked_watchdog.get_watchdog().clone(); 556 if watchdog.is_none() 557 || ele_data.rating > watchdog.unwrap().clocksource_data().rating 558 { 559 // 如果watchdog不存在或者当前时钟源的精度高于watchdog的精度,则记录当前时钟源的下标 560 replace_pos = pos; 561 } 562 } 563 // 使用刚刚找到的更好的时钟源替换旧的watchdog 564 if replace_pos < clocksource_list.len() { 565 let mut temp_list = clocksource_list.split_off(replace_pos); 566 let new_wd = temp_list.front().unwrap().clone(); 567 clocksource_list.append(&mut temp_list); 568 // 替换watchdog 569 locked_watchdog.watchdog.replace(new_wd); 570 // drop(locked_watchdog); 571 } 572 // 删除时钟源 573 if del_pos != size { 574 let mut temp_list = list.split_off(del_pos); 575 temp_list.pop_front(); 576 list.append(&mut temp_list); 577 } 578 } 579 580 // 清除watchdog标记 581 let mut cs_data = self.clocksource_data(); 582 cs_data 583 .flags 584 .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 585 self.update_clocksource_data(cs_data) 586 .expect("clocksource_dequeue_watchdog: failed to update clocksource data"); 587 size = list.len(); 588 // 停止当前的watchdog 589 locked_watchdog.clocksource_stop_watchdog(size - 1); 590 } 591 592 /// # 将时钟源从时钟源链表中弹出 593 fn clocksource_dequeue(&self) { 594 let mut list = CLOCKSOURCE_LIST.lock(); 595 let data = self.clocksource_data(); 596 let mut del_pos: usize = list.len(); 597 for (pos, ele) in list.iter().enumerate() { 598 let ele_data = ele.clocksource_data(); 599 if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) { 600 // 记录时钟源在链表中的下标 601 del_pos = pos; 602 } 603 } 604 605 // 删除时钟源 606 if del_pos != list.len() { 607 let mut temp_list = list.split_off(del_pos); 608 temp_list.pop_front(); 609 list.append(&mut temp_list); 610 } 611 } 612 613 /// # 注销时钟源 614 #[allow(dead_code)] 615 pub fn unregister(&self) { 616 // 将时钟源从监视链表中弹出 617 self.clocksource_dequeue_watchdog(); 618 // 将时钟源从时钟源链表中弹出 619 self.clocksource_dequeue(); 620 // 检查是否有更好的时钟源 621 clocksource_select(); 622 } 623 /// # 修改时钟源的精度 624 /// 625 /// ## 参数 626 /// 627 /// * `rating` - 指定的时钟精度 628 fn clocksource_change_rating(&self, rating: i32) { 629 // 将时钟源从链表中弹出 630 self.clocksource_dequeue(); 631 let mut data = self.clocksource_data(); 632 // 修改时钟源的精度 633 data.set_rating(rating); 634 self.update_clocksource_data(data) 635 .expect("clocksource_change_rating:updata clocksource failed"); 636 // 插入时钟源到时钟源链表中 637 self.clocksource_enqueue(); 638 // 检查是否有更好的时钟源 639 clocksource_select(); 640 } 641 } 642 643 #[derive(Debug, Clone)] 644 pub struct ClocksourceData { 645 /// 时钟源名字 646 pub name: String, 647 /// 时钟精度 648 pub rating: i32, 649 pub mask: ClocksourceMask, 650 pub mult: u32, 651 pub shift: u32, 652 pub max_idle_ns: u32, 653 pub flags: ClocksourceFlags, 654 pub watchdog_last: CycleNum, 655 // 用于描述时钟源的不确定性边界,时钟源读取的时间可能存在的不确定性和误差范围 656 pub uncertainty_margin: u32, 657 // 最大的时间调整量 658 pub maxadj: u32, 659 } 660 661 impl ClocksourceData { 662 #[allow(dead_code)] 663 #[allow(clippy::too_many_arguments)] 664 pub fn new( 665 name: String, 666 rating: i32, 667 mask: ClocksourceMask, 668 mult: u32, 669 shift: u32, 670 max_idle_ns: u32, 671 flags: ClocksourceFlags, 672 uncertainty_margin: u32, 673 maxadj: u32, 674 ) -> Self { 675 let csd = ClocksourceData { 676 name, 677 rating, 678 mask, 679 mult, 680 shift, 681 max_idle_ns, 682 flags, 683 watchdog_last: CycleNum(0), 684 uncertainty_margin, 685 maxadj, 686 }; 687 return csd; 688 } 689 690 pub fn set_name(&mut self, name: String) { 691 self.name = name; 692 } 693 pub fn set_rating(&mut self, rating: i32) { 694 self.rating = rating; 695 } 696 pub fn set_mask(&mut self, mask: ClocksourceMask) { 697 self.mask = mask; 698 } 699 pub fn set_mult(&mut self, mult: u32) { 700 self.mult = mult; 701 } 702 pub fn set_shift(&mut self, shift: u32) { 703 self.shift = shift; 704 } 705 pub fn set_max_idle_ns(&mut self, max_idle_ns: u32) { 706 self.max_idle_ns = max_idle_ns; 707 } 708 pub fn set_flags(&mut self, flags: ClocksourceFlags) { 709 self.flags = flags; 710 } 711 #[allow(dead_code)] 712 pub fn remove_flags(&mut self, flags: ClocksourceFlags) { 713 self.flags.remove(flags) 714 } 715 #[allow(dead_code)] 716 pub fn insert_flags(&mut self, flags: ClocksourceFlags) { 717 self.flags.insert(flags) 718 } 719 pub fn set_uncertainty_margin(&mut self, uncertainty_margin: u32) { 720 self.uncertainty_margin = uncertainty_margin; 721 } 722 pub fn set_maxadj(&mut self, maxadj: u32) { 723 self.maxadj = maxadj; 724 } 725 } 726 727 /// converts clocksource cycles to nanoseconds 728 /// 729 pub fn clocksource_cyc2ns(cycles: CycleNum, mult: u32, shift: u32) -> u64 { 730 return (cycles.data() * mult as u64) >> shift; 731 } 732 733 /// # 重启所有的时间源 734 #[allow(dead_code)] 735 pub fn clocksource_resume() { 736 let list = CLOCKSOURCE_LIST.lock(); 737 for ele in list.iter() { 738 let data = ele.clocksource_data(); 739 match ele.resume() { 740 Ok(_) => continue, 741 Err(_) => { 742 debug!("clocksource {:?} resume failed", data.name); 743 } 744 } 745 } 746 clocksource_resume_watchdog(); 747 } 748 749 /// # 暂停所有的时间源 750 #[allow(dead_code)] 751 pub fn clocksource_suspend() { 752 let list = CLOCKSOURCE_LIST.lock(); 753 for ele in list.iter() { 754 let data = ele.clocksource_data(); 755 match ele.suspend() { 756 Ok(_) => continue, 757 Err(_) => { 758 debug!("clocksource {:?} suspend failed", data.name); 759 } 760 } 761 } 762 } 763 764 /// # 根据watchdog的精度,来检查被监视的时钟源的误差 765 /// 766 /// ## 返回值 767 /// 768 /// * `Ok()` - 检查完成 769 /// * `Err(SystemError)` - 错误码 770 pub fn clocksource_watchdog() -> Result<(), SystemError> { 771 let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock_irqsave(); 772 // debug!("clocksource_watchdog start"); 773 774 // watchdog没有在运行的话直接退出 775 if !cs_watchdog.is_running || cs_watchdog.watchdog.is_none() { 776 // debug!("is_running = {:?},watchdog = {:?}", cs_watchdog.is_running, cs_watchdog.watchdog); 777 return Ok(()); 778 } 779 let cur_watchdog = cs_watchdog.watchdog.as_ref().unwrap().clone(); 780 let cur_wd_data = cur_watchdog.as_ref().clocksource_data(); 781 let cur_wd_nowclock = cur_watchdog.as_ref().read().data(); 782 783 let wd_last = cs_watchdog.last_check.data(); 784 let wd_dev_nsec = clocksource_cyc2ns( 785 CycleNum((cur_wd_nowclock - wd_last) & cur_wd_data.mask.bits), 786 cur_wd_data.mult, 787 cur_wd_data.shift, 788 ); 789 cs_watchdog.last_check = CycleNum(cur_wd_nowclock); 790 drop(cs_watchdog); 791 let watchdog_list = WATCHDOG_LIST.lock_irqsave(); 792 for cs in watchdog_list.iter() { 793 let mut cs_data = cs.clocksource_data(); 794 // 判断时钟源是否已经被标记为不稳定 795 if cs_data 796 .flags 797 .contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) 798 { 799 // debug!("clocksource_watchdog unstable"); 800 // 启动watchdog_kthread 801 run_watchdog_kthread(); 802 continue; 803 } 804 // 读取时钟源现在的时间 805 let cs_now_clock = cs.read(); 806 807 // 如果时钟源没有被监视,则开始监视他 808 if !cs_data 809 .flags 810 .contains(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG) 811 { 812 // debug!("clocksource_watchdog start watch"); 813 cs_data 814 .flags 815 .insert(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 816 // 记录此次检查的时刻 817 cs_data.watchdog_last = cs_now_clock; 818 cs.update_clocksource_data(cs_data.clone())?; 819 continue; 820 } 821 // debug!("cs_data.watchdog_last = {:?},cs_now_clock = {:?}", cs_data.watchdog_last, cs_now_clock); 822 // 计算时钟源的误差 823 let cs_dev_nsec = clocksource_cyc2ns( 824 CycleNum(cs_now_clock.div(cs_data.watchdog_last).data() & cs_data.mask.bits), 825 cs_data.mult, 826 cs_data.shift, 827 ); 828 // 记录此次检查的时刻 829 cs_data.watchdog_last = cs_now_clock; 830 cs.update_clocksource_data(cs_data.clone())?; 831 if cs_dev_nsec.abs_diff(wd_dev_nsec) > WATCHDOG_THRESHOLD.into() { 832 // debug!("set_unstable"); 833 // 误差过大,标记为unstable 834 info!("cs_dev_nsec = {}", cs_dev_nsec); 835 info!("wd_dev_nsec = {}", wd_dev_nsec); 836 cs.set_unstable((cs_dev_nsec - wd_dev_nsec).try_into().unwrap())?; 837 continue; 838 } 839 // debug!("clocksource_watchdog aaa"); 840 841 // 判断是否要切换为高精度模式 842 if !cs_data 843 .flags 844 .contains(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES) 845 && cs_data 846 .flags 847 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS) 848 && cur_wd_data 849 .flags 850 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS) 851 { 852 cs_data 853 .flags 854 .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES); 855 cs.update_clocksource_data(cs_data)?; 856 // TODO 通知tick机制 切换为高精度模式 857 } 858 } 859 create_new_watchdog_timer_function(); 860 return Ok(()); 861 } 862 863 fn create_new_watchdog_timer_function() { 864 let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock_irqsave(); 865 866 cs_watchdog.timer_expires += WATCHDOG_INTERVAL; 867 //创建定时器执行watchdog 868 let watchdog_func = Box::new(WatchdogTimerFunc {}); 869 let watchdog_timer = Timer::new(watchdog_func, cs_watchdog.timer_expires); 870 watchdog_timer.activate(); 871 } 872 873 fn __clocksource_watchdog_kthread() { 874 let mut del_vec: Vec<usize> = Vec::new(); 875 let mut del_clocks: Vec<Arc<dyn Clocksource>> = Vec::new(); 876 let mut wd_list = WATCHDOG_LIST.lock_irqsave(); 877 878 // 将不稳定的时钟源弹出监视链表 879 for (pos, ele) in wd_list.iter().enumerate() { 880 let data = ele.clocksource_data(); 881 if data.flags.contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) { 882 del_vec.push(pos); 883 del_clocks.push(ele.clone()); 884 } 885 } 886 for pos in del_vec { 887 let mut temp_list = wd_list.split_off(pos); 888 temp_list.pop_front(); 889 wd_list.append(&mut temp_list); 890 } 891 892 // 检查是否需要停止watchdog 893 CLOCKSOUCE_WATCHDOG 894 .lock_irqsave() 895 .clocksource_stop_watchdog(wd_list.len()); 896 drop(wd_list); 897 // 将不稳定的时钟源精度都设置为最低,然后删除unstable标记 898 for clock in del_clocks.iter() { 899 clock.clocksource_change_rating(0); 900 let mut data = clock.clocksource_data(); 901 data.watchdog_last = clock.read(); 902 debug!("kthread: watchdog_last = {:?}", data.watchdog_last); 903 data.flags.remove(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE); 904 clock 905 .update_clocksource_data(data) 906 .expect("clocksource_watchdog_kthread: failed to update clocksource data"); 907 908 // 重新插入监视链表 909 clock 910 .clocksource_enqueue_watchdog() 911 .expect("clocksource_watchdog_kthread: failed to enqueue watchdog list"); 912 } 913 } 914 915 /// # watchdog线程的逻辑,执行unstable的后续操作 916 pub fn clocksource_watchdog_kthread() -> i32 { 917 // return 0; 918 loop { 919 // debug!("clocksource_watchdog_kthread start"); 920 __clocksource_watchdog_kthread(); 921 if KernelThreadMechanism::should_stop(&ProcessManager::current_pcb()) { 922 break; 923 } 924 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 925 ProcessManager::mark_sleep(true).expect("clocksource_watchdog_kthread:mark sleep failed"); 926 drop(irq_guard); 927 schedule(SchedMode::SM_NONE); 928 } 929 return 0; 930 } 931 932 /// # 清空所有时钟源的watchdog标志位 933 pub fn clocksource_reset_watchdog() { 934 let list_guard = WATCHDOG_LIST.lock_irqsave(); 935 for ele in list_guard.iter() { 936 ele.clocksource_data() 937 .flags 938 .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG); 939 } 940 } 941 942 /// # 重启检查器 943 pub fn clocksource_resume_watchdog() { 944 clocksource_reset_watchdog(); 945 } 946 947 /// # 根据精度选择最优的时钟源,或者接受用户指定的时间源 948 pub fn clocksource_select() { 949 let list_guard = CLOCKSOURCE_LIST.lock(); 950 if FINISHED_BOOTING.load(Ordering::Relaxed) || list_guard.is_empty() { 951 return; 952 } 953 let mut best = list_guard.front().unwrap().clone(); 954 let override_name = OVERRIDE_NAME.lock(); 955 // 判断是否有用户空间指定的时间源 956 for ele in list_guard.iter() { 957 if ele.clocksource_data().name.eq(override_name.deref()) { 958 // TODO 判断是否是高精度模式 959 // 暂时不支持高精度模式 960 // 如果是高精度模式,但是时钟源不支持高精度模式的话,就要退出循环 961 best = ele.clone(); 962 break; 963 } 964 } 965 // 对比当前的时钟源和记录到最好的时钟源的精度 966 if CUR_CLOCKSOURCE.lock().as_ref().is_some() { 967 // 当前时钟源不为空 968 let cur_clocksource = CUR_CLOCKSOURCE.lock().as_ref().unwrap().clone(); 969 let best_name = &best.clocksource_data().name; 970 if cur_clocksource.clocksource_data().name.ne(best_name) { 971 info!("Switching to the clocksource {:?}\n", best_name); 972 drop(cur_clocksource); 973 CUR_CLOCKSOURCE.lock().replace(best.clone()); 974 // TODO 通知timerkeeping 切换了时间源 975 } 976 } else { 977 // 当前时钟源为空 978 CUR_CLOCKSOURCE.lock().replace(best.clone()); 979 } 980 debug!("clocksource_select finish, CUR_CLOCKSOURCE = {best:?}"); 981 } 982 983 /// # clocksource模块加载完成 984 pub fn clocksource_boot_finish() { 985 let mut cur_clocksource = CUR_CLOCKSOURCE.lock(); 986 cur_clocksource.replace(clocksource_default_clock()); 987 FINISHED_BOOTING.store(true, Ordering::Relaxed); 988 // 清除不稳定的时钟源 989 __clocksource_watchdog_kthread(); 990 debug!("clocksource_boot_finish"); 991 } 992 993 fn run_watchdog_kthread() { 994 if let Some(watchdog_kthread) = unsafe { WATCHDOG_KTHREAD.clone() } { 995 ProcessManager::wakeup(&watchdog_kthread).ok(); 996 } 997 } 998 999 #[unified_init(INITCALL_LATE)] 1000 pub fn init_watchdog_kthread() -> Result<(), SystemError> { 1001 assert!(CurrentIrqArch::is_irq_enabled()); 1002 let closure = KernelThreadClosure::StaticEmptyClosure(( 1003 &(clocksource_watchdog_kthread as fn() -> i32), 1004 (), 1005 )); 1006 let pcb = KernelThreadMechanism::create_and_run(closure, "clocksource watchdog".to_string()) 1007 .ok_or(SystemError::EPERM)?; 1008 unsafe { 1009 WATCHDOG_KTHREAD.replace(pcb); 1010 } 1011 1012 return Ok(()); 1013 } 1014