mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
feat(net): 引入kthread,将Inet-网卡处理流程移入内核线程中
This commit is contained in:
parent
8fef80f8ed
commit
2452957cf4
@ -1,14 +1,10 @@
|
|||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::exception::{
|
||||||
exception::{
|
irqdata::IrqHandlerData,
|
||||||
irqdata::IrqHandlerData,
|
irqdesc::{IrqHandler, IrqReturn},
|
||||||
irqdesc::{IrqHandler, IrqReturn},
|
IrqNumber,
|
||||||
IrqNumber,
|
|
||||||
},
|
|
||||||
// net::net_core::poll_ifaces_try_lock_onetime,
|
|
||||||
net::net_core::poll_ifaces,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 默认的网卡中断处理函数
|
/// 默认的网卡中断处理函数
|
||||||
@ -22,8 +18,7 @@ impl IrqHandler for DefaultNetIrqHandler {
|
|||||||
_static_data: Option<&dyn IrqHandlerData>,
|
_static_data: Option<&dyn IrqHandlerData>,
|
||||||
_dynamic_data: Option<Arc<dyn IrqHandlerData>>,
|
_dynamic_data: Option<Arc<dyn IrqHandlerData>>,
|
||||||
) -> Result<IrqReturn, SystemError> {
|
) -> Result<IrqReturn, SystemError> {
|
||||||
// poll_ifaces_try_lock_onetime().ok();
|
super::kthread::wakeup_poll_thread();
|
||||||
poll_ifaces();
|
|
||||||
Ok(IrqReturn::Handled)
|
Ok(IrqReturn::Handled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
47
kernel/src/driver/net/kthread.rs
Normal file
47
kernel/src/driver/net/kthread.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use alloc::borrow::ToOwned;
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
use unified_init::macros::unified_init;
|
||||||
|
|
||||||
|
use crate::arch::CurrentIrqArch;
|
||||||
|
use crate::exception::InterruptArch;
|
||||||
|
use crate::init::initcall::INITCALL_SUBSYS;
|
||||||
|
use crate::net::NET_DEVICES;
|
||||||
|
use crate::process::kthread::{KernelThreadClosure, KernelThreadMechanism};
|
||||||
|
use crate::process::{ProcessControlBlock, ProcessManager};
|
||||||
|
use crate::sched::{schedule, SchedMode};
|
||||||
|
|
||||||
|
static mut NET_POLL_THREAD: Option<Arc<ProcessControlBlock>> = None;
|
||||||
|
|
||||||
|
#[unified_init(INITCALL_SUBSYS)]
|
||||||
|
pub fn net_poll_init() -> Result<(), system_error::SystemError> {
|
||||||
|
let closure = KernelThreadClosure::StaticEmptyClosure((&(net_poll_thread as fn() -> i32), ()));
|
||||||
|
let pcb = KernelThreadMechanism::create_and_run(closure, "net_poll".to_owned())
|
||||||
|
.ok_or("")
|
||||||
|
.expect("create net_poll thread failed");
|
||||||
|
log::info!("net_poll thread created");
|
||||||
|
unsafe {
|
||||||
|
NET_POLL_THREAD = Some(pcb);
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn net_poll_thread() -> i32 {
|
||||||
|
log::info!("net_poll thread started");
|
||||||
|
loop {
|
||||||
|
for (_, iface) in NET_DEVICES.read_irqsave().iter() {
|
||||||
|
iface.poll();
|
||||||
|
}
|
||||||
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
|
ProcessManager::mark_sleep(true).expect("clocksource_watchdog_kthread:mark sleep failed");
|
||||||
|
drop(irq_guard);
|
||||||
|
schedule(SchedMode::SM_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 拉起线程
|
||||||
|
pub(super) fn wakeup_poll_thread() {
|
||||||
|
if unsafe { NET_POLL_THREAD.is_none() } {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let _ = ProcessManager::wakeup(unsafe { NET_POLL_THREAD.as_ref().unwrap() });
|
||||||
|
}
|
@ -14,6 +14,7 @@ pub mod class;
|
|||||||
mod dma;
|
mod dma;
|
||||||
pub mod e1000e;
|
pub mod e1000e;
|
||||||
pub mod irq_handle;
|
pub mod irq_handle;
|
||||||
|
pub mod kthread;
|
||||||
pub mod loopback;
|
pub mod loopback;
|
||||||
pub mod sysfs;
|
pub mod sysfs;
|
||||||
pub mod virtio_net;
|
pub mod virtio_net;
|
||||||
|
@ -47,7 +47,7 @@ use crate::{
|
|||||||
rwlock::{RwLockReadGuard, RwLockWriteGuard},
|
rwlock::{RwLockReadGuard, RwLockWriteGuard},
|
||||||
spinlock::{SpinLock, SpinLockGuard},
|
spinlock::{SpinLock, SpinLockGuard},
|
||||||
},
|
},
|
||||||
net::{generate_iface_id, net_core::poll_ifaces, NET_DEVICES},
|
net::{generate_iface_id, NET_DEVICES},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
@ -263,8 +263,7 @@ impl Device for VirtIONetDevice {
|
|||||||
|
|
||||||
impl VirtIODevice for VirtIONetDevice {
|
impl VirtIODevice for VirtIONetDevice {
|
||||||
fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
|
fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
|
||||||
// log::warn!("VirtioInterface: poll_ifaces_try_lock_onetime -> poll_ifaces");
|
super::kthread::wakeup_poll_thread();
|
||||||
poll_ifaces();
|
|
||||||
return Ok(IrqReturn::Handled);
|
return Ok(IrqReturn::Handled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
use alloc::{collections::BTreeMap, sync::Arc};
|
|
||||||
use log::{debug, info, warn};
|
|
||||||
use smoltcp::{socket::dhcpv4, wire};
|
use smoltcp::{socket::dhcpv4, wire};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
driver::net::{Iface, Operstate},
|
driver::net::Operstate,
|
||||||
libs::rwlock::RwLockReadGuard,
|
|
||||||
net::NET_DEVICES,
|
net::NET_DEVICES,
|
||||||
time::{sleep::nanosleep, PosixTimeSpec},
|
time::{sleep::nanosleep, PosixTimeSpec},
|
||||||
};
|
};
|
||||||
@ -86,7 +83,7 @@ fn dhcp_query() -> Result<(), SystemError> {
|
|||||||
if let Some(cidr) = cidr {
|
if let Some(cidr) = cidr {
|
||||||
// 这里先在这里将网卡设置为up,后面等netlink实现了再修改
|
// 这里先在这里将网卡设置为up,后面等netlink实现了再修改
|
||||||
net_face.set_operstate(Operstate::IF_OPER_UP);
|
net_face.set_operstate(Operstate::IF_OPER_UP);
|
||||||
info!("Successfully allocated ip by Dhcpv4! Ip:{}", cidr);
|
log::info!("Successfully allocated ip by Dhcpv4! Ip:{}", cidr);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -99,7 +96,7 @@ fn dhcp_query() -> Result<(), SystemError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Some(dhcpv4::Event::Deconfigured) => {
|
Some(dhcpv4::Event::Deconfigured) => {
|
||||||
debug!("Dhcp v4 deconfigured");
|
log::debug!("Dhcp v4 deconfigured");
|
||||||
net_face
|
net_face
|
||||||
.update_ip_addrs(&[smoltcp::wire::IpCidr::Ipv4(wire::Ipv4Cidr::new(
|
.update_ip_addrs(&[smoltcp::wire::IpCidr::Ipv4(wire::Ipv4Cidr::new(
|
||||||
wire::Ipv4Address::UNSPECIFIED,
|
wire::Ipv4Address::UNSPECIFIED,
|
||||||
@ -125,15 +122,3 @@ fn dhcp_query() -> Result<(), SystemError> {
|
|||||||
|
|
||||||
return Err(SystemError::ETIMEDOUT);
|
return Err(SystemError::ETIMEDOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_ifaces() {
|
|
||||||
// log::debug!("poll_ifaces");
|
|
||||||
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn Iface>>> = NET_DEVICES.read_irqsave();
|
|
||||||
if guard.len() == 0 {
|
|
||||||
warn!("poll_ifaces: No net driver found!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (_, iface) in guard.iter() {
|
|
||||||
iface.poll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -53,11 +53,11 @@ impl BoundInner {
|
|||||||
})
|
})
|
||||||
.expect("No default interface");
|
.expect("No default interface");
|
||||||
|
|
||||||
let handle = iface.sockets().lock_irqsave().add(socket);
|
let handle = iface.sockets().lock().add(socket);
|
||||||
return Ok(Self { handle, iface });
|
return Ok(Self { handle, iface });
|
||||||
} else {
|
} else {
|
||||||
let iface = get_iface_to_bind(address).ok_or(SystemError::ENODEV)?;
|
let iface = get_iface_to_bind(address).ok_or(SystemError::ENODEV)?;
|
||||||
let handle = iface.sockets().lock_irqsave().add(socket);
|
let handle = iface.sockets().lock().add(socket);
|
||||||
return Ok(Self { handle, iface });
|
return Ok(Self { handle, iface });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ impl BoundInner {
|
|||||||
{
|
{
|
||||||
let (iface, address) = get_ephemeral_iface(&remote);
|
let (iface, address) = get_ephemeral_iface(&remote);
|
||||||
// let bound_port = iface.port_manager().bind_ephemeral_port(socket_type)?;
|
// let bound_port = iface.port_manager().bind_ephemeral_port(socket_type)?;
|
||||||
let handle = iface.sockets().lock_no_preempt().add(socket);
|
let handle = iface.sockets().lock().add(socket);
|
||||||
// let endpoint = smoltcp::wire::IpEndpoint::new(local_addr, bound_port);
|
// let endpoint = smoltcp::wire::IpEndpoint::new(local_addr, bound_port);
|
||||||
Ok((Self { handle, iface }, address))
|
Ok((Self { handle, iface }, address))
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ use system_error::SystemError;
|
|||||||
|
|
||||||
use crate::libs::wait_queue::WaitQueue;
|
use crate::libs::wait_queue::WaitQueue;
|
||||||
use crate::net::event_poll::EPollEventType;
|
use crate::net::event_poll::EPollEventType;
|
||||||
use crate::net::net_core::poll_ifaces;
|
|
||||||
use crate::net::socket::{Socket, PMSG};
|
use crate::net::socket::{Socket, PMSG};
|
||||||
use crate::{libs::rwlock::RwLock, net::socket::endpoint::Endpoint};
|
use crate::{libs::rwlock::RwLock, net::socket::endpoint::Endpoint};
|
||||||
use alloc::sync::{Arc, Weak};
|
use alloc::sync::{Arc, Weak};
|
||||||
@ -89,7 +88,7 @@ impl UdpSocket {
|
|||||||
match self.inner.read().as_ref().expect("Udp Inner is None") {
|
match self.inner.read().as_ref().expect("Udp Inner is None") {
|
||||||
UdpInner::Bound(bound) => {
|
UdpInner::Bound(bound) => {
|
||||||
let ret = bound.try_recv(buf);
|
let ret = bound.try_recv(buf);
|
||||||
poll_ifaces();
|
bound.inner().iface().poll();
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
_ => Err(SystemError::ENOTCONN),
|
_ => Err(SystemError::ENOTCONN),
|
||||||
@ -125,10 +124,13 @@ impl UdpSocket {
|
|||||||
};
|
};
|
||||||
// Optimize: 拿两次锁的平均效率是否比一次长时间的读锁效率要高?
|
// Optimize: 拿两次锁的平均效率是否比一次长时间的读锁效率要高?
|
||||||
let result = match self.inner.read().as_ref().expect("Udp Inner is None") {
|
let result = match self.inner.read().as_ref().expect("Udp Inner is None") {
|
||||||
UdpInner::Bound(bound) => bound.try_send(buf, to),
|
UdpInner::Bound(bound) => {
|
||||||
|
let ret = bound.try_send(buf, to);
|
||||||
|
bound.inner().iface().poll();
|
||||||
|
ret
|
||||||
|
}
|
||||||
_ => Err(SystemError::ENOTCONN),
|
_ => Err(SystemError::ENOTCONN),
|
||||||
};
|
};
|
||||||
poll_ifaces();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ impl Connecting {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_result(self) -> (Inner, Result<(), SystemError>) {
|
pub fn into_result(self) -> (Inner, Result<(), SystemError>) {
|
||||||
let result = *self.result.read_irqsave();
|
let result = *self.result.read();
|
||||||
match result {
|
match result {
|
||||||
ConnectResult::Connecting => (
|
ConnectResult::Connecting => (
|
||||||
Inner::Connecting(self),
|
Inner::Connecting(self),
|
||||||
@ -245,7 +245,7 @@ impl Connecting {
|
|||||||
|
|
||||||
self.inner
|
self.inner
|
||||||
.with_mut(|socket: &mut smoltcp::socket::tcp::Socket| {
|
.with_mut(|socket: &mut smoltcp::socket::tcp::Socket| {
|
||||||
let mut result = self.result.write_irqsave();
|
let mut result = self.result.write();
|
||||||
if matches!(*result, ConnectResult::Refused | ConnectResult::Connected) {
|
if matches!(*result, ConnectResult::Refused | ConnectResult::Connected) {
|
||||||
return false; // Already connected or refused
|
return false; // Already connected or refused
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user