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 use system_error::SystemError;
10
11 use crate::{
12 include::bindings::bindings::run_watchdog_kthread, kdebug, kinfo, libs::spinlock::SpinLock,
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 = 250;
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)]
new(cycle: u64) -> Self57 pub fn new(cycle: u64) -> Self {
58 Self(cycle)
59 }
60 #[inline(always)]
data(&self) -> u6461 pub fn data(&self) -> u64 {
62 self.0
63 }
64 #[inline(always)]
65 #[allow(dead_code)]
add(&self, other: CycleNum) -> CycleNum66 pub fn add(&self, other: CycleNum) -> CycleNum {
67 CycleNum(self.data() + other.data())
68 }
69 #[inline(always)]
div(&self, other: CycleNum) -> CycleNum70 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 {
from(value: u64) -> Self96 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 {
new(b: u64) -> Self104 pub fn new(b: u64) -> Self {
105 Self { bits: b }
106 }
107 }
108 impl ClocksourceFlags {
new(b: u64) -> Self109 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 {
new() -> Self126 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
get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>>136 fn get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>> {
137 &mut self.watchdog
138 }
139
140 /// 启用检查器
clocksource_start_watchdog(&mut self)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长度
clocksource_stop_watchdog(&mut self, list_len: usize)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 {
run(&mut self) -> Result<(), SystemError>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
read(&self) -> CycleNum180 fn read(&self) -> CycleNum;
181 /// optional function to enable the clocksource
enable(&self) -> Result<i32, SystemError>182 fn enable(&self) -> Result<i32, SystemError> {
183 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
184 }
185 /// optional function to disable the clocksource
disable(&self) -> Result<(), SystemError>186 fn disable(&self) -> Result<(), SystemError> {
187 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
188 }
189 /// vsyscall based read
vread(&self) -> Result<CycleNum, SystemError>190 fn vread(&self) -> Result<CycleNum, SystemError> {
191 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
192 }
193 /// suspend function for the clocksource, if necessary
suspend(&self) -> Result<(), SystemError>194 fn suspend(&self) -> Result<(), SystemError> {
195 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
196 }
197 /// resume function for the clocksource, if necessary
resume(&self) -> Result<(), SystemError>198 fn resume(&self) -> Result<(), SystemError> {
199 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
200 }
201 // 获取时钟源数据
clocksource_data(&self) -> ClocksourceData202 fn clocksource_data(&self) -> ClocksourceData;
203
update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError>204 fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> {
205 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
206 }
207 // 获取时钟源
clocksource(&self) -> Arc<dyn Clocksource>208 fn clocksource(&self) -> Arc<dyn Clocksource>;
209 }
210
211 /// # 实现整数log2的运算
212 ///
213 /// ## 参数
214 ///
215 /// * `x` - 要计算的数字
216 ///
217 /// ## 返回值
218 ///
219 /// * `u32` - 返回\log_2(x)的值
log2(x: u32) -> u32220 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 /// # 计算时钟源能记录的最大时间跨度
clocksource_max_deferment(&self) -> u64249 pub fn clocksource_max_deferment(&self) -> u64 {
250 let cs_data_guard = self.clocksource_data();
251
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 let 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)` - 时钟源注册失败。
register(&self) -> Result<i32, 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 /// # 将时钟源插入时钟源队列
clocksource_enqueue(&self)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)` - 时间源插入监控队列失败
clocksource_enqueue_watchdog(&self) -> Result<i32, 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` - 时钟源误差
set_unstable(&self, delta: i64) -> Result<i32, SystemError>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 /// # 将时间源从监视链表中弹出
clocksource_dequeue_watchdog(&self)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 /// # 将时钟源从时钟源链表中弹出
clocksource_dequeue(&self)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)]
unregister(&self)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` - 指定的时钟精度
clocksource_change_rating(&self, rating: i32)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)]
new( name: String, rating: i32, mask: ClocksourceMask, mult: u32, shift: u32, max_idle_ns: u32, flags: ClocksourceFlags, ) -> Self560 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
set_name(&mut self, name: String)582 pub fn set_name(&mut self, name: String) {
583 self.name = name;
584 }
set_rating(&mut self, rating: i32)585 pub fn set_rating(&mut self, rating: i32) {
586 self.rating = rating;
587 }
set_mask(&mut self, mask: ClocksourceMask)588 pub fn set_mask(&mut self, mask: ClocksourceMask) {
589 self.mask = mask;
590 }
set_mult(&mut self, mult: u32)591 pub fn set_mult(&mut self, mult: u32) {
592 self.mult = mult;
593 }
set_shift(&mut self, shift: u32)594 pub fn set_shift(&mut self, shift: u32) {
595 self.shift = shift;
596 }
set_max_idle_ns(&mut self, max_idle_ns: u32)597 pub fn set_max_idle_ns(&mut self, max_idle_ns: u32) {
598 self.max_idle_ns = max_idle_ns;
599 }
set_flags(&mut self, flags: ClocksourceFlags)600 pub fn set_flags(&mut self, flags: ClocksourceFlags) {
601 self.flags = flags;
602 }
603 #[allow(dead_code)]
remove_flags(&mut self, flags: ClocksourceFlags)604 pub fn remove_flags(&mut self, flags: ClocksourceFlags) {
605 self.flags.remove(flags)
606 }
607 #[allow(dead_code)]
insert_flags(&mut self, flags: ClocksourceFlags)608 pub fn insert_flags(&mut self, flags: ClocksourceFlags) {
609 self.flags.insert(flags)
610 }
611 }
612
613 /// converts clocksource cycles to nanoseconds
614 ///
clocksource_cyc2ns(cycles: CycleNum, mult: u32, shift: u32) -> u64615 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)]
clocksource_resume()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)]
clocksource_suspend()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)` - 错误码
clocksource_watchdog() -> Result<(), 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的后续操作
clocksource_watchdog_kthread()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标志位
clocksource_reset_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 /// # 重启检查器
clocksource_resume_watchdog()788 pub fn clocksource_resume_watchdog() {
789 clocksource_reset_watchdog();
790 }
791
792 /// # 根据精度选择最优的时钟源,或者接受用户指定的时间源
clocksource_select()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模块加载完成
clocksource_boot_finish()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
840 /// # 启动watchdog线程的辅助函数
841 #[no_mangle]
rs_clocksource_watchdog_kthread(_data: c_void) -> i32842 pub extern "C" fn rs_clocksource_watchdog_kthread(_data: c_void) -> i32 {
843 clocksource_watchdog_kthread();
844 return 0;
845 }
846