From 2452957cf43ff2e1c45da0009e480957045c7168 Mon Sep 17 00:00:00 2001 From: Samuka007 Date: Wed, 9 Apr 2025 12:12:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(net):=20=E5=BC=95=E5=85=A5kthread=EF=BC=8C?= =?UTF-8?q?=E5=B0=86Inet-=E7=BD=91=E5=8D=A1=E5=A4=84=E7=90=86=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E7=A7=BB=E5=85=A5=E5=86=85=E6=A0=B8=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/driver/net/irq_handle.rs | 15 +++---- kernel/src/driver/net/kthread.rs | 47 ++++++++++++++++++++++ kernel/src/driver/net/mod.rs | 1 + kernel/src/driver/net/virtio_net.rs | 5 +-- kernel/src/net/net_core.rs | 21 ++-------- kernel/src/net/socket/inet/common/mod.rs | 6 +-- kernel/src/net/socket/inet/datagram/mod.rs | 10 +++-- kernel/src/net/socket/inet/stream/inner.rs | 4 +- 8 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 kernel/src/driver/net/kthread.rs diff --git a/kernel/src/driver/net/irq_handle.rs b/kernel/src/driver/net/irq_handle.rs index bdc3942d..5a6cd0db 100644 --- a/kernel/src/driver/net/irq_handle.rs +++ b/kernel/src/driver/net/irq_handle.rs @@ -1,14 +1,10 @@ use alloc::sync::Arc; use system_error::SystemError; -use crate::{ - exception::{ - irqdata::IrqHandlerData, - irqdesc::{IrqHandler, IrqReturn}, - IrqNumber, - }, - // net::net_core::poll_ifaces_try_lock_onetime, - net::net_core::poll_ifaces, +use crate::exception::{ + irqdata::IrqHandlerData, + irqdesc::{IrqHandler, IrqReturn}, + IrqNumber, }; /// 默认的网卡中断处理函数 @@ -22,8 +18,7 @@ impl IrqHandler for DefaultNetIrqHandler { _static_data: Option<&dyn IrqHandlerData>, _dynamic_data: Option>, ) -> Result { - // poll_ifaces_try_lock_onetime().ok(); - poll_ifaces(); + super::kthread::wakeup_poll_thread(); Ok(IrqReturn::Handled) } } diff --git a/kernel/src/driver/net/kthread.rs b/kernel/src/driver/net/kthread.rs new file mode 100644 index 00000000..3c634499 --- /dev/null +++ b/kernel/src/driver/net/kthread.rs @@ -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> = 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() }); +} diff --git a/kernel/src/driver/net/mod.rs b/kernel/src/driver/net/mod.rs index 4b3cfe0f..c9d02653 100644 --- a/kernel/src/driver/net/mod.rs +++ b/kernel/src/driver/net/mod.rs @@ -14,6 +14,7 @@ pub mod class; mod dma; pub mod e1000e; pub mod irq_handle; +pub mod kthread; pub mod loopback; pub mod sysfs; pub mod virtio_net; diff --git a/kernel/src/driver/net/virtio_net.rs b/kernel/src/driver/net/virtio_net.rs index 27d544ec..307a3a05 100644 --- a/kernel/src/driver/net/virtio_net.rs +++ b/kernel/src/driver/net/virtio_net.rs @@ -47,7 +47,7 @@ use crate::{ rwlock::{RwLockReadGuard, RwLockWriteGuard}, spinlock::{SpinLock, SpinLockGuard}, }, - net::{generate_iface_id, net_core::poll_ifaces, NET_DEVICES}, + net::{generate_iface_id, NET_DEVICES}, time::Instant, }; use system_error::SystemError; @@ -263,8 +263,7 @@ impl Device for VirtIONetDevice { impl VirtIODevice for VirtIONetDevice { fn handle_irq(&self, _irq: IrqNumber) -> Result { - // log::warn!("VirtioInterface: poll_ifaces_try_lock_onetime -> poll_ifaces"); - poll_ifaces(); + super::kthread::wakeup_poll_thread(); return Ok(IrqReturn::Handled); } diff --git a/kernel/src/net/net_core.rs b/kernel/src/net/net_core.rs index 9038e7de..c62badc0 100644 --- a/kernel/src/net/net_core.rs +++ b/kernel/src/net/net_core.rs @@ -1,11 +1,8 @@ -use alloc::{collections::BTreeMap, sync::Arc}; -use log::{debug, info, warn}; use smoltcp::{socket::dhcpv4, wire}; use system_error::SystemError; use crate::{ - driver::net::{Iface, Operstate}, - libs::rwlock::RwLockReadGuard, + driver::net::Operstate, net::NET_DEVICES, time::{sleep::nanosleep, PosixTimeSpec}, }; @@ -86,7 +83,7 @@ fn dhcp_query() -> Result<(), SystemError> { if let Some(cidr) = cidr { // 这里先在这里将网卡设置为up,后面等netlink实现了再修改 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(()); } } else { @@ -99,7 +96,7 @@ fn dhcp_query() -> Result<(), SystemError> { } Some(dhcpv4::Event::Deconfigured) => { - debug!("Dhcp v4 deconfigured"); + log::debug!("Dhcp v4 deconfigured"); net_face .update_ip_addrs(&[smoltcp::wire::IpCidr::Ipv4(wire::Ipv4Cidr::new( wire::Ipv4Address::UNSPECIFIED, @@ -125,15 +122,3 @@ fn dhcp_query() -> Result<(), SystemError> { return Err(SystemError::ETIMEDOUT); } - -pub fn poll_ifaces() { - // log::debug!("poll_ifaces"); - let guard: RwLockReadGuard>> = NET_DEVICES.read_irqsave(); - if guard.len() == 0 { - warn!("poll_ifaces: No net driver found!"); - return; - } - for (_, iface) in guard.iter() { - iface.poll(); - } -} diff --git a/kernel/src/net/socket/inet/common/mod.rs b/kernel/src/net/socket/inet/common/mod.rs index 581e1269..8b60c071 100644 --- a/kernel/src/net/socket/inet/common/mod.rs +++ b/kernel/src/net/socket/inet/common/mod.rs @@ -53,11 +53,11 @@ impl BoundInner { }) .expect("No default interface"); - let handle = iface.sockets().lock_irqsave().add(socket); + let handle = iface.sockets().lock().add(socket); return Ok(Self { handle, iface }); } else { 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 }); } } @@ -72,7 +72,7 @@ impl BoundInner { { let (iface, address) = get_ephemeral_iface(&remote); // 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); Ok((Self { handle, iface }, address)) } diff --git a/kernel/src/net/socket/inet/datagram/mod.rs b/kernel/src/net/socket/inet/datagram/mod.rs index b98b87ee..594457c5 100644 --- a/kernel/src/net/socket/inet/datagram/mod.rs +++ b/kernel/src/net/socket/inet/datagram/mod.rs @@ -4,7 +4,6 @@ use system_error::SystemError; use crate::libs::wait_queue::WaitQueue; use crate::net::event_poll::EPollEventType; -use crate::net::net_core::poll_ifaces; use crate::net::socket::{Socket, PMSG}; use crate::{libs::rwlock::RwLock, net::socket::endpoint::Endpoint}; use alloc::sync::{Arc, Weak}; @@ -89,7 +88,7 @@ impl UdpSocket { match self.inner.read().as_ref().expect("Udp Inner is None") { UdpInner::Bound(bound) => { let ret = bound.try_recv(buf); - poll_ifaces(); + bound.inner().iface().poll(); ret } _ => Err(SystemError::ENOTCONN), @@ -125,10 +124,13 @@ impl UdpSocket { }; // Optimize: 拿两次锁的平均效率是否比一次长时间的读锁效率要高? 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), }; - poll_ifaces(); return result; } diff --git a/kernel/src/net/socket/inet/stream/inner.rs b/kernel/src/net/socket/inet/stream/inner.rs index b9252f24..bda841a4 100644 --- a/kernel/src/net/socket/inet/stream/inner.rs +++ b/kernel/src/net/socket/inet/stream/inner.rs @@ -211,7 +211,7 @@ impl Connecting { } pub fn into_result(self) -> (Inner, Result<(), SystemError>) { - let result = *self.result.read_irqsave(); + let result = *self.result.read(); match result { ConnectResult::Connecting => ( Inner::Connecting(self), @@ -245,7 +245,7 @@ impl Connecting { self.inner .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) { return false; // Already connected or refused }