Skip to content

Commit

Permalink
Merge pull request #799 from stlankes/async
Browse files Browse the repository at this point in the history
revise handling of asynchronous tasks
  • Loading branch information
mkroening authored Jul 25, 2023
2 parents 1811673 + 342e631 commit 9cf5554
Show file tree
Hide file tree
Showing 19 changed files with 600 additions and 521 deletions.
30 changes: 0 additions & 30 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 0 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ smp = ["include-transformed"]
fsgsbase = []
trace = []
tcp = [
"async-task",
"futures-lite",
"smoltcp",
]
dhcpv4 = [
Expand All @@ -85,8 +83,6 @@ pflock = "0.2"
shell-words = { version = "1.1", default-features = false }
qemu-exit = "3.0"
rand_chacha = { version = "0.3", default-features = false }
futures-lite = { version = "1.11", default-features = false, optional = true }
async-task = { version = "4.4", default-features = false, optional = true }
lock_api = "0.4"
num = { version = "0.4", default-features = false }
num-traits = { version = "0.2", default-features = false }
Expand Down
21 changes: 15 additions & 6 deletions src/arch/aarch64/kernel/core_local.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::arch::asm;
use core::cell::Cell;
use core::cell::{Cell, RefCell, RefMut};
use core::ptr;
use core::sync::atomic::Ordering;

use super::interrupts::{IrqStatistics, IRQ_COUNTERS};
use super::CPU_ONLINE;
use crate::executor::task::AsyncTask;
use crate::scheduler::{CoreId, PerCoreScheduler};

pub struct CoreLocal {
pub(crate) struct CoreLocal {
this: *const Self,
/// ID of the current Core.
core_id: CoreId,
/// Scheduler of the current Core.
scheduler: Cell<*mut PerCoreScheduler>,
/// Interface to the interrupt counters
irq_statistics: &'static IrqStatistics,
/// Queue of async tasks
async_tasks: RefCell<Vec<AsyncTask>>,
}

impl CoreLocal {
Expand All @@ -30,6 +34,7 @@ impl CoreLocal {
core_id,
scheduler: Cell::new(ptr::null_mut()),
irq_statistics,
async_tasks: RefCell::new(Vec::new()),
};
let this = Box::leak(Box::new(this));
this.this = &*this;
Expand All @@ -50,7 +55,7 @@ impl CoreLocal {
}

#[inline]
pub fn core_id() -> CoreId {
pub(crate) fn core_id() -> CoreId {
if cfg!(target_os = "none") {
CoreLocal::get().core_id
} else {
Expand All @@ -59,14 +64,18 @@ pub fn core_id() -> CoreId {
}

#[inline]
pub fn core_scheduler() -> &'static mut PerCoreScheduler {
pub(crate) fn core_scheduler() -> &'static mut PerCoreScheduler {
unsafe { &mut *CoreLocal::get().scheduler.get() }
}

pub fn set_core_scheduler(scheduler: *mut PerCoreScheduler) {
pub(crate) fn async_tasks() -> RefMut<'static, Vec<AsyncTask>> {
CoreLocal::get().async_tasks.borrow_mut()
}

pub(crate) fn set_core_scheduler(scheduler: *mut PerCoreScheduler) {
CoreLocal::get().scheduler.set(scheduler);
}

pub fn increment_irq_counter(irq_no: u8) {
pub(crate) fn increment_irq_counter(irq_no: u8) {
CoreLocal::get().irq_statistics.inc(irq_no);
}
22 changes: 16 additions & 6 deletions src/arch/x86_64/kernel/core_local.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::arch::asm;
use core::cell::Cell;
use core::cell::{Cell, RefCell, RefMut};
use core::ptr;
use core::sync::atomic::Ordering;

Expand All @@ -10,10 +11,11 @@ use x86_64::VirtAddr;

use super::interrupts::{IrqStatistics, IRQ_COUNTERS};
use super::CPU_ONLINE;
use crate::executor::task::AsyncTask;
use crate::scheduler::{CoreId, PerCoreScheduler};

#[repr(C)]
pub struct CoreLocal {
pub(crate) struct CoreLocal {
this: *const Self,
/// Sequential ID of this CPU Core.
core_id: CoreId,
Expand All @@ -25,6 +27,8 @@ pub struct CoreLocal {
pub kernel_stack: Cell<u64>,
/// Interface to the interrupt counters
irq_statistics: &'static IrqStatistics,
/// Queue of async tasks
async_tasks: RefCell<Vec<AsyncTask>>,
}

impl CoreLocal {
Expand All @@ -43,13 +47,15 @@ impl CoreLocal {
tss: Cell::new(ptr::null_mut()),
kernel_stack: Cell::new(0),
irq_statistics,
async_tasks: RefCell::new(Vec::new()),
};
let this = Box::leak(Box::new(this));
this.this = &*this;

GsBase::write(VirtAddr::from_ptr(this));
}

#[inline]
pub fn get() -> &'static Self {
debug_assert_ne!(VirtAddr::zero(), GsBase::read());
unsafe {
Expand All @@ -60,22 +66,26 @@ impl CoreLocal {
}
}

pub fn core_id() -> CoreId {
pub(crate) fn core_id() -> CoreId {
if cfg!(target_os = "none") {
CoreLocal::get().core_id
} else {
0
}
}

pub fn core_scheduler() -> &'static mut PerCoreScheduler {
pub(crate) fn core_scheduler() -> &'static mut PerCoreScheduler {
unsafe { &mut *CoreLocal::get().scheduler.get() }
}

pub fn set_core_scheduler(scheduler: *mut PerCoreScheduler) {
pub(crate) fn async_tasks() -> RefMut<'static, Vec<AsyncTask>> {
CoreLocal::get().async_tasks.borrow_mut()
}

pub(crate) fn set_core_scheduler(scheduler: *mut PerCoreScheduler) {
CoreLocal::get().scheduler.set(scheduler);
}

pub fn increment_irq_counter(irq_no: u8) {
pub(crate) fn increment_irq_counter(irq_no: u8) {
CoreLocal::get().irq_statistics.inc(irq_no);
}
27 changes: 10 additions & 17 deletions src/drivers/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,37 +47,30 @@ pub trait NetworkInterface {

#[inline]
fn _irqhandler() -> bool {
if let Some(driver) = hardware::get_network_driver() {
let result = if let Some(driver) = hardware::get_network_driver() {
driver.lock().handle_interrupt()
} else {
debug!("Unable to handle interrupt!");
false
}
};

// TODO: do we need it?
crate::executor::run();

result
}

#[cfg(target_arch = "aarch64")]
pub(crate) fn network_irqhandler(_state: &State) -> bool {
debug!("Receive network interrupt");
let has_packet = _irqhandler();

if has_packet {
#[cfg(feature = "tcp")]
core_scheduler().wakeup_async_tasks();
}

has_packet
_irqhandler()
}

#[cfg(target_arch = "x86_64")]
pub(crate) extern "x86-interrupt" fn network_irqhandler(_stack_frame: ExceptionStackFrame) {
debug!("Receive network interrupt");
apic::eoi();
let has_packet = _irqhandler();
let _ = _irqhandler();

if has_packet {
let core_scheduler = core_scheduler();
#[cfg(feature = "tcp")]
core_scheduler.wakeup_async_tasks();
core_scheduler.reschedule();
}
core_scheduler().reschedule();
}
9 changes: 8 additions & 1 deletion src/drivers/net/virtio_net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use core::cell::RefCell;
use core::cmp::Ordering;
use core::mem;
use core::result::Result;
use core::str::FromStr;

use pci_types::InterruptLine;
use zerocopy::AsBytes;
Expand Down Expand Up @@ -517,7 +518,13 @@ impl NetworkInterface for VirtioNetDriver {
/// Currently, if VIRTIO_NET_F_MAC is not set
// MTU is set static to 1500 bytes.
fn get_mtu(&self) -> u16 {
if self.dev_cfg.features.is_feature(Features::VIRTIO_NET_F_MTU) {
if let Some(my_mtu) = hermit_var!("HERMIT_MTU") {
warn!(
"Using value of the environment variable HERMIT_MTU ({}) as MTU",
my_mtu
);
u16::from_str(&my_mtu).unwrap()
} else if self.dev_cfg.features.is_feature(Features::VIRTIO_NET_F_MTU) {
self.dev_cfg.raw.get_mtu()
} else {
1500
Expand Down
1 change: 0 additions & 1 deletion src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ pub fn freq() -> Option<u16> {
CLI.get().unwrap().freq
}

#[cfg(all(feature = "tcp", not(feature = "dhcpv4")))]
pub fn var(key: &str) -> Option<&String> {
CLI.get().unwrap().env_vars.get(key)
}
Expand Down
35 changes: 3 additions & 32 deletions src/executor/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ use smoltcp::wire::{EthernetAddress, HardwareAddress};
#[cfg(not(feature = "dhcpv4"))]
use smoltcp::wire::{IpAddress, IpCidr, Ipv4Address};

use super::network::{NetworkInterface, NetworkState};
use crate::arch;
#[cfg(not(feature = "pci"))]
use crate::arch::kernel::mmio as hardware;
#[cfg(feature = "pci")]
use crate::drivers::pci as hardware;
#[cfg(not(feature = "dhcpv4"))]
use crate::env;
use crate::executor::{NetworkInterface, NetworkState};

/// Data type to determine the mac address
#[derive(Debug, Copy, Clone)]
Expand All @@ -35,33 +33,6 @@ impl HermitNet {
}
}

/// Returns the value of the specified environment variable.
///
/// The value is fetched from the current runtime environment and, if not
/// present, falls back to the same environment variable set at compile time
/// (might not be present as well).
#[cfg(not(feature = "dhcpv4"))]
macro_rules! hermit_var {
($name:expr) => {{
use alloc::borrow::Cow;

match env::var($name) {
Some(val) => Some(Cow::from(val)),
None => option_env!($name).map(Cow::Borrowed),
}
}};
}

/// Tries to fetch the specified environment variable with a default value.
///
/// Fetches according to [`hermit_var`] or returns the specified default value.
#[cfg(not(feature = "dhcpv4"))]
macro_rules! hermit_var_or {
($name:expr, $default:expr) => {{
hermit_var!($name).as_deref().unwrap_or($default)
}};
}

impl<'a> NetworkInterface<'a> {
#[cfg(feature = "dhcpv4")]
pub(crate) fn create() -> NetworkState<'a> {
Expand Down Expand Up @@ -89,7 +60,7 @@ impl<'a> NetworkInterface<'a> {
config.hardware_addr = hardware_addr;
}

let iface = Interface::new(config, &mut device, crate::executor::now());
let iface = Interface::new(config, &mut device, crate::executor::network::now());
let mut sockets = SocketSet::new(vec![]);
let dhcp_handle = sockets.add(dhcp);

Expand Down Expand Up @@ -154,7 +125,7 @@ impl<'a> NetworkInterface<'a> {
config.hardware_addr = hardware_addr;
}

let mut iface = Interface::new(config, &mut device, crate::executor::now());
let mut iface = Interface::new(config, &mut device, crate::executor::network::now());
iface.update_ip_addrs(|ip_addrs| {
ip_addrs
.push(IpCidr::new(
Expand Down
Loading

0 comments on commit 9cf5554

Please sign in to comment.