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