softirq.rs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. use core::{
  2. fmt::Debug,
  3. intrinsics::unlikely,
  4. mem::{self, MaybeUninit},
  5. ptr::null_mut,
  6. sync::atomic::{compiler_fence, fence, AtomicI16, Ordering},
  7. };
  8. use alloc::{boxed::Box, sync::Arc, vec::Vec};
  9. use log::{debug, info};
  10. use num_traits::FromPrimitive;
  11. use system_error::SystemError;
  12. use crate::{
  13. arch::CurrentIrqArch,
  14. exception::InterruptArch,
  15. libs::rwlock::RwLock,
  16. mm::percpu::{PerCpu, PerCpuVar},
  17. process::ProcessManager,
  18. sched::cputime::IrqTime,
  19. smp::{core::smp_get_processor_id, cpu::ProcessorId},
  20. time::timer::clock,
  21. };
  22. const MAX_SOFTIRQ_NUM: u64 = 64;
  23. const MAX_SOFTIRQ_RESTART: i32 = 20;
  24. static mut __CPU_PENDING: Option<Box<[VecStatus; PerCpu::MAX_CPU_NUM as usize]>> = None;
  25. static mut __SORTIRQ_VECTORS: *mut Softirq = null_mut();
  26. #[no_mangle]
  27. pub extern "C" fn rs_softirq_init() {
  28. softirq_init().expect("softirq_init failed");
  29. }
  30. #[inline(never)]
  31. pub fn softirq_init() -> Result<(), SystemError> {
  32. info!("Initializing softirq...");
  33. unsafe {
  34. __SORTIRQ_VECTORS = Box::leak(Box::new(Softirq::new()));
  35. __CPU_PENDING = Some(Box::new(
  36. [VecStatus::default(); PerCpu::MAX_CPU_NUM as usize],
  37. ));
  38. let cpu_pending = __CPU_PENDING.as_mut().unwrap();
  39. for i in 0..PerCpu::MAX_CPU_NUM {
  40. cpu_pending[i as usize] = VecStatus::default();
  41. }
  42. }
  43. info!("Softirq initialized.");
  44. return Ok(());
  45. }
  46. #[inline(always)]
  47. pub fn softirq_vectors() -> &'static mut Softirq {
  48. unsafe {
  49. return __SORTIRQ_VECTORS.as_mut().unwrap();
  50. }
  51. }
  52. #[inline(always)]
  53. fn cpu_pending(cpu_id: ProcessorId) -> &'static mut VecStatus {
  54. unsafe {
  55. return &mut __CPU_PENDING.as_mut().unwrap()[cpu_id.data() as usize];
  56. }
  57. }
  58. /// 软中断向量号码
  59. #[allow(dead_code)]
  60. #[repr(u8)]
  61. #[derive(FromPrimitive, Copy, Clone, Debug, PartialEq, Eq)]
  62. pub enum SoftirqNumber {
  63. /// 时钟软中断信号
  64. TIMER = 0,
  65. VideoRefresh = 1, //帧缓冲区刷新软中断
  66. }
  67. impl From<u64> for SoftirqNumber {
  68. fn from(value: u64) -> Self {
  69. return <Self as FromPrimitive>::from_u64(value).unwrap();
  70. }
  71. }
  72. bitflags! {
  73. #[derive(Default)]
  74. pub struct VecStatus: u64 {
  75. const TIMER = 1 << 0;
  76. const VIDEO_REFRESH = 1 << 1;
  77. }
  78. }
  79. impl From<SoftirqNumber> for VecStatus {
  80. fn from(value: SoftirqNumber) -> Self {
  81. return Self::from_bits_truncate(1 << (value as u64));
  82. }
  83. }
  84. pub trait SoftirqVec: Send + Sync + Debug {
  85. fn run(&self);
  86. }
  87. #[derive(Debug)]
  88. pub struct Softirq {
  89. table: RwLock<[Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize]>,
  90. /// 软中断嵌套层数(per cpu)
  91. cpu_running_count: PerCpuVar<AtomicI16>,
  92. }
  93. impl Softirq {
  94. /// 每个CPU最大嵌套的软中断数量
  95. const MAX_RUNNING_PER_CPU: i16 = 3;
  96. fn new() -> Softirq {
  97. let mut data: [MaybeUninit<Option<Arc<dyn SoftirqVec>>>; MAX_SOFTIRQ_NUM as usize] =
  98. unsafe { MaybeUninit::uninit().assume_init() };
  99. for i in 0..MAX_SOFTIRQ_NUM {
  100. data[i as usize] = MaybeUninit::new(None);
  101. }
  102. let data: [Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize] = unsafe {
  103. mem::transmute::<_, [Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize]>(data)
  104. };
  105. let mut percpu_count = Vec::with_capacity(PerCpu::MAX_CPU_NUM as usize);
  106. percpu_count.resize_with(PerCpu::MAX_CPU_NUM as usize, || AtomicI16::new(0));
  107. let cpu_running_count = PerCpuVar::new(percpu_count).unwrap();
  108. return Softirq {
  109. table: RwLock::new(data),
  110. cpu_running_count,
  111. };
  112. }
  113. fn cpu_running_count(&self) -> &PerCpuVar<AtomicI16> {
  114. return &self.cpu_running_count;
  115. }
  116. /// @brief 注册软中断向量
  117. ///
  118. /// @param softirq_num 中断向量号
  119. ///
  120. /// @param hanlder 中断函数对应的结构体
  121. pub fn register_softirq(
  122. &self,
  123. softirq_num: SoftirqNumber,
  124. handler: Arc<dyn SoftirqVec>,
  125. ) -> Result<i32, SystemError> {
  126. // debug!("register_softirq softirq_num = {:?}", softirq_num as u64);
  127. // let self = &mut SOFTIRQ_VECTORS.lock();
  128. // 判断该软中断向量是否已经被注册
  129. let mut table_guard = self.table.write_irqsave();
  130. if table_guard[softirq_num as usize].is_some() {
  131. // debug!("register_softirq failed");
  132. return Err(SystemError::EINVAL);
  133. }
  134. table_guard[softirq_num as usize] = Some(handler);
  135. drop(table_guard);
  136. // debug!(
  137. // "register_softirq successfully, softirq_num = {:?}",
  138. // softirq_num as u64
  139. // );
  140. compiler_fence(Ordering::SeqCst);
  141. return Ok(0);
  142. }
  143. /// @brief 解注册软中断向量
  144. ///
  145. /// @param irq_num 中断向量号码
  146. #[allow(dead_code)]
  147. pub fn unregister_softirq(&self, softirq_num: SoftirqNumber) {
  148. // debug!("unregister_softirq softirq_num = {:?}", softirq_num as u64);
  149. let mut table_guard = self.table.write_irqsave();
  150. // 将软中断向量清空
  151. table_guard[softirq_num as usize] = None;
  152. drop(table_guard);
  153. // 将对应位置的pending和runing都置0
  154. // self.running.lock().set(VecStatus::from(softirq_num), false);
  155. // 将对应CPU的pending置0
  156. compiler_fence(Ordering::SeqCst);
  157. cpu_pending(smp_get_processor_id()).set(VecStatus::from(softirq_num), false);
  158. compiler_fence(Ordering::SeqCst);
  159. }
  160. #[inline(never)]
  161. pub fn do_softirq(&self) {
  162. if self.cpu_running_count().get().load(Ordering::SeqCst) >= Self::MAX_RUNNING_PER_CPU {
  163. // 当前CPU的软中断嵌套层数已经达到最大值,不再执行
  164. return;
  165. }
  166. // 创建一个RunningCountGuard,当退出作用域时,会自动将cpu_running_count减1
  167. let _count_guard = RunningCountGuard::new(self.cpu_running_count());
  168. // TODO pcb的flags未修改
  169. let end = clock() + 500 * 2;
  170. let cpu_id = smp_get_processor_id();
  171. let mut max_restart = MAX_SOFTIRQ_RESTART;
  172. loop {
  173. compiler_fence(Ordering::SeqCst);
  174. let pending = cpu_pending(cpu_id).bits;
  175. cpu_pending(cpu_id).bits = 0;
  176. compiler_fence(Ordering::SeqCst);
  177. unsafe { CurrentIrqArch::interrupt_enable() };
  178. if pending != 0 {
  179. for i in 0..MAX_SOFTIRQ_NUM {
  180. if pending & (1 << i) == 0 {
  181. continue;
  182. }
  183. let table_guard = self.table.read_irqsave();
  184. let softirq_func = table_guard[i as usize].clone();
  185. drop(table_guard);
  186. if softirq_func.is_none() {
  187. continue;
  188. }
  189. let prev_count: usize = ProcessManager::current_pcb().preempt_count();
  190. softirq_func.as_ref().unwrap().run();
  191. if unlikely(prev_count != ProcessManager::current_pcb().preempt_count()) {
  192. debug!(
  193. "entered softirq {:?} with preempt_count {:?},exited with {:?}",
  194. i,
  195. prev_count,
  196. ProcessManager::current_pcb().preempt_count()
  197. );
  198. unsafe { ProcessManager::current_pcb().set_preempt_count(prev_count) };
  199. }
  200. }
  201. }
  202. unsafe { CurrentIrqArch::interrupt_disable() };
  203. max_restart -= 1;
  204. compiler_fence(Ordering::SeqCst);
  205. if cpu_pending(cpu_id).is_empty() {
  206. compiler_fence(Ordering::SeqCst);
  207. if clock() < end && max_restart > 0 {
  208. continue;
  209. } else {
  210. break;
  211. }
  212. } else {
  213. // TODO:当有softirqd时 唤醒它
  214. break;
  215. }
  216. }
  217. }
  218. pub fn raise_softirq(&self, softirq_num: SoftirqNumber) {
  219. let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  220. let processor_id = smp_get_processor_id();
  221. cpu_pending(processor_id).insert(VecStatus::from(softirq_num));
  222. compiler_fence(Ordering::SeqCst);
  223. drop(guard);
  224. // debug!("raise_softirq exited");
  225. }
  226. #[allow(dead_code)]
  227. pub unsafe fn clear_softirq_pending(&self, softirq_num: SoftirqNumber) {
  228. compiler_fence(Ordering::SeqCst);
  229. cpu_pending(smp_get_processor_id()).remove(VecStatus::from(softirq_num));
  230. compiler_fence(Ordering::SeqCst);
  231. }
  232. }
  233. /// 当前CPU的软中断嵌套层数的计数器守卫
  234. ///
  235. /// 当进入作用域时,会自动将cpu_running_count加1,
  236. /// 当退出作用域时,会自动将cpu_running_count减1
  237. struct RunningCountGuard<'a> {
  238. cpu_running_count: &'a PerCpuVar<AtomicI16>,
  239. }
  240. impl<'a> RunningCountGuard<'a> {
  241. fn new(cpu_running_count: &'a PerCpuVar<AtomicI16>) -> RunningCountGuard {
  242. cpu_running_count.get().fetch_add(1, Ordering::SeqCst);
  243. return RunningCountGuard { cpu_running_count };
  244. }
  245. }
  246. impl<'a> Drop for RunningCountGuard<'a> {
  247. fn drop(&mut self) {
  248. self.cpu_running_count.get().fetch_sub(1, Ordering::SeqCst);
  249. }
  250. }
  251. #[inline(never)]
  252. pub fn do_softirq() {
  253. fence(Ordering::SeqCst);
  254. IrqTime::irqtime_start();
  255. softirq_vectors().do_softirq();
  256. IrqTime::irqtime_account_irq(ProcessManager::current_pcb());
  257. fence(Ordering::SeqCst);
  258. }