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)]
new(cycle: u64) -> Self78 pub const fn new(cycle: u64) -> Self {
79 Self(cycle)
80 }
81 #[inline(always)]
data(&self) -> u6482 pub const fn data(&self) -> u64 {
83 self.0
84 }
85 #[inline(always)]
86 #[allow(dead_code)]
add(&self, other: CycleNum) -> CycleNum87 pub fn add(&self, other: CycleNum) -> CycleNum {
88 CycleNum(self.data() + other.data())
89 }
90 #[inline(always)]
div(&self, other: CycleNum) -> CycleNum91 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 {
from(value: u64) -> Self117 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 {
new(b: u64) -> Self125 pub fn new(b: u64) -> Self {
126 Self { bits: b }
127 }
128 }
129 impl ClocksourceFlags {
new(b: u64) -> Self130 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 {
new() -> Self145 pub fn new() -> Self {
146 Self {
147 watchdog: None,
148 is_running: false,
149 timer_expires: 0,
150 }
151 }
152
153 /// 获取watchdog
get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>>154 fn get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>> {
155 &mut self.watchdog
156 }
157
158 /// 启用检查器
clocksource_start_watchdog(&mut self)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长度
clocksource_stop_watchdog(&mut self, list_len: usize)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 {
run(&mut self) -> Result<(), SystemError>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
read(&self) -> CycleNum204 fn read(&self) -> CycleNum;
205 /// optional function to enable the clocksource
enable(&self) -> Result<i32, SystemError>206 fn enable(&self) -> Result<i32, SystemError> {
207 return Err(SystemError::ENOSYS);
208 }
209 /// optional function to disable the clocksource
210 #[allow(dead_code)]
disable(&self) -> Result<(), SystemError>211 fn disable(&self) -> Result<(), SystemError> {
212 return Err(SystemError::ENOSYS);
213 }
214 /// vsyscall based read
215 #[allow(dead_code)]
vread(&self) -> Result<CycleNum, SystemError>216 fn vread(&self) -> Result<CycleNum, SystemError> {
217 return Err(SystemError::ENOSYS);
218 }
219 /// suspend function for the clocksource, if necessary
suspend(&self) -> Result<(), SystemError>220 fn suspend(&self) -> Result<(), SystemError> {
221 return Err(SystemError::ENOSYS);
222 }
223 /// resume function for the clocksource, if necessary
resume(&self) -> Result<(), SystemError>224 fn resume(&self) -> Result<(), SystemError> {
225 return Err(SystemError::ENOSYS);
226 }
227 // 获取时钟源数据
clocksource_data(&self) -> ClocksourceData228 fn clocksource_data(&self) -> ClocksourceData;
229
update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError>230 fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> {
231 return Err(SystemError::ENOSYS);
232 }
233 // 获取时钟源
clocksource(&self) -> Arc<dyn Clocksource>234 fn clocksource(&self) -> Arc<dyn Clocksource>;
235 }
236
237 /// # 实现整数log2的运算
238 ///
239 /// ## 参数
240 ///
241 /// * `x` - 要计算的数字
242 ///
243 /// ## 返回值
244 ///
245 /// * `u32` - 返回\log_2(x)的值
log2(x: u32) -> u32246 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 /// # 计算时钟源能记录的最大时间跨度
clocksource_max_deferment(&self) -> u64275 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,以便将一个时钟源的频率转换为另一个时钟源的频率
clocks_calc_mult_shift(&self, from: u32, to: u32, maxsec: u32) -> (u32, u32)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 /// # 计算时钟源可以进行的最大调整量
clocksource_max_adjustment(&self) -> u32316 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
clocksource_update_freq_scale(&self, scale: u32, freq: u32) -> Result<(), SystemError>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)` - 时钟源注册失败。
register(&self, scale: u32, freq: u32) -> Result<(), 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 /// # 将时钟源插入时钟源队列
clocksource_enqueue(&self)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)` - 时间源插入监控队列失败
clocksource_enqueue_watchdog(&self) -> Result<i32, 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` - 时钟源误差
set_unstable(&self, delta: i64) -> Result<i32, SystemError>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 /// # 将时间源从监视链表中弹出
clocksource_dequeue_watchdog(&self)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 /// # 将时钟源从时钟源链表中弹出
clocksource_dequeue(&self)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)]
unregister(&self)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` - 指定的时钟精度
clocksource_change_rating(&self, rating: i32)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)]
new( name: String, rating: i32, mask: ClocksourceMask, mult: u32, shift: u32, max_idle_ns: u32, flags: ClocksourceFlags, uncertainty_margin: u32, maxadj: u32, ) -> Self688 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
set_name(&mut self, name: String)716 pub fn set_name(&mut self, name: String) {
717 self.name = name;
718 }
set_rating(&mut self, rating: i32)719 pub fn set_rating(&mut self, rating: i32) {
720 self.rating = rating;
721 }
set_mask(&mut self, mask: ClocksourceMask)722 pub fn set_mask(&mut self, mask: ClocksourceMask) {
723 self.mask = mask;
724 }
set_mult(&mut self, mult: u32)725 pub fn set_mult(&mut self, mult: u32) {
726 self.mult = mult;
727 }
set_shift(&mut self, shift: u32)728 pub fn set_shift(&mut self, shift: u32) {
729 self.shift = shift;
730 }
set_max_idle_ns(&mut self, max_idle_ns: u32)731 pub fn set_max_idle_ns(&mut self, max_idle_ns: u32) {
732 self.max_idle_ns = max_idle_ns;
733 }
set_flags(&mut self, flags: ClocksourceFlags)734 pub fn set_flags(&mut self, flags: ClocksourceFlags) {
735 self.flags = flags;
736 }
737 #[allow(dead_code)]
remove_flags(&mut self, flags: ClocksourceFlags)738 pub fn remove_flags(&mut self, flags: ClocksourceFlags) {
739 self.flags.remove(flags)
740 }
741 #[allow(dead_code)]
insert_flags(&mut self, flags: ClocksourceFlags)742 pub fn insert_flags(&mut self, flags: ClocksourceFlags) {
743 self.flags.insert(flags)
744 }
set_uncertainty_margin(&mut self, uncertainty_margin: u32)745 pub fn set_uncertainty_margin(&mut self, uncertainty_margin: u32) {
746 self.uncertainty_margin = uncertainty_margin;
747 }
set_maxadj(&mut self, maxadj: u32)748 pub fn set_maxadj(&mut self, maxadj: u32) {
749 self.maxadj = maxadj;
750 }
751 }
752
753 /// converts clocksource cycles to nanoseconds
754 ///
clocksource_cyc2ns(cycles: CycleNum, mult: u32, shift: u32) -> u64755 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)]
clocksource_resume()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)]
clocksource_suspend()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)` - 错误码
clocksource_watchdog() -> Result<(), 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
create_new_watchdog_timer_function()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
__clocksource_watchdog_kthread()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的后续操作
clocksource_watchdog_kthread() -> i32947 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标志位
clocksource_reset_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 /// # 重启检查器
clocksource_resume_watchdog()974 pub fn clocksource_resume_watchdog() {
975 clocksource_reset_watchdog();
976 }
977
978 /// # 根据精度选择最优的时钟源,或者接受用户指定的时间源
clocksource_select()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模块加载完成
clocksource_boot_finish()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
run_watchdog_kthread()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)]
init_watchdog_kthread() -> Result<(), SystemError>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