clocksource.rs 27 KB

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