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