Move network polling code to bottom half

This commit is contained in:
jiangjianfeng 2025-02-20 07:00:53 +00:00 committed by Tate, Hongliang Tian
parent 9804f053f2
commit 7d24e63216
16 changed files with 122 additions and 85 deletions

3
Cargo.lock generated
View File

@ -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",

View File

@ -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" }

View File

@ -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();

View File

@ -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();

View File

@ -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,39 +115,52 @@ 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 mut device = callback_set.device.lock();
device.free_processed_tx_buffers();
device.can_send()
};
let can_send = { if !can_send {
let mut device = callbacks.device.lock(); continue;
device.free_processed_tx_buffers(); }
device.can_send()
};
if !can_send {
return;
}
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)> {
let network_devs = COMPONENT.get().unwrap().network_device_table.lock(); let network_devs = COMPONENT.get().unwrap().network_device_table.lock();
network_devs network_devs
@ -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 {

View File

@ -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;

View File

@ -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" }

View File

@ -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;

View File

@ -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;

View File

@ -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" }

View File

@ -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()
} }
} }

View File

@ -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> {

View File

@ -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()
} }
} }

View File

@ -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,
} }

View File

@ -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,
} }

View File

@ -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;