xref: /DragonOS/kernel/src/time/clocksource.rs (revision a30434f5201ca4c60b9515c8c23444fea3b5a8c6)
1 use core::{
2     ffi::c_void,
3     fmt::Debug,
4     sync::atomic::{AtomicBool, Ordering},
5 };
6 
7 use alloc::{boxed::Box, collections::LinkedList, string::String, sync::Arc, vec::Vec};
8 use lazy_static::__Deref;
9 
10 use crate::{
11     include::bindings::bindings::run_watchdog_kthread, kdebug, kinfo, libs::spinlock::SpinLock,
12     syscall::SystemError,
13 };
14 
15 use super::{
16     jiffies::clocksource_default_clock,
17     timer::{clock, Timer, TimerFunction},
18     NSEC_PER_SEC,
19 };
20 
21 lazy_static! {
22     /// linked list with the registered clocksources
23     pub static ref CLOCKSOURCE_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> =
24         SpinLock::new(LinkedList::new());
25     /// 被监视中的时钟源
26     pub static ref WATCHDOG_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> =
27         SpinLock::new(LinkedList::new());
28 
29     pub static ref CLOCKSOUCE_WATCHDOG:SpinLock<ClocksouceWatchdog>  = SpinLock::new(ClocksouceWatchdog::new());
30 
31     pub static ref OVERRIDE_NAME: SpinLock<String> = SpinLock::new(String::from(""));
32 
33 
34 }
35 
36 /// 正在被使用时钟源
37 pub static CUR_CLOCKSOURCE: SpinLock<Option<Arc<dyn Clocksource>>> = SpinLock::new(None);
38 /// 是否完成加载
39 pub static mut FINISHED_BOOTING: AtomicBool = AtomicBool::new(false);
40 
41 /// Interval: 0.5sec Threshold: 0.0625s
42 /// 系统节拍率
43 pub const HZ: u64 = 1000;
44 /// watchdog检查间隔
45 pub const WATCHDOG_INTERVAL: u64 = HZ >> 1;
46 /// 最大能接受的误差大小
47 pub const WATCHDOG_THRESHOLD: u32 = NSEC_PER_SEC >> 4;
48 
49 // 时钟周期数
50 #[derive(Debug, Clone, Copy)]
51 #[repr(transparent)]
52 pub struct CycleNum(pub u64);
53 
54 #[allow(dead_code)]
55 impl CycleNum {
56     #[inline(always)]
57     pub fn new(cycle: u64) -> Self {
58         Self(cycle)
59     }
60     #[inline(always)]
61     pub fn data(&self) -> u64 {
62         self.0
63     }
64     #[inline(always)]
65     #[allow(dead_code)]
66     pub fn add(&self, other: CycleNum) -> CycleNum {
67         CycleNum(self.data() + other.data())
68     }
69     #[inline(always)]
70     pub fn div(&self, other: CycleNum) -> CycleNum {
71         CycleNum(self.data() - other.data())
72     }
73 }
74 
75 bitflags! {
76 
77     #[derive(Default)]
78     pub struct ClocksourceMask: u64 {
79     }
80     /// 时钟状态标记
81     #[derive(Default)]
82     pub struct ClocksourceFlags: u64 {
83         /// 表示时钟设备是连续的
84         const CLOCK_SOURCE_IS_CONTINUOUS = 0x01;
85         /// 表示该时钟源需要经过watchdog检查
86         const CLOCK_SOURCE_MUST_VERIFY = 0x02;
87         /// 表示该时钟源是watchdog
88         const CLOCK_SOURCE_WATCHDOG = 0x10;
89         /// 表示该时钟源是高分辨率的
90         const CLOCK_SOURCE_VALID_FOR_HRES = 0x20;
91         /// 表示该时钟源误差过大
92         const CLOCK_SOURCE_UNSTABLE = 0x40;
93     }
94 }
95 impl From<u64> for ClocksourceMask {
96     fn from(value: u64) -> Self {
97         if value < 64 {
98             return Self::from_bits_truncate((1 << value) - 1);
99         }
100         return Self::from_bits_truncate(u64::MAX);
101     }
102 }
103 impl ClocksourceMask {
104     pub fn new(b: u64) -> Self {
105         Self { bits: b }
106     }
107 }
108 impl ClocksourceFlags {
109     pub fn new(b: u64) -> Self {
110         Self { bits: b }
111     }
112 }
113 
114 #[derive(Debug)]
115 pub struct ClocksouceWatchdog {
116     /// 监视器
117     watchdog: Option<Arc<dyn Clocksource>>,
118     /// 检查器是否在工作的标志
119     is_running: bool,
120     /// 上一次检查的时刻
121     last_check: CycleNum,
122     /// 定时监视器的过期时间
123     timer_expires: u64,
124 }
125 impl ClocksouceWatchdog {
126     pub fn new() -> Self {
127         Self {
128             watchdog: None,
129             is_running: false,
130             last_check: CycleNum(0),
131             timer_expires: 0,
132         }
133     }
134 
135     /// 获取watchdog
136     fn get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>> {
137         &mut self.watchdog
138     }
139 
140     /// 启用检查器
141     pub fn clocksource_start_watchdog(&mut self) {
142         // 如果watchdog未被设置或者已经启用了就退出
143         let watchdog_list = &WATCHDOG_LIST.lock();
144         if self.is_running || self.watchdog.is_none() || watchdog_list.is_empty() {
145             return;
146         }
147         // 生成一个定时器
148         let wd_timer_func: Box<WatchdogTimerFunc> = Box::new(WatchdogTimerFunc {});
149         self.timer_expires += clock() + WATCHDOG_INTERVAL;
150         self.last_check = self.watchdog.as_ref().unwrap().clone().read();
151         let wd_timer = Timer::new(wd_timer_func, self.timer_expires);
152         wd_timer.activate();
153         self.is_running = true;
154     }
155 
156     /// 停止检查器
157     /// list_len WATCHDOG_LIST长度
158     pub fn clocksource_stop_watchdog(&mut self, list_len: usize) {
159         if !self.is_running || (self.watchdog.is_some() && list_len != 0) {
160             return;
161         }
162         // TODO 当实现了周期性的定时器后 需要将监视用的定时器删除
163         self.is_running = false;
164     }
165 }
166 
167 /// 定时检查器
168 #[derive(Debug)]
169 pub struct WatchdogTimerFunc;
170 impl TimerFunction for WatchdogTimerFunc {
171     fn run(&mut self) -> Result<(), SystemError> {
172         return clocksource_watchdog();
173     }
174 }
175 
176 /// 时钟源的特性
177 pub trait Clocksource: Send + Sync + Debug {
178     // TODO 返回值类型可能需要改变
179     /// returns a cycle value, passes clocksource as argument
180     fn read(&self) -> CycleNum;
181     /// optional function to enable the clocksource
182     fn enable(&self) -> Result<i32, SystemError> {
183         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
184     }
185     /// optional function to disable the clocksource
186     fn disable(&self) -> Result<(), SystemError> {
187         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
188     }
189     /// vsyscall based read
190     fn vread(&self) -> Result<CycleNum, SystemError> {
191         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
192     }
193     /// suspend function for the clocksource, if necessary
194     fn suspend(&self) -> Result<(), SystemError> {
195         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
196     }
197     /// resume function for the clocksource, if necessary
198     fn resume(&self) -> Result<(), SystemError> {
199         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
200     }
201     // 获取时钟源数据
202     fn clocksource_data(&self) -> ClocksourceData;
203 
204     fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> {
205         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
206     }
207     // 获取时钟源
208     fn clocksource(&self) -> Arc<dyn Clocksource>;
209 }
210 
211 /// # 实现整数log2的运算
212 ///
213 /// ## 参数
214 ///
215 /// * `x` - 要计算的数字
216 ///
217 /// ## 返回值
218 ///
219 /// * `u32` - 返回\log_2(x)的值
220 fn log2(x: u32) -> u32 {
221     let mut result = 0;
222     let mut x = x;
223 
224     if x >= 1 << 16 {
225         x >>= 16;
226         result |= 16;
227     }
228     if x >= 1 << 8 {
229         x >>= 8;
230         result |= 8;
231     }
232     if x >= 1 << 4 {
233         x >>= 4;
234         result |= 4;
235     }
236     if x >= 1 << 2 {
237         x >>= 2;
238         result |= 2;
239     }
240     if x >= 1 << 1 {
241         result |= 1;
242     }
243 
244     result
245 }
246 
247 impl dyn Clocksource {
248     /// # 计算时钟源能记录的最大时间跨度
249     pub fn clocksource_max_deferment(&self) -> u64 {
250         let cs_data_guard = self.clocksource_data();
251         let max_nsecs: u64;
252         let mut max_cycles: u64;
253         max_cycles = (1 << (63 - (log2(cs_data_guard.mult) + 1))) as u64;
254         max_cycles = max_cycles.min(cs_data_guard.mask.bits);
255         max_nsecs = clocksource_cyc2ns(
256             CycleNum(max_cycles),
257             cs_data_guard.mult,
258             cs_data_guard.shift,
259         );
260         return max_nsecs - (max_nsecs >> 5);
261     }
262 
263     /// # 注册时钟源
264     ///
265     /// ## 返回值
266     ///
267     /// * `Ok(0)` - 时钟源注册成功。
268     /// * `Err(SystemError)` - 时钟源注册失败。
269     pub fn register(&self) -> Result<i32, SystemError> {
270         let ns = self.clocksource_max_deferment();
271         let mut cs_data = self.clocksource_data();
272         cs_data.max_idle_ns = ns as u32;
273         self.update_clocksource_data(cs_data)?;
274         // 将时钟源加入到时钟源队列中
275         self.clocksource_enqueue();
276         // 将时钟源加入到监视队列中
277         self.clocksource_enqueue_watchdog()
278             .expect("register: failed to enqueue watchdog list");
279         // 选择一个最好的时钟源
280         clocksource_select();
281         kdebug!("clocksource_register successfully");
282         return Ok(0);
283     }
284 
285     /// # 将时钟源插入时钟源队列
286     pub fn clocksource_enqueue(&self) {
287         // 根据rating由大到小排序
288         let cs_data = self.clocksource_data();
289         let list_guard = &mut CLOCKSOURCE_LIST.lock();
290         let mut spilt_pos: usize = 0;
291         for (pos, ele) in list_guard.iter().enumerate() {
292             if ele.clocksource_data().rating < cs_data.rating {
293                 spilt_pos = pos;
294                 break;
295             }
296         }
297         let mut temp_list = list_guard.split_off(spilt_pos);
298         let cs = self.clocksource();
299         list_guard.push_back(cs);
300         list_guard.append(&mut temp_list);
301         // kdebug!(
302         //     "CLOCKSOURCE_LIST len = {:?},clocksource_enqueue sccessfully",
303         //     list_guard.len()
304         // );
305     }
306 
307     /// # 将时间源插入监控队列
308     ///
309     /// ## 返回值
310     ///
311     /// * `Ok(0)` - 时间源插入监控队列成功
312     /// * `Err(SystemError)` - 时间源插入监控队列失败
313     pub fn clocksource_enqueue_watchdog(&self) -> Result<i32, SystemError> {
314         // BUG 可能需要lock irq
315         let mut cs_data = self.clocksource_data();
316 
317         let cs = self.clocksource();
318         if cs_data
319             .flags
320             .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
321         {
322             let mut list_guard = WATCHDOG_LIST.lock_irqsave();
323             // cs是被监视的
324             cs_data
325                 .flags
326                 .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
327             cs.update_clocksource_data(cs_data)?;
328             list_guard.push_back(cs);
329         } else {
330             // cs是监视器
331             if cs_data
332                 .flags
333                 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
334             {
335                 // 如果时钟设备是连续的
336                 cs_data
337                     .flags
338                     .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES);
339                 cs.update_clocksource_data(cs_data.clone())?;
340             }
341 
342             // 将时钟源加入到监控队列中
343             let mut list_guard = WATCHDOG_LIST.lock();
344             list_guard.push_back(cs.clone());
345             drop(list_guard);
346 
347             // 对比当前注册的时间源的精度和监视器的精度
348             let cs_watchdog = &mut CLOCKSOUCE_WATCHDOG.lock();
349             if cs_watchdog.watchdog.is_none()
350                 || cs_data.rating
351                     > cs_watchdog
352                         .watchdog
353                         .clone()
354                         .unwrap()
355                         .clocksource_data()
356                         .rating
357             {
358                 // 当前注册的时间源的精度更高或者没有监视器,替换监视器
359                 cs_watchdog.watchdog.replace(cs);
360                 clocksource_reset_watchdog();
361             }
362 
363             // 启动监视器
364             cs_watchdog.clocksource_start_watchdog();
365         }
366         return Ok(0);
367     }
368 
369     /// # 将时钟源标记为unstable
370     ///
371     /// ## 参数
372     /// * `delta` - 时钟源误差
373     pub fn set_unstable(&self, delta: i64) -> Result<i32, SystemError> {
374         let mut cs_data = self.clocksource_data();
375         // 打印出unstable的时钟源信息
376         kdebug!(
377             "clocksource :{:?} is unstable, its delta is {:?}",
378             cs_data.name,
379             delta
380         );
381         cs_data.flags.remove(
382             ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES | ClocksourceFlags::CLOCK_SOURCE_WATCHDOG,
383         );
384         cs_data
385             .flags
386             .insert(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE);
387         self.update_clocksource_data(cs_data)?;
388 
389         // 启动watchdog线程 进行后续处理
390         if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } {
391             // TODO 在实现了工作队列后,将启动线程换成schedule work
392             unsafe { run_watchdog_kthread() }
393         }
394         return Ok(0);
395     }
396 
397     /// # 将时间源从监视链表中弹出
398     fn clocksource_dequeue_watchdog(&self) {
399         let data = self.clocksource_data();
400         let mut locked_watchdog = CLOCKSOUCE_WATCHDOG.lock();
401         let watchdog = locked_watchdog
402             .get_watchdog()
403             .clone()
404             .unwrap()
405             .clocksource_data();
406 
407         let mut list = WATCHDOG_LIST.lock();
408         let mut size = list.len();
409 
410         let mut del_pos: usize = size;
411         for (pos, ele) in list.iter().enumerate() {
412             let ele_data = ele.clocksource_data();
413             if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) {
414                 // 记录要删除的时钟源在监视链表中的下标
415                 del_pos = pos;
416             }
417         }
418 
419         if data
420             .flags
421             .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
422         {
423             // 如果时钟源是需要被检查的,直接删除时钟源
424             if del_pos != size {
425                 let mut temp_list = list.split_off(del_pos);
426                 temp_list.pop_front();
427                 list.append(&mut temp_list);
428             }
429         } else if watchdog.name.eq(&data.name) && watchdog.rating.eq(&data.rating) {
430             // 如果要删除的时钟源是监视器,则需要找到一个新的监视器
431             // TODO 重新设置时钟源
432             // 将链表解锁防止reset中双重加锁 并释放保存的旧的watchdog的数据
433 
434             // 代替了clocksource_reset_watchdog()的功能,将所有时钟源的watchdog标记清除
435             for ele in list.iter() {
436                 ele.clocksource_data()
437                     .flags
438                     .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
439             }
440 
441             // 遍历所有时间源,寻找新的监视器
442             let mut clocksource_list = CLOCKSOURCE_LIST.lock();
443             let mut replace_pos: usize = clocksource_list.len();
444             for (pos, ele) in clocksource_list.iter().enumerate() {
445                 let ele_data = ele.clocksource_data();
446 
447                 if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating)
448                     || ele_data
449                         .flags
450                         .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
451                 {
452                     // 当前时钟源是要被删除的时钟源或没被检查过的时钟源
453                     // 不适合成为监视器
454                     continue;
455                 }
456                 let watchdog = locked_watchdog.get_watchdog().clone();
457                 if watchdog.is_none()
458                     || ele_data.rating > watchdog.unwrap().clocksource_data().rating
459                 {
460                     // 如果watchdog不存在或者当前时钟源的精度高于watchdog的精度,则记录当前时钟源的下标
461                     replace_pos = pos;
462                 }
463             }
464             // 使用刚刚找到的更好的时钟源替换旧的watchdog
465             if replace_pos < clocksource_list.len() {
466                 let mut temp_list = clocksource_list.split_off(replace_pos);
467                 let new_wd = temp_list.front().unwrap().clone();
468                 clocksource_list.append(&mut temp_list);
469                 // 替换watchdog
470                 locked_watchdog.watchdog.replace(new_wd);
471                 // drop(locked_watchdog);
472             }
473             // 删除时钟源
474             if del_pos != size {
475                 let mut temp_list = list.split_off(del_pos);
476                 temp_list.pop_front();
477                 list.append(&mut temp_list);
478             }
479         }
480 
481         // 清除watchdog标记
482         let mut cs_data = self.clocksource_data();
483         cs_data
484             .flags
485             .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
486         self.update_clocksource_data(cs_data)
487             .expect("clocksource_dequeue_watchdog: failed to update clocksource data");
488         size = list.len();
489         // 停止当前的watchdog
490         locked_watchdog.clocksource_stop_watchdog(size - 1);
491     }
492 
493     /// # 将时钟源从时钟源链表中弹出
494     fn clocksource_dequeue(&self) {
495         let mut list = CLOCKSOURCE_LIST.lock();
496         let data = self.clocksource_data();
497         let mut del_pos: usize = list.len();
498         for (pos, ele) in list.iter().enumerate() {
499             let ele_data = ele.clocksource_data();
500             if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) {
501                 // 记录时钟源在链表中的下标
502                 del_pos = pos;
503             }
504         }
505 
506         // 删除时钟源
507         if del_pos != list.len() {
508             let mut temp_list = list.split_off(del_pos);
509             temp_list.pop_front();
510             list.append(&mut temp_list);
511         }
512     }
513 
514     /// # 注销时钟源
515     #[allow(dead_code)]
516     pub fn unregister(&self) {
517         // 将时钟源从监视链表中弹出
518         self.clocksource_dequeue_watchdog();
519         // 将时钟源从时钟源链表中弹出
520         self.clocksource_dequeue();
521         // 检查是否有更好的时钟源
522         clocksource_select();
523     }
524     /// # 修改时钟源的精度
525     ///
526     /// ## 参数
527     ///
528     /// * `rating` - 指定的时钟精度
529     fn clocksource_change_rating(&self, rating: i32) {
530         // 将时钟源从链表中弹出
531         self.clocksource_dequeue();
532         let mut data = self.clocksource_data();
533         // 修改时钟源的精度
534         data.set_rating(rating);
535         self.update_clocksource_data(data)
536             .expect("clocksource_change_rating:updata clocksource failed");
537         // 插入时钟源到时钟源链表中
538         self.clocksource_enqueue();
539         // 检查是否有更好的时钟源
540         clocksource_select();
541     }
542 }
543 
544 #[derive(Debug, Clone)]
545 pub struct ClocksourceData {
546     /// 时钟源名字
547     pub name: String,
548     /// 时钟精度
549     pub rating: i32,
550     pub mask: ClocksourceMask,
551     pub mult: u32,
552     pub shift: u32,
553     pub max_idle_ns: u32,
554     pub flags: ClocksourceFlags,
555     pub watchdog_last: CycleNum,
556 }
557 
558 impl ClocksourceData {
559     #[allow(dead_code)]
560     pub fn new(
561         name: String,
562         rating: i32,
563         mask: ClocksourceMask,
564         mult: u32,
565         shift: u32,
566         max_idle_ns: u32,
567         flags: ClocksourceFlags,
568     ) -> Self {
569         let csd = ClocksourceData {
570             name,
571             rating,
572             mask,
573             mult,
574             shift,
575             max_idle_ns,
576             flags,
577             watchdog_last: CycleNum(0),
578         };
579         return csd;
580     }
581 
582     pub fn set_name(&mut self, name: String) {
583         self.name = name;
584     }
585     pub fn set_rating(&mut self, rating: i32) {
586         self.rating = rating;
587     }
588     pub fn set_mask(&mut self, mask: ClocksourceMask) {
589         self.mask = mask;
590     }
591     pub fn set_mult(&mut self, mult: u32) {
592         self.mult = mult;
593     }
594     pub fn set_shift(&mut self, shift: u32) {
595         self.shift = shift;
596     }
597     pub fn set_max_idle_ns(&mut self, max_idle_ns: u32) {
598         self.max_idle_ns = max_idle_ns;
599     }
600     pub fn set_flags(&mut self, flags: ClocksourceFlags) {
601         self.flags = flags;
602     }
603     #[allow(dead_code)]
604     pub fn remove_flags(&mut self, flags: ClocksourceFlags) {
605         self.flags.remove(flags)
606     }
607     #[allow(dead_code)]
608     pub fn insert_flags(&mut self, flags: ClocksourceFlags) {
609         self.flags.insert(flags)
610     }
611 }
612 
613 ///  converts clocksource cycles to nanoseconds
614 ///
615 pub fn clocksource_cyc2ns(cycles: CycleNum, mult: u32, shift: u32) -> u64 {
616     return (cycles.data() * mult as u64) >> shift;
617 }
618 
619 /// # 重启所有的时间源
620 #[allow(dead_code)]
621 pub fn clocksource_resume() {
622     let list = CLOCKSOURCE_LIST.lock();
623     for ele in list.iter() {
624         let data = ele.clocksource_data();
625         match ele.resume() {
626             Ok(_) => continue,
627             Err(_) => {
628                 kdebug!("clocksource {:?} resume failed", data.name);
629             }
630         }
631     }
632     clocksource_resume_watchdog();
633 }
634 
635 /// # 暂停所有的时间源
636 #[allow(dead_code)]
637 pub fn clocksource_suspend() {
638     let list = CLOCKSOURCE_LIST.lock();
639     for ele in list.iter() {
640         let data = ele.clocksource_data();
641         match ele.suspend() {
642             Ok(_) => continue,
643             Err(_) => {
644                 kdebug!("clocksource {:?} suspend failed", data.name);
645             }
646         }
647     }
648 }
649 
650 /// # 根据watchdog的精度,来检查被监视的时钟源的误差
651 ///
652 /// ## 返回值
653 ///
654 /// * `Ok()` - 检查完成
655 /// * `Err(SystemError)` - 错误码
656 pub fn clocksource_watchdog() -> Result<(), SystemError> {
657     let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock();
658 
659     // watchdog没有在运行的话直接退出
660     if !cs_watchdog.is_running || cs_watchdog.watchdog.is_none() {
661         return Ok(());
662     }
663     let cur_watchdog = cs_watchdog.watchdog.as_ref().unwrap().clone();
664     let cur_wd_data = cur_watchdog.as_ref().clocksource_data();
665     let cur_wd_nowclock = cur_watchdog.as_ref().read().data();
666 
667     let wd_last = cs_watchdog.last_check.data();
668     let wd_dev_nsec = clocksource_cyc2ns(
669         CycleNum((cur_wd_nowclock - wd_last) & cur_wd_data.mask.bits),
670         cur_wd_data.mult,
671         cur_wd_data.shift,
672     );
673     cs_watchdog.last_check = CycleNum(cur_wd_nowclock);
674     drop(cs_watchdog);
675     let watchdog_list = &mut WATCHDOG_LIST.lock();
676     for cs in watchdog_list.iter() {
677         let mut cs_data = cs.clocksource_data();
678         // 判断时钟源是否已经被标记为不稳定
679         if cs_data
680             .flags
681             .contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE)
682         {
683             // 启动watchdog_kthread
684             unsafe { run_watchdog_kthread() };
685             continue;
686         }
687         // 读取时钟源现在的时间
688         let cs_now_clock = cs.read();
689 
690         // 如果时钟源没有被监视,则开始监视他
691         if !cs_data
692             .flags
693             .contains(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG)
694         {
695             cs_data
696                 .flags
697                 .insert(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
698             // 记录此次检查的时刻
699             cs_data.watchdog_last = cs_now_clock;
700             cs.update_clocksource_data(cs_data.clone())?;
701             continue;
702         }
703 
704         // 计算时钟源的误差
705         let cs_dev_nsec = clocksource_cyc2ns(
706             CycleNum(cs_now_clock.div(cs_data.watchdog_last).data() & cs_data.mask.bits),
707             cs_data.mult,
708             cs_data.shift,
709         );
710         // 记录此次检查的时刻
711         cs_data.watchdog_last = cs_now_clock;
712         cs.update_clocksource_data(cs_data.clone())?;
713         if cs_dev_nsec.abs_diff(wd_dev_nsec) > WATCHDOG_THRESHOLD.into() {
714             // 误差过大,标记为unstable
715             cs.set_unstable((cs_dev_nsec - wd_dev_nsec).try_into().unwrap())?;
716             continue;
717         }
718 
719         // 判断是否要切换为高精度模式
720         if !cs_data
721             .flags
722             .contains(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES)
723             && cs_data
724                 .flags
725                 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
726             && cur_wd_data
727                 .flags
728                 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
729         {
730             cs_data
731                 .flags
732                 .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES);
733             cs.update_clocksource_data(cs_data)?;
734             // TODO 通知tick机制 切换为高精度模式
735         }
736         let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock();
737         // FIXME 需要保证所有cpu时间统一
738         cs_watchdog.timer_expires += WATCHDOG_INTERVAL;
739         //创建定时器执行watchdog
740         let watchdog_func = Box::new(WatchdogTimerFunc {});
741         let watchdog_timer = Timer::new(watchdog_func, cs_watchdog.timer_expires);
742         watchdog_timer.activate();
743     }
744     return Ok(());
745 }
746 
747 /// # watchdog线程的逻辑,执行unstable的后续操作
748 pub fn clocksource_watchdog_kthread() {
749     let mut del_vec: Vec<usize> = Vec::new();
750     let mut del_clocks: Vec<Arc<dyn Clocksource>> = Vec::new();
751     let wd_list = &mut WATCHDOG_LIST.lock();
752 
753     // 将不稳定的时钟源弹出监视链表
754     for (pos, ele) in wd_list.iter().enumerate() {
755         let data = ele.clocksource_data();
756         if data.flags.contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) {
757             del_vec.push(pos);
758             del_clocks.push(ele.clone());
759         }
760     }
761     for pos in del_vec {
762         let mut temp_list = wd_list.split_off(pos);
763         temp_list.pop_front();
764         wd_list.append(&mut temp_list);
765     }
766 
767     // 检查是否需要停止watchdog
768     CLOCKSOUCE_WATCHDOG
769         .lock()
770         .clocksource_stop_watchdog(wd_list.len());
771     // 将不稳定的时钟源精度都设置为最低
772     for clock in del_clocks.iter() {
773         clock.clocksource_change_rating(0);
774     }
775 }
776 
777 /// # 清空所有时钟源的watchdog标志位
778 pub fn clocksource_reset_watchdog() {
779     let list_guard = WATCHDOG_LIST.lock();
780     for ele in list_guard.iter() {
781         ele.clocksource_data()
782             .flags
783             .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
784     }
785 }
786 
787 /// # 重启检查器
788 pub fn clocksource_resume_watchdog() {
789     clocksource_reset_watchdog();
790 }
791 
792 /// # 根据精度选择最优的时钟源,或者接受用户指定的时间源
793 pub fn clocksource_select() {
794     let list_guard = CLOCKSOURCE_LIST.lock();
795     if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } || list_guard.is_empty() {
796         return;
797     }
798     let mut best = list_guard.front().unwrap().clone();
799     let override_name = OVERRIDE_NAME.lock();
800     // 判断是否有用户空间指定的时间源
801     for ele in list_guard.iter() {
802         if ele.clocksource_data().name.eq(override_name.deref()) {
803             // TODO 判断是否是高精度模式
804             // 暂时不支持高精度模式
805             // 如果是高精度模式,但是时钟源不支持高精度模式的话,就要退出循环
806             best = ele.clone();
807             break;
808         }
809     }
810     // 对比当前的时钟源和记录到最好的时钟源的精度
811     if CUR_CLOCKSOURCE.lock().as_ref().is_some() {
812         // 当前时钟源不为空
813         let cur_clocksource = CUR_CLOCKSOURCE.lock().as_ref().unwrap().clone();
814         let best_name = &best.clocksource_data().name;
815         if cur_clocksource.clocksource_data().name.ne(best_name) {
816             kinfo!("Switching to the clocksource {:?}\n", best_name);
817             drop(cur_clocksource);
818             CUR_CLOCKSOURCE.lock().replace(best);
819             // TODO 通知timerkeeping 切换了时间源
820         }
821     } else {
822         // 当前时钟源为空
823         CUR_CLOCKSOURCE.lock().replace(best);
824     }
825     kdebug!(" clocksource_select finish");
826 }
827 
828 /// # clocksource模块加载完成
829 pub fn clocksource_boot_finish() {
830     let mut cur_clocksource = CUR_CLOCKSOURCE.lock();
831     cur_clocksource.replace(clocksource_default_clock());
832     unsafe { FINISHED_BOOTING.store(true, Ordering::Relaxed) };
833     // 清除不稳定的时钟源
834     clocksource_watchdog_kthread();
835     kdebug!("clocksource_boot_finish");
836 }
837 
838 // ======== 以下为对C的接口 ========
839 /// # 完成对clocksource模块的加载
840 #[no_mangle]
841 pub extern "C" fn rs_clocksource_boot_finish() {
842     clocksource_boot_finish();
843 }
844 
845 /// # 启动watchdog线程的辅助函数
846 #[no_mangle]
847 pub extern "C" fn rs_clocksource_watchdog_kthread(_data: c_void) -> i32 {
848     clocksource_watchdog_kthread();
849     return 0;
850 }
851