From 0cfc9af8bd85f715171dff5b032b3867d1230489 Mon Sep 17 00:00:00 2001 From: Stefan Lankes <slankes@eonerc.rwth-aachen.de> Date: Sun, 24 Jul 2022 09:35:11 +0200 Subject: [PATCH] add option to assign a task to the nic the new syscall allows us to handle the network interrupt on the core, where the network thread (see hermit-sys) is running --- src/arch/x86_64/kernel/apic.rs | 5 +++++ src/drivers/net/mod.rs | 2 ++ src/drivers/net/rtl8139.rs | 7 ++++++- src/drivers/net/virtio_net.rs | 7 ++++++- src/syscalls/interfaces/mod.rs | 7 +++++++ src/syscalls/mod.rs | 11 +++++++++++ 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/arch/x86_64/kernel/apic.rs b/src/arch/x86_64/kernel/apic.rs index 89f8594cd..8853d5dcf 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 673e0b500..cb455bcfa 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 0f52fc58f..87de243ba 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 f9b4afc6c..b4c649254 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 5f9b66f42..676a51ff8 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 037543640..cc0ac4d52 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() } -- GitLab