123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850 |
- use core::{
- ffi::c_void,
- fmt::Debug,
- sync::atomic::{AtomicBool, Ordering},
- };
- use alloc::{boxed::Box, collections::LinkedList, string::String, sync::Arc, vec::Vec};
- use lazy_static::__Deref;
- use crate::{
- include::bindings::bindings::run_watchdog_kthread, kdebug, kinfo, libs::spinlock::SpinLock,
- syscall::SystemError,
- };
- use super::{
- jiffies::clocksource_default_clock,
- timer::{clock, Timer, TimerFunction},
- NSEC_PER_SEC,
- };
- lazy_static! {
- /// linked list with the registered clocksources
- pub static ref CLOCKSOURCE_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> =
- SpinLock::new(LinkedList::new());
- /// 被监视中的时钟源
- pub static ref WATCHDOG_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> =
- SpinLock::new(LinkedList::new());
- pub static ref CLOCKSOUCE_WATCHDOG:SpinLock<ClocksouceWatchdog> = SpinLock::new(ClocksouceWatchdog::new());
- pub static ref OVERRIDE_NAME: SpinLock<String> = SpinLock::new(String::from(""));
- }
- /// 正在被使用时钟源
- pub static CUR_CLOCKSOURCE: SpinLock<Option<Arc<dyn Clocksource>>> = SpinLock::new(None);
- /// 是否完成加载
- pub static mut FINISHED_BOOTING: AtomicBool = AtomicBool::new(false);
- /// Interval: 0.5sec Threshold: 0.0625s
- /// 系统节拍率
- pub const HZ: u64 = 1000;
- /// watchdog检查间隔
- pub const WATCHDOG_INTERVAL: u64 = HZ >> 1;
- /// 最大能接受的误差大小
- pub const WATCHDOG_THRESHOLD: u32 = NSEC_PER_SEC >> 4;
- // 时钟周期数
- #[derive(Debug, Clone, Copy)]
- #[repr(transparent)]
- pub struct CycleNum(pub u64);
- #[allow(dead_code)]
- impl CycleNum {
- #[inline(always)]
- pub fn new(cycle: u64) -> Self {
- Self(cycle)
- }
- #[inline(always)]
- pub fn data(&self) -> u64 {
- self.0
- }
- #[inline(always)]
- #[allow(dead_code)]
- pub fn add(&self, other: CycleNum) -> CycleNum {
- CycleNum(self.data() + other.data())
- }
- #[inline(always)]
- pub fn div(&self, other: CycleNum) -> CycleNum {
- CycleNum(self.data() - other.data())
- }
- }
- bitflags! {
- #[derive(Default)]
- pub struct ClocksourceMask: u64 {
- }
- /// 时钟状态标记
- #[derive(Default)]
- pub struct ClocksourceFlags: u64 {
- /// 表示时钟设备是连续的
- const CLOCK_SOURCE_IS_CONTINUOUS = 0x01;
- /// 表示该时钟源需要经过watchdog检查
- const CLOCK_SOURCE_MUST_VERIFY = 0x02;
- /// 表示该时钟源是watchdog
- const CLOCK_SOURCE_WATCHDOG = 0x10;
- /// 表示该时钟源是高分辨率的
- const CLOCK_SOURCE_VALID_FOR_HRES = 0x20;
- /// 表示该时钟源误差过大
- const CLOCK_SOURCE_UNSTABLE = 0x40;
- }
- }
- impl From<u64> for ClocksourceMask {
- fn from(value: u64) -> Self {
- if value < 64 {
- return Self::from_bits_truncate((1 << value) - 1);
- }
- return Self::from_bits_truncate(u64::MAX);
- }
- }
- impl ClocksourceMask {
- pub fn new(b: u64) -> Self {
- Self { bits: b }
- }
- }
- impl ClocksourceFlags {
- pub fn new(b: u64) -> Self {
- Self { bits: b }
- }
- }
- #[derive(Debug)]
- pub struct ClocksouceWatchdog {
- /// 监视器
- watchdog: Option<Arc<dyn Clocksource>>,
- /// 检查器是否在工作的标志
- is_running: bool,
- /// 上一次检查的时刻
- last_check: CycleNum,
- /// 定时监视器的过期时间
- timer_expires: u64,
- }
- impl ClocksouceWatchdog {
- pub fn new() -> Self {
- Self {
- watchdog: None,
- is_running: false,
- last_check: CycleNum(0),
- timer_expires: 0,
- }
- }
- /// 获取watchdog
- fn get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>> {
- &mut self.watchdog
- }
- /// 启用检查器
- pub fn clocksource_start_watchdog(&mut self) {
- // 如果watchdog未被设置或者已经启用了就退出
- let watchdog_list = &WATCHDOG_LIST.lock();
- if self.is_running || self.watchdog.is_none() || watchdog_list.is_empty() {
- return;
- }
- // 生成一个定时器
- let wd_timer_func: Box<WatchdogTimerFunc> = Box::new(WatchdogTimerFunc {});
- self.timer_expires += clock() + WATCHDOG_INTERVAL;
- self.last_check = self.watchdog.as_ref().unwrap().clone().read();
- let wd_timer = Timer::new(wd_timer_func, self.timer_expires);
- wd_timer.activate();
- self.is_running = true;
- }
- /// 停止检查器
- /// list_len WATCHDOG_LIST长度
- pub fn clocksource_stop_watchdog(&mut self, list_len: usize) {
- if !self.is_running || (self.watchdog.is_some() && list_len != 0) {
- return;
- }
- // TODO 当实现了周期性的定时器后 需要将监视用的定时器删除
- self.is_running = false;
- }
- }
- /// 定时检查器
- #[derive(Debug)]
- pub struct WatchdogTimerFunc;
- impl TimerFunction for WatchdogTimerFunc {
- fn run(&mut self) -> Result<(), SystemError> {
- return clocksource_watchdog();
- }
- }
- /// 时钟源的特性
- pub trait Clocksource: Send + Sync + Debug {
- // TODO 返回值类型可能需要改变
- /// returns a cycle value, passes clocksource as argument
- fn read(&self) -> CycleNum;
- /// optional function to enable the clocksource
- fn enable(&self) -> Result<i32, SystemError> {
- return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
- }
- /// optional function to disable the clocksource
- fn disable(&self) -> Result<(), SystemError> {
- return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
- }
- /// vsyscall based read
- fn vread(&self) -> Result<CycleNum, SystemError> {
- return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
- }
- /// suspend function for the clocksource, if necessary
- fn suspend(&self) -> Result<(), SystemError> {
- return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
- }
- /// resume function for the clocksource, if necessary
- fn resume(&self) -> Result<(), SystemError> {
- return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
- }
- // 获取时钟源数据
- fn clocksource_data(&self) -> ClocksourceData;
- fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> {
- return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
- }
- // 获取时钟源
- fn clocksource(&self) -> Arc<dyn Clocksource>;
- }
- /// # 实现整数log2的运算
- ///
- /// ## 参数
- ///
- /// * `x` - 要计算的数字
- ///
- /// ## 返回值
- ///
- /// * `u32` - 返回\log_2(x)的值
- fn log2(x: u32) -> u32 {
- let mut result = 0;
- let mut x = x;
- if x >= 1 << 16 {
- x >>= 16;
- result |= 16;
- }
- if x >= 1 << 8 {
- x >>= 8;
- result |= 8;
- }
- if x >= 1 << 4 {
- x >>= 4;
- result |= 4;
- }
- if x >= 1 << 2 {
- x >>= 2;
- result |= 2;
- }
- if x >= 1 << 1 {
- result |= 1;
- }
- result
- }
- impl dyn Clocksource {
- /// # 计算时钟源能记录的最大时间跨度
- pub fn clocksource_max_deferment(&self) -> u64 {
- let cs_data_guard = self.clocksource_data();
- let max_nsecs: u64;
- let mut max_cycles: u64;
- max_cycles = (1 << (63 - (log2(cs_data_guard.mult) + 1))) as u64;
- max_cycles = max_cycles.min(cs_data_guard.mask.bits);
- max_nsecs = clocksource_cyc2ns(
- CycleNum(max_cycles),
- cs_data_guard.mult,
- cs_data_guard.shift,
- );
- return max_nsecs - (max_nsecs >> 5);
- }
- /// # 注册时钟源
- ///
- /// ## 返回值
- ///
- /// * `Ok(0)` - 时钟源注册成功。
- /// * `Err(SystemError)` - 时钟源注册失败。
- pub fn register(&self) -> Result<i32, SystemError> {
- let ns = self.clocksource_max_deferment();
- let mut cs_data = self.clocksource_data();
- cs_data.max_idle_ns = ns as u32;
- self.update_clocksource_data(cs_data)?;
- // 将时钟源加入到时钟源队列中
- self.clocksource_enqueue();
- // 将时钟源加入到监视队列中
- self.clocksource_enqueue_watchdog()
- .expect("register: failed to enqueue watchdog list");
- // 选择一个最好的时钟源
- clocksource_select();
- kdebug!("clocksource_register successfully");
- return Ok(0);
- }
- /// # 将时钟源插入时钟源队列
- pub fn clocksource_enqueue(&self) {
- // 根据rating由大到小排序
- let cs_data = self.clocksource_data();
- let list_guard = &mut CLOCKSOURCE_LIST.lock();
- let mut spilt_pos: usize = 0;
- for (pos, ele) in list_guard.iter().enumerate() {
- if ele.clocksource_data().rating < cs_data.rating {
- spilt_pos = pos;
- break;
- }
- }
- let mut temp_list = list_guard.split_off(spilt_pos);
- let cs = self.clocksource();
- list_guard.push_back(cs);
- list_guard.append(&mut temp_list);
- // kdebug!(
- // "CLOCKSOURCE_LIST len = {:?},clocksource_enqueue sccessfully",
- // list_guard.len()
- // );
- }
- /// # 将时间源插入监控队列
- ///
- /// ## 返回值
- ///
- /// * `Ok(0)` - 时间源插入监控队列成功
- /// * `Err(SystemError)` - 时间源插入监控队列失败
- pub fn clocksource_enqueue_watchdog(&self) -> Result<i32, SystemError> {
- // BUG 可能需要lock irq
- let mut cs_data = self.clocksource_data();
- let cs = self.clocksource();
- if cs_data
- .flags
- .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
- {
- let mut list_guard = WATCHDOG_LIST.lock_irqsave();
- // cs是被监视的
- cs_data
- .flags
- .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
- cs.update_clocksource_data(cs_data)?;
- list_guard.push_back(cs);
- } else {
- // cs是监视器
- if cs_data
- .flags
- .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
- {
- // 如果时钟设备是连续的
- cs_data
- .flags
- .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES);
- cs.update_clocksource_data(cs_data.clone())?;
- }
- // 将时钟源加入到监控队列中
- let mut list_guard = WATCHDOG_LIST.lock();
- list_guard.push_back(cs.clone());
- drop(list_guard);
- // 对比当前注册的时间源的精度和监视器的精度
- let cs_watchdog = &mut CLOCKSOUCE_WATCHDOG.lock();
- if cs_watchdog.watchdog.is_none()
- || cs_data.rating
- > cs_watchdog
- .watchdog
- .clone()
- .unwrap()
- .clocksource_data()
- .rating
- {
- // 当前注册的时间源的精度更高或者没有监视器,替换监视器
- cs_watchdog.watchdog.replace(cs);
- clocksource_reset_watchdog();
- }
- // 启动监视器
- cs_watchdog.clocksource_start_watchdog();
- }
- return Ok(0);
- }
- /// # 将时钟源标记为unstable
- ///
- /// ## 参数
- /// * `delta` - 时钟源误差
- pub fn set_unstable(&self, delta: i64) -> Result<i32, SystemError> {
- let mut cs_data = self.clocksource_data();
- // 打印出unstable的时钟源信息
- kdebug!(
- "clocksource :{:?} is unstable, its delta is {:?}",
- cs_data.name,
- delta
- );
- cs_data.flags.remove(
- ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES | ClocksourceFlags::CLOCK_SOURCE_WATCHDOG,
- );
- cs_data
- .flags
- .insert(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE);
- self.update_clocksource_data(cs_data)?;
- // 启动watchdog线程 进行后续处理
- if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } {
- // TODO 在实现了工作队列后,将启动线程换成schedule work
- unsafe { run_watchdog_kthread() }
- }
- return Ok(0);
- }
- /// # 将时间源从监视链表中弹出
- fn clocksource_dequeue_watchdog(&self) {
- let data = self.clocksource_data();
- let mut locked_watchdog = CLOCKSOUCE_WATCHDOG.lock();
- let watchdog = locked_watchdog
- .get_watchdog()
- .clone()
- .unwrap()
- .clocksource_data();
- let mut list = WATCHDOG_LIST.lock();
- let mut size = list.len();
- let mut del_pos: usize = size;
- for (pos, ele) in list.iter().enumerate() {
- let ele_data = ele.clocksource_data();
- if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) {
- // 记录要删除的时钟源在监视链表中的下标
- del_pos = pos;
- }
- }
- if data
- .flags
- .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
- {
- // 如果时钟源是需要被检查的,直接删除时钟源
- if del_pos != size {
- let mut temp_list = list.split_off(del_pos);
- temp_list.pop_front();
- list.append(&mut temp_list);
- }
- } else if watchdog.name.eq(&data.name) && watchdog.rating.eq(&data.rating) {
- // 如果要删除的时钟源是监视器,则需要找到一个新的监视器
- // TODO 重新设置时钟源
- // 将链表解锁防止reset中双重加锁 并释放保存的旧的watchdog的数据
- // 代替了clocksource_reset_watchdog()的功能,将所有时钟源的watchdog标记清除
- for ele in list.iter() {
- ele.clocksource_data()
- .flags
- .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
- }
- // 遍历所有时间源,寻找新的监视器
- let mut clocksource_list = CLOCKSOURCE_LIST.lock();
- let mut replace_pos: usize = clocksource_list.len();
- for (pos, ele) in clocksource_list.iter().enumerate() {
- let ele_data = ele.clocksource_data();
- if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating)
- || ele_data
- .flags
- .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
- {
- // 当前时钟源是要被删除的时钟源或没被检查过的时钟源
- // 不适合成为监视器
- continue;
- }
- let watchdog = locked_watchdog.get_watchdog().clone();
- if watchdog.is_none()
- || ele_data.rating > watchdog.unwrap().clocksource_data().rating
- {
- // 如果watchdog不存在或者当前时钟源的精度高于watchdog的精度,则记录当前时钟源的下标
- replace_pos = pos;
- }
- }
- // 使用刚刚找到的更好的时钟源替换旧的watchdog
- if replace_pos < clocksource_list.len() {
- let mut temp_list = clocksource_list.split_off(replace_pos);
- let new_wd = temp_list.front().unwrap().clone();
- clocksource_list.append(&mut temp_list);
- // 替换watchdog
- locked_watchdog.watchdog.replace(new_wd);
- // drop(locked_watchdog);
- }
- // 删除时钟源
- if del_pos != size {
- let mut temp_list = list.split_off(del_pos);
- temp_list.pop_front();
- list.append(&mut temp_list);
- }
- }
- // 清除watchdog标记
- let mut cs_data = self.clocksource_data();
- cs_data
- .flags
- .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
- self.update_clocksource_data(cs_data)
- .expect("clocksource_dequeue_watchdog: failed to update clocksource data");
- size = list.len();
- // 停止当前的watchdog
- locked_watchdog.clocksource_stop_watchdog(size - 1);
- }
- /// # 将时钟源从时钟源链表中弹出
- fn clocksource_dequeue(&self) {
- let mut list = CLOCKSOURCE_LIST.lock();
- let data = self.clocksource_data();
- let mut del_pos: usize = list.len();
- for (pos, ele) in list.iter().enumerate() {
- let ele_data = ele.clocksource_data();
- if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) {
- // 记录时钟源在链表中的下标
- del_pos = pos;
- }
- }
- // 删除时钟源
- if del_pos != list.len() {
- let mut temp_list = list.split_off(del_pos);
- temp_list.pop_front();
- list.append(&mut temp_list);
- }
- }
- /// # 注销时钟源
- #[allow(dead_code)]
- pub fn unregister(&self) {
- // 将时钟源从监视链表中弹出
- self.clocksource_dequeue_watchdog();
- // 将时钟源从时钟源链表中弹出
- self.clocksource_dequeue();
- // 检查是否有更好的时钟源
- clocksource_select();
- }
- /// # 修改时钟源的精度
- ///
- /// ## 参数
- ///
- /// * `rating` - 指定的时钟精度
- fn clocksource_change_rating(&self, rating: i32) {
- // 将时钟源从链表中弹出
- self.clocksource_dequeue();
- let mut data = self.clocksource_data();
- // 修改时钟源的精度
- data.set_rating(rating);
- self.update_clocksource_data(data)
- .expect("clocksource_change_rating:updata clocksource failed");
- // 插入时钟源到时钟源链表中
- self.clocksource_enqueue();
- // 检查是否有更好的时钟源
- clocksource_select();
- }
- }
- #[derive(Debug, Clone)]
- pub struct ClocksourceData {
- /// 时钟源名字
- pub name: String,
- /// 时钟精度
- pub rating: i32,
- pub mask: ClocksourceMask,
- pub mult: u32,
- pub shift: u32,
- pub max_idle_ns: u32,
- pub flags: ClocksourceFlags,
- pub watchdog_last: CycleNum,
- }
- impl ClocksourceData {
- #[allow(dead_code)]
- pub fn new(
- name: String,
- rating: i32,
- mask: ClocksourceMask,
- mult: u32,
- shift: u32,
- max_idle_ns: u32,
- flags: ClocksourceFlags,
- ) -> Self {
- let csd = ClocksourceData {
- name,
- rating,
- mask,
- mult,
- shift,
- max_idle_ns,
- flags,
- watchdog_last: CycleNum(0),
- };
- return csd;
- }
- pub fn set_name(&mut self, name: String) {
- self.name = name;
- }
- pub fn set_rating(&mut self, rating: i32) {
- self.rating = rating;
- }
- pub fn set_mask(&mut self, mask: ClocksourceMask) {
- self.mask = mask;
- }
- pub fn set_mult(&mut self, mult: u32) {
- self.mult = mult;
- }
- pub fn set_shift(&mut self, shift: u32) {
- self.shift = shift;
- }
- pub fn set_max_idle_ns(&mut self, max_idle_ns: u32) {
- self.max_idle_ns = max_idle_ns;
- }
- pub fn set_flags(&mut self, flags: ClocksourceFlags) {
- self.flags = flags;
- }
- #[allow(dead_code)]
- pub fn remove_flags(&mut self, flags: ClocksourceFlags) {
- self.flags.remove(flags)
- }
- #[allow(dead_code)]
- pub fn insert_flags(&mut self, flags: ClocksourceFlags) {
- self.flags.insert(flags)
- }
- }
- /// converts clocksource cycles to nanoseconds
- ///
- pub fn clocksource_cyc2ns(cycles: CycleNum, mult: u32, shift: u32) -> u64 {
- return (cycles.data() * mult as u64) >> shift;
- }
- /// # 重启所有的时间源
- #[allow(dead_code)]
- pub fn clocksource_resume() {
- let list = CLOCKSOURCE_LIST.lock();
- for ele in list.iter() {
- let data = ele.clocksource_data();
- match ele.resume() {
- Ok(_) => continue,
- Err(_) => {
- kdebug!("clocksource {:?} resume failed", data.name);
- }
- }
- }
- clocksource_resume_watchdog();
- }
- /// # 暂停所有的时间源
- #[allow(dead_code)]
- pub fn clocksource_suspend() {
- let list = CLOCKSOURCE_LIST.lock();
- for ele in list.iter() {
- let data = ele.clocksource_data();
- match ele.suspend() {
- Ok(_) => continue,
- Err(_) => {
- kdebug!("clocksource {:?} suspend failed", data.name);
- }
- }
- }
- }
- /// # 根据watchdog的精度,来检查被监视的时钟源的误差
- ///
- /// ## 返回值
- ///
- /// * `Ok()` - 检查完成
- /// * `Err(SystemError)` - 错误码
- pub fn clocksource_watchdog() -> Result<(), SystemError> {
- let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock();
- // watchdog没有在运行的话直接退出
- if !cs_watchdog.is_running || cs_watchdog.watchdog.is_none() {
- return Ok(());
- }
- let cur_watchdog = cs_watchdog.watchdog.as_ref().unwrap().clone();
- let cur_wd_data = cur_watchdog.as_ref().clocksource_data();
- let cur_wd_nowclock = cur_watchdog.as_ref().read().data();
- let wd_last = cs_watchdog.last_check.data();
- let wd_dev_nsec = clocksource_cyc2ns(
- CycleNum((cur_wd_nowclock - wd_last) & cur_wd_data.mask.bits),
- cur_wd_data.mult,
- cur_wd_data.shift,
- );
- cs_watchdog.last_check = CycleNum(cur_wd_nowclock);
- drop(cs_watchdog);
- let watchdog_list = &mut WATCHDOG_LIST.lock();
- for cs in watchdog_list.iter() {
- let mut cs_data = cs.clocksource_data();
- // 判断时钟源是否已经被标记为不稳定
- if cs_data
- .flags
- .contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE)
- {
- // 启动watchdog_kthread
- unsafe { run_watchdog_kthread() };
- continue;
- }
- // 读取时钟源现在的时间
- let cs_now_clock = cs.read();
- // 如果时钟源没有被监视,则开始监视他
- if !cs_data
- .flags
- .contains(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG)
- {
- cs_data
- .flags
- .insert(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
- // 记录此次检查的时刻
- cs_data.watchdog_last = cs_now_clock;
- cs.update_clocksource_data(cs_data.clone())?;
- continue;
- }
- // 计算时钟源的误差
- let cs_dev_nsec = clocksource_cyc2ns(
- CycleNum(cs_now_clock.div(cs_data.watchdog_last).data() & cs_data.mask.bits),
- cs_data.mult,
- cs_data.shift,
- );
- // 记录此次检查的时刻
- cs_data.watchdog_last = cs_now_clock;
- cs.update_clocksource_data(cs_data.clone())?;
- if cs_dev_nsec.abs_diff(wd_dev_nsec) > WATCHDOG_THRESHOLD.into() {
- // 误差过大,标记为unstable
- cs.set_unstable((cs_dev_nsec - wd_dev_nsec).try_into().unwrap())?;
- continue;
- }
- // 判断是否要切换为高精度模式
- if !cs_data
- .flags
- .contains(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES)
- && cs_data
- .flags
- .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
- && cur_wd_data
- .flags
- .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
- {
- cs_data
- .flags
- .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES);
- cs.update_clocksource_data(cs_data)?;
- // TODO 通知tick机制 切换为高精度模式
- }
- let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock();
- // FIXME 需要保证所有cpu时间统一
- cs_watchdog.timer_expires += WATCHDOG_INTERVAL;
- //创建定时器执行watchdog
- let watchdog_func = Box::new(WatchdogTimerFunc {});
- let watchdog_timer = Timer::new(watchdog_func, cs_watchdog.timer_expires);
- watchdog_timer.activate();
- }
- return Ok(());
- }
- /// # watchdog线程的逻辑,执行unstable的后续操作
- pub fn clocksource_watchdog_kthread() {
- let mut del_vec: Vec<usize> = Vec::new();
- let mut del_clocks: Vec<Arc<dyn Clocksource>> = Vec::new();
- let wd_list = &mut WATCHDOG_LIST.lock();
- // 将不稳定的时钟源弹出监视链表
- for (pos, ele) in wd_list.iter().enumerate() {
- let data = ele.clocksource_data();
- if data.flags.contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) {
- del_vec.push(pos);
- del_clocks.push(ele.clone());
- }
- }
- for pos in del_vec {
- let mut temp_list = wd_list.split_off(pos);
- temp_list.pop_front();
- wd_list.append(&mut temp_list);
- }
- // 检查是否需要停止watchdog
- CLOCKSOUCE_WATCHDOG
- .lock()
- .clocksource_stop_watchdog(wd_list.len());
- // 将不稳定的时钟源精度都设置为最低
- for clock in del_clocks.iter() {
- clock.clocksource_change_rating(0);
- }
- }
- /// # 清空所有时钟源的watchdog标志位
- pub fn clocksource_reset_watchdog() {
- let list_guard = WATCHDOG_LIST.lock();
- for ele in list_guard.iter() {
- ele.clocksource_data()
- .flags
- .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
- }
- }
- /// # 重启检查器
- pub fn clocksource_resume_watchdog() {
- clocksource_reset_watchdog();
- }
- /// # 根据精度选择最优的时钟源,或者接受用户指定的时间源
- pub fn clocksource_select() {
- let list_guard = CLOCKSOURCE_LIST.lock();
- if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } || list_guard.is_empty() {
- return;
- }
- let mut best = list_guard.front().unwrap().clone();
- let override_name = OVERRIDE_NAME.lock();
- // 判断是否有用户空间指定的时间源
- for ele in list_guard.iter() {
- if ele.clocksource_data().name.eq(override_name.deref()) {
- // TODO 判断是否是高精度模式
- // 暂时不支持高精度模式
- // 如果是高精度模式,但是时钟源不支持高精度模式的话,就要退出循环
- best = ele.clone();
- break;
- }
- }
- // 对比当前的时钟源和记录到最好的时钟源的精度
- if CUR_CLOCKSOURCE.lock().as_ref().is_some() {
- // 当前时钟源不为空
- let cur_clocksource = CUR_CLOCKSOURCE.lock().as_ref().unwrap().clone();
- let best_name = &best.clocksource_data().name;
- if cur_clocksource.clocksource_data().name.ne(best_name) {
- kinfo!("Switching to the clocksource {:?}\n", best_name);
- drop(cur_clocksource);
- CUR_CLOCKSOURCE.lock().replace(best);
- // TODO 通知timerkeeping 切换了时间源
- }
- } else {
- // 当前时钟源为空
- CUR_CLOCKSOURCE.lock().replace(best);
- }
- kdebug!(" clocksource_select finish");
- }
- /// # clocksource模块加载完成
- pub fn clocksource_boot_finish() {
- let mut cur_clocksource = CUR_CLOCKSOURCE.lock();
- cur_clocksource.replace(clocksource_default_clock());
- unsafe { FINISHED_BOOTING.store(true, Ordering::Relaxed) };
- // 清除不稳定的时钟源
- clocksource_watchdog_kthread();
- kdebug!("clocksource_boot_finish");
- }
- // ======== 以下为对C的接口 ========
- /// # 完成对clocksource模块的加载
- #[no_mangle]
- pub extern "C" fn rs_clocksource_boot_finish() {
- clocksource_boot_finish();
- }
- /// # 启动watchdog线程的辅助函数
- #[no_mangle]
- pub extern "C" fn rs_clocksource_watchdog_kthread(_data: c_void) -> i32 {
- clocksource_watchdog_kthread();
- return 0;
- }
|