Skip to content

refactor(drivers): Make virtio-net optional and feature-gated #1825

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ jobs:
- name: Checkout hermit-rs
uses: actions/checkout@v4
with:
repository: hermit-os/hermit-rs
repository: Gelbpunkt/hermit-rs
ref: virtio-net-optional
- name: Checkout hermit-kernel
uses: actions/checkout@v4
with:
Expand Down
23 changes: 12 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ jobs:
- name: Checkout hermit-rs
uses: actions/checkout@v4
with:
repository: hermit-os/hermit-rs
repository: Gelbpunkt/hermit-rs
ref: virtio-net-optional
- name: Checkout hermit-kernel
uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -209,39 +210,39 @@ jobs:
if: matrix.arch == 'x86_64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package rftrace-example qemu ${{ matrix.flags }} --devices virtio-fs-pci
if: matrix.arch == 'x86_64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4 qemu ${{ matrix.flags }} --devices virtio-net-pci
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4,hermit/virtio-net qemu ${{ matrix.flags }} --devices virtio-net-pci
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci qemu --sudo --devices virtio-net-pci --tap
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/virtio-net qemu --sudo --devices virtio-net-pci --tap
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4 qemu ${{ matrix.flags }} --devices virtio-net-pci --no-default-virtio-features
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4,hermit/virtio-net qemu ${{ matrix.flags }} --devices virtio-net-pci --no-default-virtio-features
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4 qemu ${{ matrix.flags }} --devices virtio-net-pci --uefi
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4,hermit/virtio-net qemu ${{ matrix.flags }} --devices virtio-net-pci --uefi
if: matrix.arch == 'x86_64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --no-default-features --features ci,hermit/dhcpv4,hermit/tcp qemu ${{ matrix.flags }} --microvm --devices virtio-net-mmio
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --no-default-features --features ci,hermit/dhcpv4,hermit/tcp,hermit/virtio-net qemu ${{ matrix.flags }} --microvm --devices virtio-net-mmio
if: matrix.arch == 'x86_64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --no-default-features --features ci,hermit/dhcpv4,hermit/tcp qemu ${{ matrix.flags }} --devices virtio-net-mmio
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --no-default-features --features ci,hermit/dhcpv4,hermit/tcp,hermit/virtio-net qemu ${{ matrix.flags }} --devices virtio-net-mmio
if: matrix.arch == 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.flags }} --devices rtl8139
if: matrix.arch == 'x86_64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --no-default-features --features ci,hermit/dhcpv4,hermit/tcp,hermit/gem-net qemu ${{ matrix.flags }} --devices cadence-gem
if: matrix.arch == 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package testudp --features hermit/udp,hermit/dhcpv4 qemu ${{ matrix.flags }} --devices virtio-net-pci
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package testudp --features hermit/udp,hermit/dhcpv4,hermit/virtio-net qemu ${{ matrix.flags }} --devices virtio-net-pci
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package testudp --features hermit/udp,hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.flags }} --devices rtl8139
if: matrix.arch == 'x86_64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package testudp --no-default-features --features hermit/udp,hermit/dhcpv4,hermit/gem-net qemu ${{ matrix.flags }} --devices cadence-gem
if: matrix.arch == 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package miotcp --features hermit/dhcpv4 qemu ${{ matrix.flags }} --devices virtio-net-pci
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package miotcp --features hermit/dhcpv4,hermit/virtio-net qemu ${{ matrix.flags }} --devices virtio-net-pci
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package miotcp --features hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.flags }} --devices rtl8139
if: matrix.arch == 'x86_64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package miotcp --no-default-features --features hermit/dhcpv4,hermit/tcp,hermit/gem-net qemu ${{ matrix.flags }} --devices cadence-gem
if: matrix.arch == 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package poll --features hermit/dhcpv4 qemu ${{ matrix.flags }} --devices virtio-net-pci
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package poll --features hermit/dhcpv4,hermit/virtio-net qemu ${{ matrix.flags }} --devices virtio-net-pci
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package poll --features hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.flags }} --devices rtl8139
if: matrix.arch == 'x86_64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package mioudp --features hermit/udp,hermit/dhcpv4 qemu ${{ matrix.flags }} --devices virtio-net-pci
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package mioudp --features hermit/udp,hermit/dhcpv4,hermit/virtio-net qemu ${{ matrix.flags }} --devices virtio-net-pci
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package mioudp --features hermit/udp,hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.flags }} --devices rtl8139
if: matrix.arch == 'x86_64'
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ tcp = ["smoltcp", "smoltcp/socket-tcp"]
trace = ["smoltcp?/log", "smoltcp?/verbose"]
udp = ["smoltcp", "smoltcp/socket-udp"]
vga = []
virtio-net = []
vsock = ["pci"]

