mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-10 05:46:48 +00:00
Move network polling code to bottom half
This commit is contained in:
parent
9804f053f2
commit
7d24e63216
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -80,6 +80,7 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
|||||||
name = "aster-bigtcp"
|
name = "aster-bigtcp"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aster-softirq",
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"jhash",
|
"jhash",
|
||||||
"ostd",
|
"ostd",
|
||||||
@ -167,6 +168,7 @@ name = "aster-network"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aster-bigtcp",
|
"aster-bigtcp",
|
||||||
|
"aster-softirq",
|
||||||
"bitvec",
|
"bitvec",
|
||||||
"component",
|
"component",
|
||||||
"ostd",
|
"ostd",
|
||||||
@ -288,6 +290,7 @@ dependencies = [
|
|||||||
"aster-input",
|
"aster-input",
|
||||||
"aster-network",
|
"aster-network",
|
||||||
"aster-rights",
|
"aster-rights",
|
||||||
|
"aster-softirq",
|
||||||
"aster-util",
|
"aster-util",
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"component",
|
"component",
|
||||||
|
@ -7,6 +7,7 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aster-bigtcp = { path = "../../libs/aster-bigtcp" }
|
aster-bigtcp = { path = "../../libs/aster-bigtcp" }
|
||||||
|
aster-softirq = { path = "../softirq" }
|
||||||
bitvec = { version = "1.0.1", default-features = false, features = ["alloc"] }
|
bitvec = { version = "1.0.1", default-features = false, features = ["alloc"] }
|
||||||
component = { path = "../../libs/comp-sys/component" }
|
component = { path = "../../libs/comp-sys/component" }
|
||||||
ostd = { path = "../../../ostd" }
|
ostd = { path = "../../../ostd" }
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
use alloc::{collections::linked_list::LinkedList, sync::Arc};
|
use alloc::{collections::linked_list::LinkedList, sync::Arc};
|
||||||
|
|
||||||
|
use aster_softirq::BottomHalfDisabled;
|
||||||
use ostd::{
|
use ostd::{
|
||||||
mm::{
|
mm::{
|
||||||
Daddr, DmaDirection, DmaStream, FrameAllocOptions, HasDaddr, Infallible, VmReader,
|
Daddr, DmaDirection, DmaStream, FrameAllocOptions, HasDaddr, Infallible, VmReader,
|
||||||
VmWriter, PAGE_SIZE,
|
VmWriter, PAGE_SIZE,
|
||||||
},
|
},
|
||||||
sync::{LocalIrqDisabled, SpinLock},
|
sync::SpinLock,
|
||||||
Pod,
|
Pod,
|
||||||
};
|
};
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
@ -17,14 +18,14 @@ use crate::dma_pool::{DmaPool, DmaSegment};
|
|||||||
pub struct TxBuffer {
|
pub struct TxBuffer {
|
||||||
dma_stream: DmaStream,
|
dma_stream: DmaStream,
|
||||||
nbytes: usize,
|
nbytes: usize,
|
||||||
pool: &'static SpinLock<LinkedList<DmaStream>, LocalIrqDisabled>,
|
pool: &'static SpinLock<LinkedList<DmaStream>, BottomHalfDisabled>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TxBuffer {
|
impl TxBuffer {
|
||||||
pub fn new<H: Pod>(
|
pub fn new<H: Pod>(
|
||||||
header: &H,
|
header: &H,
|
||||||
packet: &[u8],
|
packet: &[u8],
|
||||||
pool: &'static SpinLock<LinkedList<DmaStream>, LocalIrqDisabled>,
|
pool: &'static SpinLock<LinkedList<DmaStream>, BottomHalfDisabled>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let header = header.as_bytes();
|
let header = header.as_bytes();
|
||||||
let nbytes = header.len() + packet.len();
|
let nbytes = header.len() + packet.len();
|
||||||
|
@ -8,6 +8,7 @@ use alloc::{
|
|||||||
};
|
};
|
||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
|
|
||||||
|
use aster_softirq::BottomHalfDisabled;
|
||||||
use bitvec::{array::BitArray, prelude::Lsb0};
|
use bitvec::{array::BitArray, prelude::Lsb0};
|
||||||
use ostd::{
|
use ostd::{
|
||||||
mm::{
|
mm::{
|
||||||
@ -34,8 +35,8 @@ pub struct DmaPool {
|
|||||||
direction: DmaDirection,
|
direction: DmaDirection,
|
||||||
is_cache_coherent: bool,
|
is_cache_coherent: bool,
|
||||||
high_watermark: usize,
|
high_watermark: usize,
|
||||||
avail_pages: SpinLock<VecDeque<Arc<DmaPage>>>,
|
avail_pages: SpinLock<VecDeque<Arc<DmaPage>>, BottomHalfDisabled>,
|
||||||
all_pages: SpinLock<VecDeque<Arc<DmaPage>>>,
|
all_pages: SpinLock<VecDeque<Arc<DmaPage>>, BottomHalfDisabled>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DmaPool {
|
impl DmaPool {
|
||||||
@ -98,7 +99,7 @@ impl DmaPool {
|
|||||||
pub fn alloc_segment(self: &Arc<Self>) -> Result<DmaSegment, ostd::Error> {
|
pub fn alloc_segment(self: &Arc<Self>) -> Result<DmaSegment, ostd::Error> {
|
||||||
// Lock order: pool.avail_pages -> pool.all_pages
|
// Lock order: pool.avail_pages -> pool.all_pages
|
||||||
// pool.avail_pages -> page.allocated_segments
|
// pool.avail_pages -> page.allocated_segments
|
||||||
let mut avail_pages = self.avail_pages.disable_irq().lock();
|
let mut avail_pages = self.avail_pages.lock();
|
||||||
if avail_pages.is_empty() {
|
if avail_pages.is_empty() {
|
||||||
/// Allocate a new page
|
/// Allocate a new page
|
||||||
let new_page = {
|
let new_page = {
|
||||||
@ -110,7 +111,7 @@ impl DmaPool {
|
|||||||
pool,
|
pool,
|
||||||
)?)
|
)?)
|
||||||
};
|
};
|
||||||
let mut all_pages = self.all_pages.disable_irq().lock();
|
let mut all_pages = self.all_pages.lock();
|
||||||
avail_pages.push_back(new_page.clone());
|
avail_pages.push_back(new_page.clone());
|
||||||
all_pages.push_back(new_page);
|
all_pages.push_back(new_page);
|
||||||
}
|
}
|
||||||
@ -125,7 +126,7 @@ impl DmaPool {
|
|||||||
|
|
||||||
/// Returns the number of pages in pool
|
/// Returns the number of pages in pool
|
||||||
fn num_pages(&self) -> usize {
|
fn num_pages(&self) -> usize {
|
||||||
self.all_pages.disable_irq().lock().len()
|
self.all_pages.lock().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return segment size in pool
|
/// Return segment size in pool
|
||||||
@ -140,7 +141,7 @@ struct DmaPage {
|
|||||||
segment_size: usize,
|
segment_size: usize,
|
||||||
// `BitArray` is 64 bits, since each `DmaSegment` is bigger than 64 bytes,
|
// `BitArray` is 64 bits, since each `DmaSegment` is bigger than 64 bytes,
|
||||||
// there's no more than `PAGE_SIZE` / 64 = 64 `DmaSegment`s in a `DmaPage`.
|
// there's no more than `PAGE_SIZE` / 64 = 64 `DmaSegment`s in a `DmaPage`.
|
||||||
allocated_segments: SpinLock<BitArray>,
|
allocated_segments: SpinLock<BitArray, BottomHalfDisabled>,
|
||||||
pool: Weak<DmaPool>,
|
pool: Weak<DmaPool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +168,7 @@ impl DmaPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_segment(self: &Arc<Self>) -> Option<DmaSegment> {
|
fn alloc_segment(self: &Arc<Self>) -> Option<DmaSegment> {
|
||||||
let mut segments = self.allocated_segments.disable_irq().lock();
|
let mut segments = self.allocated_segments.lock();
|
||||||
let free_segment_index = get_next_free_index(&segments, self.nr_blocks_per_page())?;
|
let free_segment_index = get_next_free_index(&segments, self.nr_blocks_per_page())?;
|
||||||
segments.set(free_segment_index, true);
|
segments.set(free_segment_index, true);
|
||||||
|
|
||||||
@ -190,7 +191,7 @@ impl DmaPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_full(&self) -> bool {
|
fn is_full(&self) -> bool {
|
||||||
let segments = self.allocated_segments.disable_irq().lock();
|
let segments = self.allocated_segments.lock();
|
||||||
get_next_free_index(&segments, self.nr_blocks_per_page()).is_none()
|
get_next_free_index(&segments, self.nr_blocks_per_page()).is_none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,10 +263,10 @@ impl Drop for DmaSegment {
|
|||||||
|
|
||||||
// Keep the same lock order as `pool.alloc_segment`
|
// Keep the same lock order as `pool.alloc_segment`
|
||||||
// Lock order: pool.avail_pages -> pool.all_pages -> page.allocated_segments
|
// Lock order: pool.avail_pages -> pool.all_pages -> page.allocated_segments
|
||||||
let mut avail_pages = pool.avail_pages.disable_irq().lock();
|
let mut avail_pages = pool.avail_pages.lock();
|
||||||
let mut all_pages = pool.all_pages.disable_irq().lock();
|
let mut all_pages = pool.all_pages.lock();
|
||||||
|
|
||||||
let mut allocated_segments = page.allocated_segments.disable_irq().lock();
|
let mut allocated_segments = page.allocated_segments.lock();
|
||||||
|
|
||||||
let nr_blocks_per_page = PAGE_SIZE / self.size;
|
let nr_blocks_per_page = PAGE_SIZE / self.size;
|
||||||
let became_avail = get_next_free_index(&allocated_segments, nr_blocks_per_page).is_none();
|
let became_avail = get_next_free_index(&allocated_segments, nr_blocks_per_page).is_none();
|
||||||
|
@ -16,13 +16,14 @@ use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec};
|
|||||||
use core::{any::Any, fmt::Debug};
|
use core::{any::Any, fmt::Debug};
|
||||||
|
|
||||||
use aster_bigtcp::device::DeviceCapabilities;
|
use aster_bigtcp::device::DeviceCapabilities;
|
||||||
|
use aster_softirq::{
|
||||||
|
softirq_id::{NETWORK_RX_SOFTIRQ_ID, NETWORK_TX_SOFTIRQ_ID},
|
||||||
|
BottomHalfDisabled, SoftIrqLine,
|
||||||
|
};
|
||||||
pub use buffer::{RxBuffer, TxBuffer, RX_BUFFER_POOL, TX_BUFFER_LEN};
|
pub use buffer::{RxBuffer, TxBuffer, RX_BUFFER_POOL, TX_BUFFER_LEN};
|
||||||
use component::{init_component, ComponentInitError};
|
use component::{init_component, ComponentInitError};
|
||||||
pub use dma_pool::DmaSegment;
|
pub use dma_pool::DmaSegment;
|
||||||
use ostd::{
|
use ostd::{sync::SpinLock, Pod};
|
||||||
sync::{LocalIrqDisabled, SpinLock},
|
|
||||||
Pod,
|
|
||||||
};
|
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Pod)]
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
@ -66,11 +67,11 @@ pub trait AnyNetworkDevice: Send + Sync + Any + Debug {
|
|||||||
fn notify_poll_end(&mut self);
|
fn notify_poll_end(&mut self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait NetDeviceIrqHandler = Fn() + Send + Sync + 'static;
|
pub trait NetDeviceCallback = Fn() + Send + Sync + 'static;
|
||||||
|
|
||||||
pub fn register_device(
|
pub fn register_device(
|
||||||
name: String,
|
name: String,
|
||||||
device: Arc<SpinLock<dyn AnyNetworkDevice, LocalIrqDisabled>>,
|
device: Arc<SpinLock<dyn AnyNetworkDevice, BottomHalfDisabled>>,
|
||||||
) {
|
) {
|
||||||
COMPONENT
|
COMPONENT
|
||||||
.get()
|
.get()
|
||||||
@ -80,7 +81,7 @@ pub fn register_device(
|
|||||||
.insert(name, NetworkDeviceIrqCallbackSet::new(device));
|
.insert(name, NetworkDeviceIrqCallbackSet::new(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device(str: &str) -> Option<Arc<SpinLock<dyn AnyNetworkDevice, LocalIrqDisabled>>> {
|
pub fn get_device(str: &str) -> Option<Arc<SpinLock<dyn AnyNetworkDevice, BottomHalfDisabled>>> {
|
||||||
let table = COMPONENT.get().unwrap().network_device_table.lock();
|
let table = COMPONENT.get().unwrap().network_device_table.lock();
|
||||||
let callbacks = table.get(str)?;
|
let callbacks = table.get(str)?;
|
||||||
Some(callbacks.device.clone())
|
Some(callbacks.device.clone())
|
||||||
@ -88,9 +89,9 @@ pub fn get_device(str: &str) -> Option<Arc<SpinLock<dyn AnyNetworkDevice, LocalI
|
|||||||
|
|
||||||
/// Registers callback which will be called when receiving message.
|
/// Registers callback which will be called when receiving message.
|
||||||
///
|
///
|
||||||
/// Since the callback will be called in interrupt context,
|
/// Since the callback will be called in softirq context,
|
||||||
/// the callback function should NOT sleep.
|
/// the callback function should _not_ sleep.
|
||||||
pub fn register_recv_callback(name: &str, callback: impl NetDeviceIrqHandler) {
|
pub fn register_recv_callback(name: &str, callback: impl NetDeviceCallback) {
|
||||||
let device_table = COMPONENT.get().unwrap().network_device_table.lock();
|
let device_table = COMPONENT.get().unwrap().network_device_table.lock();
|
||||||
let Some(callbacks) = device_table.get(name) else {
|
let Some(callbacks) = device_table.get(name) else {
|
||||||
return;
|
return;
|
||||||
@ -98,7 +99,15 @@ pub fn register_recv_callback(name: &str, callback: impl NetDeviceIrqHandler) {
|
|||||||
callbacks.recv_callbacks.lock().push(Arc::new(callback));
|
callbacks.recv_callbacks.lock().push(Arc::new(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_send_callback(name: &str, callback: impl NetDeviceIrqHandler) {
|
/// Registers a callback that will be invoked
|
||||||
|
/// when the device has completed sending a packet.
|
||||||
|
///
|
||||||
|
/// Since this callback is executed in a softirq context,
|
||||||
|
/// the callback function should _not_ block or sleep.
|
||||||
|
///
|
||||||
|
/// Please note that the callback may not be called every time a packet is sent.
|
||||||
|
/// The driver may skip certain callbacks for performance optimization.
|
||||||
|
pub fn register_send_callback(name: &str, callback: impl NetDeviceCallback) {
|
||||||
let device_table = COMPONENT.get().unwrap().network_device_table.lock();
|
let device_table = COMPONENT.get().unwrap().network_device_table.lock();
|
||||||
let Some(callbacks) = device_table.get(name) else {
|
let Some(callbacks) = device_table.get(name) else {
|
||||||
return;
|
return;
|
||||||
@ -106,37 +115,50 @@ pub fn register_send_callback(name: &str, callback: impl NetDeviceIrqHandler) {
|
|||||||
callbacks.send_callbacks.lock().push(Arc::new(callback));
|
callbacks.send_callbacks.lock().push(Arc::new(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_recv_irq(name: &str) {
|
fn handle_rx_softirq() {
|
||||||
let device_table = COMPONENT.get().unwrap().network_device_table.lock();
|
let device_table = COMPONENT.get().unwrap().network_device_table.lock();
|
||||||
let Some(callbacks) = device_table.get(name) else {
|
// TODO: We should handle network events for just one device per softirq,
|
||||||
return;
|
// rather than processing events for all devices.
|
||||||
};
|
// This issue should be addressed once new network devices are added.
|
||||||
|
for callback_set in device_table.values() {
|
||||||
let callbacks = callbacks.recv_callbacks.lock();
|
let recv_callbacks = callback_set.recv_callbacks.lock();
|
||||||
for callback in callbacks.iter() {
|
for callback in recv_callbacks.iter() {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_send_irq(name: &str) {
|
fn handle_tx_softirq() {
|
||||||
let device_table = COMPONENT.get().unwrap().network_device_table.lock();
|
let device_table = COMPONENT.get().unwrap().network_device_table.lock();
|
||||||
let Some(callbacks) = device_table.get(name) else {
|
// TODO: We should handle network events for just one device per softirq,
|
||||||
return;
|
// rather than processing events for all devices.
|
||||||
};
|
// This issue should be addressed once new network devices are added.
|
||||||
|
for callback_set in device_table.values() {
|
||||||
let can_send = {
|
let can_send = {
|
||||||
let mut device = callbacks.device.lock();
|
let mut device = callback_set.device.lock();
|
||||||
device.free_processed_tx_buffers();
|
device.free_processed_tx_buffers();
|
||||||
device.can_send()
|
device.can_send()
|
||||||
};
|
};
|
||||||
|
|
||||||
if !can_send {
|
if !can_send {
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let callbacks = callbacks.send_callbacks.lock();
|
let send_callbacks = callback_set.send_callbacks.lock();
|
||||||
for callback in callbacks.iter() {
|
for callback in send_callbacks.iter() {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Raises softirq for handling transmission events
|
||||||
|
pub fn raise_send_softirq() {
|
||||||
|
SoftIrqLine::get(NETWORK_TX_SOFTIRQ_ID).raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Raises softirq for handling reception events
|
||||||
|
pub fn raise_receive_softirq() {
|
||||||
|
SoftIrqLine::get(NETWORK_RX_SOFTIRQ_ID).raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_devices() -> Vec<(String, NetworkDeviceRef)> {
|
pub fn all_devices() -> Vec<(String, NetworkDeviceRef)> {
|
||||||
@ -148,33 +170,31 @@ pub fn all_devices() -> Vec<(String, NetworkDeviceRef)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static COMPONENT: Once<Component> = Once::new();
|
static COMPONENT: Once<Component> = Once::new();
|
||||||
pub(crate) static NETWORK_IRQ_HANDLERS: Once<
|
|
||||||
SpinLock<Vec<Arc<dyn NetDeviceIrqHandler>>, LocalIrqDisabled>,
|
|
||||||
> = Once::new();
|
|
||||||
|
|
||||||
#[init_component]
|
#[init_component]
|
||||||
fn init() -> Result<(), ComponentInitError> {
|
fn init() -> Result<(), ComponentInitError> {
|
||||||
let a = Component::init()?;
|
let a = Component::init()?;
|
||||||
COMPONENT.call_once(|| a);
|
COMPONENT.call_once(|| a);
|
||||||
NETWORK_IRQ_HANDLERS.call_once(|| SpinLock::new(Vec::new()));
|
SoftIrqLine::get(NETWORK_TX_SOFTIRQ_ID).enable(handle_tx_softirq);
|
||||||
|
SoftIrqLine::get(NETWORK_RX_SOFTIRQ_ID).enable(handle_rx_softirq);
|
||||||
buffer::init();
|
buffer::init();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetDeviceIrqHandlerListRef =
|
type NetDeviceCallbackListRef = Arc<SpinLock<Vec<Arc<dyn NetDeviceCallback>>, BottomHalfDisabled>>;
|
||||||
Arc<SpinLock<Vec<Arc<dyn NetDeviceIrqHandler>>, LocalIrqDisabled>>;
|
type NetworkDeviceRef = Arc<SpinLock<dyn AnyNetworkDevice, BottomHalfDisabled>>;
|
||||||
type NetworkDeviceRef = Arc<SpinLock<dyn AnyNetworkDevice, LocalIrqDisabled>>;
|
|
||||||
|
|
||||||
struct Component {
|
struct Component {
|
||||||
/// Device list, the key is device name, value is (callbacks, device);
|
/// Device list, the key is device name, value is (callbacks, device);
|
||||||
network_device_table: SpinLock<BTreeMap<String, NetworkDeviceIrqCallbackSet>, LocalIrqDisabled>,
|
network_device_table:
|
||||||
|
SpinLock<BTreeMap<String, NetworkDeviceIrqCallbackSet>, BottomHalfDisabled>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The send callbacks and recv callbacks for a network device
|
/// The send callbacks and recv callbacks for a network device
|
||||||
struct NetworkDeviceIrqCallbackSet {
|
struct NetworkDeviceIrqCallbackSet {
|
||||||
device: NetworkDeviceRef,
|
device: NetworkDeviceRef,
|
||||||
recv_callbacks: NetDeviceIrqHandlerListRef,
|
recv_callbacks: NetDeviceCallbackListRef,
|
||||||
send_callbacks: NetDeviceIrqHandlerListRef,
|
send_callbacks: NetDeviceCallbackListRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkDeviceIrqCallbackSet {
|
impl NetworkDeviceIrqCallbackSet {
|
||||||
|
@ -11,3 +11,9 @@ pub const TIMER_SOFTIRQ_ID: u8 = 1;
|
|||||||
|
|
||||||
/// The corresponding softirq line is used to schedule general taskless jobs.
|
/// The corresponding softirq line is used to schedule general taskless jobs.
|
||||||
pub const TASKLESS_SOFTIRQ_ID: u8 = 2;
|
pub const TASKLESS_SOFTIRQ_ID: u8 = 2;
|
||||||
|
|
||||||
|
/// The corresponding softirq line is used to handle transmission network events.
|
||||||
|
pub const NETWORK_TX_SOFTIRQ_ID: u8 = 3;
|
||||||
|
|
||||||
|
/// The corresponding softirq line is used to handle reception network events.
|
||||||
|
pub const NETWORK_RX_SOFTIRQ_ID: u8 = 4;
|
||||||
|
@ -15,6 +15,7 @@ aster-console = { path = "../console" }
|
|||||||
aster-util = { path = "../../libs/aster-util" }
|
aster-util = { path = "../../libs/aster-util" }
|
||||||
aster-rights = { path = "../../libs/aster-rights" }
|
aster-rights = { path = "../../libs/aster-rights" }
|
||||||
aster-bigtcp = { path = "../../libs/aster-bigtcp" }
|
aster-bigtcp = { path = "../../libs/aster-bigtcp" }
|
||||||
|
aster-softirq = { path = "../softirq"}
|
||||||
id-alloc = { path = "../../../ostd/libs/id-alloc" }
|
id-alloc = { path = "../../../ostd/libs/id-alloc" }
|
||||||
typeflags-util = { path = "../../libs/typeflags-util" }
|
typeflags-util = { path = "../../libs/typeflags-util" }
|
||||||
ostd = { path = "../../../ostd" }
|
ostd = { path = "../../../ostd" }
|
||||||
|
@ -9,13 +9,10 @@ use aster_bigtcp::device::{Checksum, DeviceCapabilities, Medium};
|
|||||||
use aster_network::{
|
use aster_network::{
|
||||||
AnyNetworkDevice, EthernetAddr, RxBuffer, TxBuffer, VirtioNetError, RX_BUFFER_POOL,
|
AnyNetworkDevice, EthernetAddr, RxBuffer, TxBuffer, VirtioNetError, RX_BUFFER_POOL,
|
||||||
};
|
};
|
||||||
|
use aster_softirq::BottomHalfDisabled;
|
||||||
use aster_util::slot_vec::SlotVec;
|
use aster_util::slot_vec::SlotVec;
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use ostd::{
|
use ostd::{mm::DmaStream, sync::SpinLock, trap::TrapFrame};
|
||||||
mm::DmaStream,
|
|
||||||
sync::{LocalIrqDisabled, SpinLock},
|
|
||||||
trap::TrapFrame,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{config::VirtioNetConfig, header::VirtioNetHdr};
|
use super::{config::VirtioNetConfig, header::VirtioNetHdr};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -127,10 +124,10 @@ impl NetworkDevice {
|
|||||||
|
|
||||||
/// Interrupt handlers if network device receives/sends some packet
|
/// Interrupt handlers if network device receives/sends some packet
|
||||||
fn handle_send_event(_: &TrapFrame) {
|
fn handle_send_event(_: &TrapFrame) {
|
||||||
aster_network::handle_send_irq(super::DEVICE_NAME);
|
aster_network::raise_send_softirq();
|
||||||
}
|
}
|
||||||
fn handle_recv_event(_: &TrapFrame) {
|
fn handle_recv_event(_: &TrapFrame) {
|
||||||
aster_network::handle_recv_irq(super::DEVICE_NAME);
|
aster_network::raise_receive_softirq();
|
||||||
}
|
}
|
||||||
|
|
||||||
device
|
device
|
||||||
@ -363,7 +360,7 @@ impl Debug for NetworkDevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TX_BUFFER_POOL: SpinLock<LinkedList<DmaStream>, LocalIrqDisabled> =
|
static TX_BUFFER_POOL: SpinLock<LinkedList<DmaStream>, BottomHalfDisabled> =
|
||||||
SpinLock::new(LinkedList::new());
|
SpinLock::new(LinkedList::new());
|
||||||
|
|
||||||
const QUEUE_RECV: u16 = 0;
|
const QUEUE_RECV: u16 = 0;
|
||||||
|
@ -3,15 +3,16 @@
|
|||||||
use alloc::{collections::linked_list::LinkedList, sync::Arc};
|
use alloc::{collections::linked_list::LinkedList, sync::Arc};
|
||||||
|
|
||||||
use aster_network::dma_pool::DmaPool;
|
use aster_network::dma_pool::DmaPool;
|
||||||
|
use aster_softirq::BottomHalfDisabled;
|
||||||
use ostd::{
|
use ostd::{
|
||||||
mm::{DmaDirection, DmaStream},
|
mm::{DmaDirection, DmaStream},
|
||||||
sync::{LocalIrqDisabled, SpinLock},
|
sync::SpinLock,
|
||||||
};
|
};
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
|
|
||||||
const RX_BUFFER_LEN: usize = 4096;
|
const RX_BUFFER_LEN: usize = 4096;
|
||||||
pub static RX_BUFFER_POOL: Once<Arc<DmaPool>> = Once::new();
|
pub static RX_BUFFER_POOL: Once<Arc<DmaPool>> = Once::new();
|
||||||
pub static TX_BUFFER_POOL: Once<SpinLock<LinkedList<DmaStream>, LocalIrqDisabled>> = Once::new();
|
pub static TX_BUFFER_POOL: Once<SpinLock<LinkedList<DmaStream>, BottomHalfDisabled>> = Once::new();
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
const POOL_INIT_SIZE: usize = 32;
|
const POOL_INIT_SIZE: usize = 32;
|
||||||
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
aster-softirq = { path = "../../comps/softirq" }
|
||||||
bitflags = "1.3"
|
bitflags = "1.3"
|
||||||
jhash = { path = "../jhash" }
|
jhash = { path = "../jhash" }
|
||||||
ostd = { path = "../../../ostd" }
|
ostd = { path = "../../../ostd" }
|
||||||
|
@ -7,7 +7,8 @@ use alloc::{
|
|||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ostd::sync::{LocalIrqDisabled, SpinLock, SpinLockGuard};
|
use aster_softirq::BottomHalfDisabled;
|
||||||
|
use ostd::sync::{SpinLock, SpinLockGuard};
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::{packet::Packet, Context},
|
iface::{packet::Packet, Context},
|
||||||
phy::Device,
|
phy::Device,
|
||||||
@ -30,9 +31,9 @@ use crate::{
|
|||||||
|
|
||||||
pub struct IfaceCommon<E: Ext> {
|
pub struct IfaceCommon<E: Ext> {
|
||||||
name: String,
|
name: String,
|
||||||
interface: SpinLock<PollableIface<E>, LocalIrqDisabled>,
|
interface: SpinLock<PollableIface<E>, BottomHalfDisabled>,
|
||||||
used_ports: SpinLock<BTreeMap<u16, usize>, LocalIrqDisabled>,
|
used_ports: SpinLock<BTreeMap<u16, usize>, BottomHalfDisabled>,
|
||||||
sockets: SpinLock<SocketTable<E>, LocalIrqDisabled>,
|
sockets: SpinLock<SocketTable<E>, BottomHalfDisabled>,
|
||||||
sched_poll: E::ScheduleNextPoll,
|
sched_poll: E::ScheduleNextPoll,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,12 +68,12 @@ impl<E: Ext> IfaceCommon<E> {
|
|||||||
// Lock order: `interface` -> `sockets`
|
// Lock order: `interface` -> `sockets`
|
||||||
impl<E: Ext> IfaceCommon<E> {
|
impl<E: Ext> IfaceCommon<E> {
|
||||||
/// Acquires the lock to the interface.
|
/// Acquires the lock to the interface.
|
||||||
pub(crate) fn interface(&self) -> SpinLockGuard<'_, PollableIface<E>, LocalIrqDisabled> {
|
pub(crate) fn interface(&self) -> SpinLockGuard<'_, PollableIface<E>, BottomHalfDisabled> {
|
||||||
self.interface.lock()
|
self.interface.lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Acquires the lock to the socket table.
|
/// Acquires the lock to the socket table.
|
||||||
pub(crate) fn sockets(&self) -> SpinLockGuard<'_, SocketTable<E>, LocalIrqDisabled> {
|
pub(crate) fn sockets(&self) -> SpinLockGuard<'_, SocketTable<E>, BottomHalfDisabled> {
|
||||||
self.sockets.lock()
|
self.sockets.lock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
use alloc::{collections::btree_map::BTreeMap, string::String, sync::Arc};
|
use alloc::{collections::btree_map::BTreeMap, string::String, sync::Arc};
|
||||||
|
|
||||||
use ostd::sync::{LocalIrqDisabled, SpinLock};
|
use aster_softirq::BottomHalfDisabled;
|
||||||
|
use ostd::sync::SpinLock;
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::{packet::Packet, Config, Context},
|
iface::{packet::Packet, Config, Context},
|
||||||
phy::{DeviceCapabilities, TxToken},
|
phy::{DeviceCapabilities, TxToken},
|
||||||
@ -25,7 +26,7 @@ pub struct EtherIface<D, E: Ext> {
|
|||||||
driver: D,
|
driver: D,
|
||||||
common: IfaceCommon<E>,
|
common: IfaceCommon<E>,
|
||||||
ether_addr: EthernetAddress,
|
ether_addr: EthernetAddress,
|
||||||
arp_table: SpinLock<BTreeMap<Ipv4Address, EthernetAddress>, LocalIrqDisabled>,
|
arp_table: SpinLock<BTreeMap<Ipv4Address, EthernetAddress>, BottomHalfDisabled>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: WithDevice, E: Ext> EtherIface<D, E> {
|
impl<D: WithDevice, E: Ext> EtherIface<D, E> {
|
||||||
|
@ -6,7 +6,8 @@ use alloc::{
|
|||||||
};
|
};
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use ostd::sync::{LocalIrqDisabled, SpinLock, SpinLockGuard};
|
use aster_softirq::BottomHalfDisabled;
|
||||||
|
use ostd::sync::{SpinLock, SpinLockGuard};
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
socket::{tcp::State, PollAt},
|
socket::{tcp::State, PollAt},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
@ -34,7 +35,7 @@ pub type TcpConnection<E> = Socket<TcpConnectionInner<E>, E>;
|
|||||||
|
|
||||||
/// States needed by [`TcpConnectionBg`].
|
/// States needed by [`TcpConnectionBg`].
|
||||||
pub struct TcpConnectionInner<E: Ext> {
|
pub struct TcpConnectionInner<E: Ext> {
|
||||||
socket: SpinLock<RawTcpSocketExt<E>, LocalIrqDisabled>,
|
socket: SpinLock<RawTcpSocketExt<E>, BottomHalfDisabled>,
|
||||||
poll_key: PollKey,
|
poll_key: PollKey,
|
||||||
connection_key: ConnectionKey,
|
connection_key: ConnectionKey,
|
||||||
}
|
}
|
||||||
@ -243,7 +244,7 @@ impl<E: Ext> TcpConnectionInner<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn lock(&self) -> SpinLockGuard<RawTcpSocketExt<E>, LocalIrqDisabled> {
|
pub(super) fn lock(&self) -> SpinLockGuard<RawTcpSocketExt<E>, BottomHalfDisabled> {
|
||||||
self.socket.lock()
|
self.socket.lock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
use alloc::{boxed::Box, collections::btree_map::BTreeMap, sync::Arc, vec::Vec};
|
use alloc::{boxed::Box, collections::btree_map::BTreeMap, sync::Arc, vec::Vec};
|
||||||
|
|
||||||
use ostd::sync::{LocalIrqDisabled, SpinLock};
|
use aster_softirq::BottomHalfDisabled;
|
||||||
|
use ostd::sync::SpinLock;
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
socket::PollAt,
|
socket::PollAt,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
@ -35,7 +36,7 @@ pub struct TcpBacklog<E: Ext> {
|
|||||||
|
|
||||||
/// States needed by [`TcpListenerBg`].
|
/// States needed by [`TcpListenerBg`].
|
||||||
pub struct TcpListenerInner<E: Ext> {
|
pub struct TcpListenerInner<E: Ext> {
|
||||||
pub(super) backlog: SpinLock<TcpBacklog<E>, LocalIrqDisabled>,
|
pub(super) backlog: SpinLock<TcpBacklog<E>, BottomHalfDisabled>,
|
||||||
listener_key: ListenerKey,
|
listener_key: ListenerKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
use alloc::{boxed::Box, sync::Arc};
|
use alloc::{boxed::Box, sync::Arc};
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
use ostd::sync::{LocalIrqDisabled, SpinLock};
|
use aster_softirq::BottomHalfDisabled;
|
||||||
|
use ostd::sync::SpinLock;
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::Context,
|
iface::Context,
|
||||||
socket::udp::UdpMetadata,
|
socket::udp::UdpMetadata,
|
||||||
@ -22,7 +23,7 @@ pub type UdpSocket<E> = Socket<UdpSocketInner, E>;
|
|||||||
|
|
||||||
/// States needed by [`UdpSocketBg`].
|
/// States needed by [`UdpSocketBg`].
|
||||||
pub struct UdpSocketInner {
|
pub struct UdpSocketInner {
|
||||||
socket: SpinLock<Box<RawUdpSocket>, LocalIrqDisabled>,
|
socket: SpinLock<Box<RawUdpSocket>, BottomHalfDisabled>,
|
||||||
need_dispatch: AtomicBool,
|
need_dispatch: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use alloc::{borrow::ToOwned, sync::Arc};
|
use alloc::{borrow::ToOwned, sync::Arc};
|
||||||
|
|
||||||
use aster_bigtcp::device::WithDevice;
|
use aster_bigtcp::device::WithDevice;
|
||||||
use ostd::sync::LocalIrqDisabled;
|
use aster_softirq::BottomHalfDisabled;
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
|
|
||||||
use super::{poll::poll_ifaces, Iface};
|
use super::{poll::poll_ifaces, Iface};
|
||||||
@ -52,7 +52,7 @@ fn new_virtio() -> Option<Arc<Iface>> {
|
|||||||
|
|
||||||
let ether_addr = virtio_net.lock().mac_addr().0;
|
let ether_addr = virtio_net.lock().mac_addr().0;
|
||||||
|
|
||||||
struct Wrapper(Arc<SpinLock<dyn AnyNetworkDevice, LocalIrqDisabled>>);
|
struct Wrapper(Arc<SpinLock<dyn AnyNetworkDevice, BottomHalfDisabled>>);
|
||||||
|
|
||||||
impl WithDevice for Wrapper {
|
impl WithDevice for Wrapper {
|
||||||
type Device = dyn AnyNetworkDevice;
|
type Device = dyn AnyNetworkDevice;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user