Aufgrund einer Wartung wird GitLab am 26.10. zwischen 8:00 und 9:00 Uhr kurzzeitig nicht zur Verfügung stehen. / Due to maintenance, GitLab will be temporarily unavailable on 26.10. between 8:00 and 9:00 am.

Commit 455b63fe authored by Stefan Lankes's avatar Stefan Lankes Committed by Stefan Lankes
Browse files

Revert "protect network driver by an SpinlockIrqSave"

This reverts commit bcc35834529f2c8321ac5d381000f28ba4d6d5a5.
parent 267f35bb
......@@ -12,8 +12,9 @@ use crate::arch::x86_64::kernel::virtio_fs::VirtioFsDriver;
use crate::arch::x86_64::kernel::virtio_net::VirtioNetDriver;
use crate::synch::spinlock::SpinlockIrqSave;
use crate::x86::io::*;
use alloc::rc::Rc;
use alloc::vec::Vec;
use core::cell::UnsafeCell;
use core::cell::RefCell;
use core::convert::TryInto;
use core::{fmt, u32, u8};
......@@ -124,8 +125,8 @@ pub struct MemoryBar {
}
pub enum PciDriver<'a> {
VirtioFs(UnsafeCell<SpinlockIrqSave<VirtioFsDriver<'a>>>),
VirtioNet(UnsafeCell<SpinlockIrqSave<VirtioNetDriver<'a>>>),
VirtioFs(Rc<RefCell<VirtioFsDriver<'a>>>),
VirtioNet(Rc<RefCell<VirtioNetDriver<'a>>>),
}
pub fn register_driver(drv: PciDriver<'static>) {
......@@ -133,11 +134,12 @@ pub fn register_driver(drv: PciDriver<'static>) {
drivers.push(drv);
}
pub fn get_network_driver() -> Option<&'static SpinlockIrqSave<VirtioNetDriver<'static>>> {
for i in PCI_DRIVERS.lock().iter() {
pub fn get_network_driver() -> Option<Rc<RefCell<VirtioNetDriver<'static>>>> {
let drivers = PCI_DRIVERS.lock();
for i in drivers.iter() {
match &*i {
PciDriver::VirtioNet(nic_driver) => {
return Some(unsafe { &*nic_driver.get() });
return Some(nic_driver.clone());
}
_ => {}
}
......
......@@ -16,13 +16,11 @@ use crate::arch::x86_64::kernel::virtio_net;
use crate::arch::x86_64::mm::paging;
use crate::config::VIRTIO_MAX_QUEUE_SIZE;
use crate::synch::spinlock::SpinlockIrqSave;
use alloc::boxed::Box;
use alloc::rc::Rc;
use alloc::vec::Vec;
use core::cell::RefCell;
use core::cell::UnsafeCell;
use core::convert::TryInto;
use core::sync::atomic::spin_loop_hint;
use core::sync::atomic::{fence, Ordering};
......@@ -830,9 +828,7 @@ pub fn init_virtio_device(adapter: &pci::PciAdapter) {
PciNetworkControllerSubclass::EthernetController => {
// TODO: proper error handling on driver creation fail
let drv = virtio_net::create_virtionet_driver(adapter).unwrap();
pci::register_driver(PciDriver::VirtioNet(UnsafeCell::new(
SpinlockIrqSave::new(drv),
)));
pci::register_driver(PciDriver::VirtioNet(drv));
}
_ => {
warn!("Virtio device is NOT supported, skipping!");
......@@ -876,7 +872,7 @@ extern "x86-interrupt" fn virtio_irqhandler(_stack_frame: &mut ExceptionStackFra
increment_irq_counter((32 + unsafe { VIRTIO_IRQ_NO }).into());
let check_scheduler = match get_network_driver() {
Some(driver) => driver.lock().handle_interrupt(),
Some(driver) => driver.borrow_mut().handle_interrupt(),
_ => false,
};
......
......@@ -462,7 +462,9 @@ impl<'a> VirtioNetDriver<'a> {
}
}
pub fn create_virtionet_driver(adapter: &pci::PciAdapter) -> Option<VirtioNetDriver<'static>> {
pub fn create_virtionet_driver(
adapter: &pci::PciAdapter,
) -> Option<Rc<RefCell<VirtioNetDriver<'static>>>> {
// Scan capabilities to get common config, which we need to reset the device and get basic info.
// also see https://elixir.bootlin.com/linux/latest/source/drivers/virtio/virtio_pci_modern.c#L581 (virtio_pci_modern_probe)
// Read status register
......@@ -531,7 +533,7 @@ pub fn create_virtionet_driver(adapter: &pci::PciAdapter) -> Option<VirtioNetDri
// TODO: also load the other cap types (?).
// Instanciate driver on heap, so it outlives this function
let mut drv = VirtioNetDriver {
let drv = Rc::new(RefCell::new(VirtioNetDriver {
tx_buffers: Vec::new(),
rx_buffers: Vec::new(),
common_cfg,
......@@ -539,10 +541,10 @@ pub fn create_virtionet_driver(adapter: &pci::PciAdapter) -> Option<VirtioNetDri
isr_cfg,
notify_cfg,
vqueues: None,
};
}));
trace!("Driver before init: {:?}", drv);
drv.init();
drv.borrow_mut().init();
trace!("Driver after init: {:?}", drv);
if device_cfg.status & VIRTIO_NET_S_LINK_UP == VIRTIO_NET_S_LINK_UP {
......@@ -550,7 +552,10 @@ pub fn create_virtionet_driver(adapter: &pci::PciAdapter) -> Option<VirtioNetDri
} else {
info!("Virtio-Net link is down");
}
info!("Virtio-Net status: 0x{:x}", drv.common_cfg.device_status);
info!(
"Virtio-Net status: 0x{:x}",
drv.borrow().common_cfg.device_status
);
Some(drv)
}
......@@ -5,6 +5,7 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
use crate::arch::irq;
use crate::arch::kernel::percore::*;
use crate::scheduler::task::TaskHandle;
use crate::synch::semaphore::*;
......@@ -24,10 +25,14 @@ const POLL_PERIOD: u64 = 20_000;
fn set_polling_mode(value: bool) {
// is the driver already in polling mode?
if POLLING.swap(value, Ordering::SeqCst) != value {
let irq = irq::nested_disable();
if let Some(driver) = crate::arch::kernel::pci::get_network_driver() {
driver.lock().set_polling_mode(value);
driver.borrow_mut().set_polling_mode(value);
}
irq::nested_enable(irq);
// wakeup network thread to sleep for longer time
NET_SEM.release();
}
......@@ -65,9 +70,13 @@ pub fn netwait_and_wakeup(handles: &[usize], millis: Option<u64>) {
}
if reset_nic {
let irq = irq::nested_disable();
if let Some(driver) = crate::arch::kernel::pci::get_network_driver() {
driver.lock().set_polling_mode(false);
driver.borrow_mut().set_polling_mode(false);
}
irq::nested_enable(irq);
} else {
NET_SEM.acquire(millis);
}
......
......@@ -17,6 +17,7 @@ use crate::arch;
use crate::console;
use crate::environment;
use crate::errno::*;
use crate::synch::spinlock::SpinlockIrqSave;
use crate::syscalls::fs::{self, FilePerms, PosixFile, SeekWhence};
use crate::util;
......@@ -26,6 +27,8 @@ pub use self::uhyve::*;
mod generic;
mod uhyve;
static DRIVER_LOCK: SpinlockIrqSave<()> = SpinlockIrqSave::new(());
const SEEK_SET: i32 = 0;
const SEEK_CUR: i32 = 1;
const SEEK_END: i32 = 2;
......@@ -116,51 +119,65 @@ pub trait SyscallInterface: Send + Sync {
}
fn get_mac_address(&self) -> Result<[u8; 6], ()> {
let _lock = DRIVER_LOCK.lock();
match arch::kernel::pci::get_network_driver() {
Some(driver) => Ok(driver.lock().get_mac_address()),
Some(driver) => Ok(driver.borrow().get_mac_address()),
_ => Err(()),
}
}
fn get_mtu(&self) -> Result<u16, ()> {
let _lock = DRIVER_LOCK.lock();
match arch::kernel::pci::get_network_driver() {
Some(driver) => Ok(driver.lock().get_mtu()),
Some(driver) => Ok(driver.borrow().get_mtu()),
_ => Err(()),
}
}
fn has_packet(&self) -> bool {
let _lock = DRIVER_LOCK.lock();
match arch::kernel::pci::get_network_driver() {
Some(driver) => driver.lock().has_packet(),
Some(driver) => driver.borrow().has_packet(),
_ => false,
}
}
fn get_tx_buffer(&self, len: usize) -> Result<(*mut u8, usize), ()> {
let _lock = DRIVER_LOCK.lock();
match arch::kernel::pci::get_network_driver() {
Some(driver) => driver.lock().get_tx_buffer(len),
Some(driver) => driver.borrow_mut().get_tx_buffer(len),
_ => Err(()),
}
}
fn send_tx_buffer(&self, handle: usize, len: usize) -> Result<(), ()> {
let _lock = DRIVER_LOCK.lock();
match arch::kernel::pci::get_network_driver() {
Some(driver) => driver.lock().send_tx_buffer(handle, len),
Some(driver) => driver.borrow_mut().send_tx_buffer(handle, len),
_ => Err(()),
}
}
fn receive_rx_buffer(&self) -> Result<&'static [u8], ()> {
let _lock = DRIVER_LOCK.lock();
match arch::kernel::pci::get_network_driver() {
Some(driver) => driver.lock().receive_rx_buffer(),
Some(driver) => driver.borrow().receive_rx_buffer(),
_ => Err(()),
}
}
fn rx_buffer_consumed(&self) -> Result<(), ()> {
let _lock = DRIVER_LOCK.lock();
match arch::kernel::pci::get_network_driver() {
Some(driver) => {
driver.lock().rx_buffer_consumed();
driver.borrow_mut().rx_buffer_consumed();
Ok(())
}
_ => Err(()),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment