完成中断管理模块重构 (#554)

- 支持中断共享
- 把现有驱动程序移植到新的irq模块
- 使用`ProcessorId`标识处理器id
- 尚未实现threaded_irq

性能上,edge irq flow handler里面,对于锁的使用,可能有点问题。为了获取/修改common data还有其他几个结构体的状态,进行了多次加锁和放锁,导致性能降低。这是接下来需要优化的点。
This commit is contained in:
LoGin
2024-03-03 16:31:08 +08:00
committed by GitHub
parent 44d051e586
commit e28411791f
108 changed files with 4504 additions and 2203 deletions

View File

@ -1,13 +1,13 @@
use super::{core::smp_get_processor_id, kick_cpu};
use super::{core::smp_get_processor_id, cpu::ProcessorId, kick_cpu};
#[no_mangle]
pub extern "C" fn rs_kick_cpu(cpu_id: u32) -> usize {
return kick_cpu(cpu_id)
return kick_cpu(ProcessorId::new(cpu_id))
.map(|_| 0usize)
.unwrap_or_else(|e| e.to_posix_errno() as usize);
}
#[no_mangle]
pub extern "C" fn rs_current_cpu_id() -> i32 {
return smp_get_processor_id() as i32;
return smp_get_processor_id().data() as i32;
}

View File

@ -1,5 +1,7 @@
use super::cpu::ProcessorId;
/// @brief 获取当前的cpu id
#[inline]
pub fn smp_get_processor_id() -> u32 {
pub fn smp_get_processor_id() -> ProcessorId {
return crate::arch::cpu::current_cpu_id();
}

View File

@ -1 +1,9 @@
use core::sync::atomic::AtomicU32;
mod c_adapter;
int_like!(ProcessorId, AtomicProcessorId, u32, AtomicU32);
impl ProcessorId {
pub const INVALID: ProcessorId = ProcessorId::new(u32::MAX);
}

View File

@ -1,30 +0,0 @@
#pragma once
#include <arch/arch.h>
#if ARCH(I386) || ARCH(X86_64)
#include <arch/x86_64/include/x86_64_ipi.h>
/**
* @brief ipi中断处理注册函数
*
* @param irq_num 中断向量号
* @param arg 参数
* @param handler 处理函数
* @param param 参数
* @param controller 当前为NULL
* @param irq_name ipi中断名
* @return int 成功0
*/
extern int ipi_regiserIPI(uint64_t irq_num, void *arg,
void (*handler)(uint64_t irq_num, uint64_t param, struct pt_regs *regs),
uint64_t param, hardware_intr_controller *controller, char *irq_name);
#else
int ipi_regiserIPI(uint64_t irq_num, void *arg,
void (*handler)(uint64_t irq_num, uint64_t param, struct pt_regs *regs),
uint64_t param, hardware_intr_controller *controller, char *irq_name)
{
return -1;
}
#endif

View File

@ -5,14 +5,16 @@ use crate::{
exception::ipi::{IpiKind, IpiTarget},
};
use self::cpu::ProcessorId;
pub mod c_adapter;
pub mod core;
pub mod cpu;
pub fn kick_cpu(cpu_id: u32) -> Result<(), SystemError> {
pub fn kick_cpu(cpu_id: ProcessorId) -> Result<(), SystemError> {
// todo: 增加对cpu_id的有效性检查
send_ipi(IpiKind::KickCpu, IpiTarget::Specified(cpu_id as usize));
send_ipi(IpiKind::KickCpu, IpiTarget::Specified(cpu_id));
return Ok(());
}

View File

@ -4,13 +4,10 @@
#include <common/spinlock.h>
#include <mm/slab.h>
#include <process/process.h>
#include <arch/x86_64/driver/apic/apic_timer.h>
#include <process/preempt.h>
#include <sched/sched.h>
#include <driver/acpi/acpi.h>
#include "exception/irq.h"
#include "ipi.h"
#include <arch/arch.h>
/* x86-64 specific MSRs */
@ -19,9 +16,6 @@
#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */
#define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */
static void __smp_kick_cpu_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs);
static void __smp__flush_tlb_ipi_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs);
static spinlock_t multi_core_starting_lock = {1}; // 多核启动锁
static uint32_t total_processor_num = 0;
@ -68,7 +62,6 @@ void smp_init()
(unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
io_mfence();
memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM);
io_mfence();
@ -76,10 +69,7 @@ void smp_init()
rs_ipi_send_smp_init();
kdebug("total_processor_num=%d", total_processor_num);
// 注册接收kick_cpu功能的处理函数。向量号200
ipi_regiserIPI(KICK_CPU_IRQ_NUM, NULL, &__smp_kick_cpu_handler, (uint64_t)NULL, NULL, "IPI kick cpu");
ipi_regiserIPI(FLUSH_TLB_IRQ_NUM, NULL, &__smp__flush_tlb_ipi_handler, NULL, NULL, "IPI flush tlb");
int core_to_start = 0;
// total_processor_num = 3;
for (int i = 0; i < total_processor_num; ++i) // i从1开始不初始化bsp
@ -161,7 +151,7 @@ void smp_ap_start_stage2()
rs_init_syscall_64();
apic_timer_ap_core_init();
rs_init_current_core_sched();
#endif
sti();
@ -181,27 +171,6 @@ void smp_ap_start_stage2()
hlt();
}
/**
* @brief kick_cpu 核心间通信的处理函数
*
* @param irq_num
* @param param
* @param regs
*/
static void __smp_kick_cpu_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs)
{
if (user_mode(regs))
return;
sched();
}
static void __smp__flush_tlb_ipi_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs)
{
if (user_mode(regs))
return;
flush_tlb();
}
/**
* @brief 获取当前全部的cpu数目
*