[lints.rust]
Expand Down
6 changes: 5 additions & 1 deletion src/arch/aarch64/kernel/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
pub mod core_local;
pub mod interrupts;
#[cfg(all(not(feature = "pci"), any(feature = "tcp", feature = "udp")))]
#[cfg(all(
not(feature = "pci"),
feature = "virtio-net",
any(feature = "tcp", feature = "udp")
))]
pub mod mmio;
#[cfg(feature = "pci")]
pub mod pci;
Expand Down
57 changes: 47 additions & 10 deletions src/arch/riscv64/kernel/devicetree.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "pci")))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
feature = "virtio-net",
not(feature = "pci")
))]
use core::ptr::NonNull;

use fdt::Fdt;
Expand All @@ -9,14 +13,26 @@ use memory_addresses::PhysAddr;
not(feature = "pci")
))]
use memory_addresses::VirtAddr;
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "pci")))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
feature = "virtio-net",
not(feature = "pci")
))]
use virtio::mmio::{DeviceRegisters, DeviceRegistersVolatileFieldAccess};
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "pci")))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
feature = "virtio-net",
not(feature = "pci")
))]
use volatile::VolatileRef;

use crate::arch::riscv64::kernel::get_dtb_ptr;
use crate::arch::riscv64::kernel::interrupts::init_plic;
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "pci")))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
any(feature = "gem-net", feature = "virtio-net"),
not(feature = "pci")
))]
use crate::arch::riscv64::kernel::mmio::MmioDriver;
use crate::arch::riscv64::mm::paging::{self, PageSize};
#[cfg(all(
Expand All @@ -28,10 +44,15 @@ use crate::drivers::net::gem;
#[cfg(all(
any(feature = "tcp", feature = "udp"),
not(feature = "pci"),
not(feature = "gem-net")
not(feature = "gem-net"),
feature = "virtio-net",
))]
use crate::drivers::virtio::transport::mmio::{self as mmio_virtio, VirtioDriver};
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "pci")))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
any(feature = "gem-net", feature = "virtio-net"),
not(feature = "pci")
))]
use crate::kernel::mmio::register_driver;

static mut PLATFORM_MODEL: Model = Model::Unknown;
Expand Down Expand Up @@ -115,7 +136,11 @@ pub fn init_drivers() {
}

// Init GEM
#[cfg(all(feature = "gem-net", not(feature = "pci")))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
feature = "gem-net",
not(feature = "pci")
))]
if let Some(gem_node) = fdt.find_compatible(&["sifive,fu540-c000-gem"]) {
debug!("Found Ethernet controller");

Expand Down Expand Up @@ -170,7 +195,11 @@ pub fn init_drivers() {
}

// Init virtio-mmio
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "pci")))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
feature = "virtio-net",
not(feature = "pci")
))]
if let Some(virtio_node) = fdt.find_compatible(&["virtio,mmio"]) {
debug!("Found virtio mmio device");
let virtio_region = virtio_node
Expand Down Expand Up @@ -228,7 +257,11 @@ pub fn init_drivers() {
// BasePageSize::SIZE as usize,
// );

#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "gem-net")))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
feature = "virtio-net",
not(feature = "gem-net")
))]
if let Ok(VirtioDriver::Network(drv)) =
mmio_virtio::init_device(mmio, irq.try_into().unwrap())
{
Expand All @@ -240,6 +273,10 @@ pub fn init_drivers() {
}
}

#[cfg(all(feature = "tcp", not(feature = "pci")))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
any(feature = "virtio-net", feature = "gem-net"),
not(feature = "pci")
))]
super::mmio::MMIO_DRIVERS.finalize();
}
8 changes: 4 additions & 4 deletions src/arch/riscv64/kernel/mmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use hermit_sync::InterruptSpinMutex;

#[cfg(feature = "gem-net")]
use crate::drivers::net::gem::GEMDriver;
#[cfg(not(feature = "gem-net"))]
#[cfg(all(feature = "virtio-net", not(feature = "gem-net")))]
use crate::drivers::net::virtio::VirtioNetDriver;
use crate::init_cell::InitCell;

Expand All @@ -13,7 +13,7 @@ pub(crate) static MMIO_DRIVERS: InitCell<Vec<MmioDriver>> = InitCell::new(Vec::n
pub(crate) enum MmioDriver {
#[cfg(feature = "gem-net")]
GEMNet(InterruptSpinMutex<GEMDriver>),
#[cfg(not(feature = "gem-net"))]
#[cfg(all(feature = "virtio-net", not(feature = "gem-net")))]
VirtioNet(InterruptSpinMutex<VirtioNetDriver>),
}

Expand All @@ -25,7 +25,7 @@ impl MmioDriver {
}
}

