diff --git a/src/arch/x86_64/kernel/apic.rs b/src/arch/x86_64/kernel/apic.rs index 89f8594cd57248fccf4f894a6fccb9fceae82942..8853d5dcf6747de0c35f74e9ee2ad363eaf4647b 100644 --- a/src/arch/x86_64/kernel/apic.rs +++ b/src/arch/x86_64/kernel/apic.rs @@ -634,6 +634,11 @@ pub fn init_local_apic() { ); } +pub(crate) fn assign_irq_to_core(irq: u8, core_id: CoreId) { + info!("Assign interrupt {} to core {}", irq, core_id); + ioapic_inton(irq, core_id.try_into().unwrap()).unwrap(); +} + fn calibrate_timer() { // The APIC Timer is used to provide a one-shot interrupt for the tickless timer // implemented through processor::get_timer_ticks. diff --git a/src/drivers/net/mod.rs b/src/drivers/net/mod.rs index 673e0b500ee458df60d42eea491d9e0e767ed13e..cb455bcfa4511b10e7e0b4dddf9af538317d512e 100644 --- a/src/drivers/net/mod.rs +++ b/src/drivers/net/mod.rs @@ -40,6 +40,8 @@ pub trait NetworkInterface { fn set_polling_mode(&mut self, value: bool); /// Handle interrupt and check if a packet is available fn handle_interrupt(&mut self) -> bool; + /// handle interrupt on the same core, where the current task is running + fn assign_task_to_nic(&self); } #[cfg(all(not(feature = "newlib"), target_arch = "x86_64"))] diff --git a/src/drivers/net/rtl8139.rs b/src/drivers/net/rtl8139.rs index 0f52fc58fec8615342aa18d0606742389ec71dc7..87de243ba786ba4fd3ced7286c71105c3a3ba8d6 100644 --- a/src/drivers/net/rtl8139.rs +++ b/src/drivers/net/rtl8139.rs @@ -8,10 +8,11 @@ use core::mem; use crate::arch::kernel::irq::*; use crate::arch::kernel::pci; -use crate::arch::kernel::percore::increment_irq_counter; +use crate::arch::kernel::percore::{core_id, increment_irq_counter}; use crate::arch::mm::paging::virt_to_phys; use crate::arch::mm::VirtAddr; use crate::drivers::error::DriverError; +use crate::drivers::net::apic::assign_irq_to_core; use crate::drivers::net::{network_irqhandler, NetworkInterface}; use crate::x86::io::*; @@ -217,6 +218,10 @@ impl NetworkInterface for RTL8139Driver { self.mac } + fn assign_task_to_nic(&self) { + assign_irq_to_core(self.irq, core_id()); + } + /// Returns the current MTU of the device. fn get_mtu(&self) -> u16 { self.mtu diff --git a/src/drivers/net/virtio_net.rs b/src/drivers/net/virtio_net.rs index f9b4afc6c4ad5a96e8e37249d763d8de9c842149..b4c649254e12950fc143f7e769de084aed0899bf 100644 --- a/src/drivers/net/virtio_net.rs +++ b/src/drivers/net/virtio_net.rs @@ -4,7 +4,7 @@ #[cfg(not(feature = "newlib"))] use super::netwakeup; -use crate::arch::kernel::percore::increment_irq_counter; +use crate::arch::kernel::percore::{core_id, increment_irq_counter}; use crate::config::VIRTIO_MAX_QUEUE_SIZE; use crate::drivers::net::NetworkInterface; @@ -16,6 +16,7 @@ use core::mem; use core::result::Result; use core::{cell::RefCell, cmp::Ordering}; +use crate::drivers::net::apic::assign_irq_to_core; #[cfg(not(feature = "pci"))] use crate::drivers::net::virtio_mmio::NetDevCfgRaw; #[cfg(feature = "pci")] @@ -515,6 +516,10 @@ impl NetworkInterface for VirtioNetDriver { } } + fn assign_task_to_nic(&self) { + assign_irq_to_core(self.irq, core_id()); + } + /// Returns the current MTU of the device. /// Currently, if VIRTIO_NET_F_MAC is not set // MTU is set static to 1500 bytes. diff --git a/src/syscalls/interfaces/mod.rs b/src/syscalls/interfaces/mod.rs index 5f9b66f4220bc93bc2aeb40213ca6a6e4151660b..676a51ff83cf15accdc92936b7a4dd71110f2576 100644 --- a/src/syscalls/interfaces/mod.rs +++ b/src/syscalls/interfaces/mod.rs @@ -127,6 +127,13 @@ pub trait SyscallInterface: Send + Sync { Err(()) } + fn assign_task_to_nic(&self) { + #[cfg(not(target_arch = "aarch64"))] + if let Some(driver) = get_network_driver() { + driver.lock().assign_task_to_nic(); + } + } + fn get_mtu(&self) -> Result<u16, ()> { #[cfg(not(target_arch = "aarch64"))] match get_network_driver() { diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index 037543640135e9865fc1b4ff6d4d6b87362e91ff..cc0ac4d52b5e187b279e5a9dca3f77fa2de07780 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -103,6 +103,17 @@ pub fn sys_get_mac_address() -> Result<[u8; 6], ()> { kernel_function!(__sys_get_mac_address()) } +extern "C" fn __sys_assign_task_to_nic() { + unsafe { + SYS.assign_task_to_nic(); + } +} + +#[no_mangle] +fn sys_assign_task_to_nic() { + kernel_function!(__sys_assign_task_to_nic()); +} + #[allow(improper_ctypes_definitions)] extern "C" fn __sys_get_mtu() -> Result<u16, ()> { unsafe { SYS.get_mtu() }