#[cfg(not(feature = "gem-net"))]
#[cfg(all(feature = "virtio-net", not(feature = "gem-net")))]
fn get_network_driver(&self) -> Option<&InterruptSpinMutex<VirtioNetDriver>> {
match self {
Self::VirtioNet(drv) => Some(drv),
Expand All @@ -44,7 +44,7 @@ pub(crate) fn get_network_driver() -> Option<&'static InterruptSpinMutex<GEMDriv
.find_map(|drv| drv.get_network_driver())
}

#[cfg(not(feature = "gem-net"))]
#[cfg(all(feature = "virtio-net", not(feature = "gem-net")))]
pub(crate) fn get_network_driver() -> Option<&'static InterruptSpinMutex<VirtioNetDriver>> {
MMIO_DRIVERS
.get()?
Expand Down
6 changes: 5 additions & 1 deletion src/arch/riscv64/kernel/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
pub mod core_local;
mod devicetree;
pub mod interrupts;
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "pci")))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
any(feature = "virtio-net", feature = "gem-net"),
not(feature = "pci")
))]
pub mod mmio;
#[cfg(feature = "pci")]
pub mod pci;
Expand Down
9 changes: 5 additions & 4 deletions src/arch/x86_64/kernel/mmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ pub(crate) enum MmioDriver {
}

impl MmioDriver {
#[allow(unreachable_patterns)]
fn get_network_driver(&self) -> Option<&InterruptTicketMutex<VirtioNetDriver>> {
match self {
Self::VirtioNet(drv) => Some(drv),
_ => None,
#[allow(clippy::irrefutable_let_patterns)]
if let MmioDriver::VirtioNet(drv) = self {
return Some(drv);
}

None
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/arch/x86_64/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ pub mod apic;
pub mod core_local;
pub mod gdt;
pub mod interrupts;
#[cfg(all(not(feature = "pci"), any(feature = "tcp", feature = "udp")))]
#[cfg(all(
not(feature = "pci"),
feature = "virtio-net",
any(feature = "tcp", feature = "udp")
))]
pub mod mmio;
#[cfg(feature = "pci")]
pub mod pci;
Expand Down
15 changes: 13 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,25 @@ pub const DEFAULT_STACK_SIZE: usize = 0x0001_0000;
pub(crate) const USER_STACK_SIZE: usize = 0x0010_0000;

#[cfg(any(
all(any(feature = "tcp", feature = "udp"), not(feature = "rtl8139")),
all(
any(feature = "tcp", feature = "udp"),
feature = "virtio-net",
not(feature = "rtl8139")
),
feature = "fuse",
feature = "vsock"
))]
pub(crate) const VIRTIO_MAX_QUEUE_SIZE: u16 = if cfg!(feature = "pci") { 2048 } else { 1024 };

/// Default keep alive interval in milliseconds
#[cfg(feature = "tcp")]
#[cfg(all(
feature = "tcp",
any(
feature = "virtio-net",
all(target_arch = "riscv64", feature = "gem-net", not(feature = "pci")),
all(target_arch = "x86_64", feature = "rtl8139"),
)
))]
pub(crate) const DEFAULT_KEEP_ALIVE_INTERVAL: u64 = 75000;

#[cfg(feature = "vsock")]
Expand Down
45 changes: 40 additions & 5 deletions src/drivers/mmio.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
#[cfg(any(feature = "tcp", feature = "udp"))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
any(
feature = "virtio-net",
all(target_arch = "riscv64", feature = "gem-net"),
all(target_arch = "x86_64", feature = "rtl8139"),
)
))]
use alloc::collections::VecDeque;

use ahash::RandomState;
use hashbrown::HashMap;

#[cfg(any(feature = "tcp", feature = "udp"))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
any(
feature = "virtio-net",
all(target_arch = "riscv64", feature = "gem-net"),
all(target_arch = "x86_64", feature = "rtl8139"),
)
))]
pub(crate) use crate::arch::kernel::mmio::get_network_driver;
#[cfg(any(feature = "tcp", feature = "udp"))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
any(
feature = "virtio-net",
all(target_arch = "riscv64", feature = "gem-net"),
all(target_arch = "x86_64", feature = "rtl8139"),
)
))]
use crate::drivers::Driver;
#[cfg(any(feature = "tcp", feature = "udp"))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
any(
feature = "virtio-net",
all(target_arch = "riscv64", feature = "gem-net"),
all(target_arch = "x86_64", feature = "rtl8139"),
)
))]
use crate::drivers::net::NetworkDriver;
use crate::drivers::{InterruptHandlerQueue, InterruptLine};

Expand All @@ -18,7 +46,14 @@ pub(crate) fn get_interrupt_handlers() -> HashMap<InterruptLine, InterruptHandle
let mut handlers: HashMap<InterruptLine, InterruptHandlerQueue, RandomState> =
HashMap::with_hasher(RandomState::with_seeds(0, 0, 0, 0));

#[cfg(any(feature = "tcp", feature = "udp"))]
#[cfg(all(
any(feature = "tcp", feature = "udp"),
any(
feature = "virtio-net",
all(target_arch = "riscv64", feature = "gem-net"),
all(target_arch = "x86_64", feature = "rtl8139"),
)
))]
if let Some(drv) = get_network_driver() {
fn network_handler() {
if let Some(driver) = get_network_driver() {
Expand Down
Loading