Skip to content

Commit 9c652d1

Browse files
committed
WIP
1 parent f250a72 commit 9c652d1

File tree

7 files changed

+59
-46
lines changed

7 files changed

+59
-46
lines changed

src/arch/aarch64/kernel/interrupts.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use crate::drivers::mmio::get_interrupt_handlers;
2222
#[cfg(feature = "pci")]
2323
use crate::drivers::pci::get_interrupt_handlers;
2424
use crate::drivers::{InterruptHandlerQueue, InterruptLine};
25+
#[cfg(feature = "net")]
26+
use crate::executor::network::NETWORK_WAKER;
2527
use crate::kernel::serial::handle_uart_interrupt;
2628
use crate::mm::{PageAlloc, PageRangeAllocator};
2729
use crate::scheduler::{self, CoreId};
@@ -94,6 +96,11 @@ pub(crate) fn install_handlers() {
9496
fn timer_handler() {
9597
debug!("Handle timer interrupt");
9698

99+
// FIXME this is ugly as hell
100+
debug!("Waking network waker");
101+
#[cfg(feature = "net")]
102+
NETWORK_WAKER.lock().wake();
103+
97104
// disable timer
98105
CNTP_CVAL_EL0.set(0);
99106
CNTP_CTL_EL0.write(CNTP_CTL_EL0::ENABLE::CLEAR);

src/drivers/net/gem.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use crate::drivers::net::{NetworkDriver, mtu};
3232
#[cfg(feature = "pci")]
3333
use crate::drivers::pci as hardware;
3434
use crate::drivers::{Driver, InterruptLine};
35+
use crate::executor::network::NETWORK_WAKER;
3536
use crate::mm::device_alloc::DeviceAlloc;
3637
use crate::{BasePageSize, PageSize};
3738

@@ -276,6 +277,9 @@ impl NetworkDriver for GEMDriver {
276277

277278
fn handle_interrupt(&mut self) {
278279
self.tx_fields.handle_interrupt();
280+
281+
debug!("Waking network waker");
282+
NETWORK_WAKER.lock().wake();
279283
}
280284
}
281285

src/drivers/net/virtio/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use crate::drivers::virtio::virtqueue::{
4141
AvailBufferToken, BufferElem, BufferType, UsedBufferToken, VirtQueue, Virtq,
4242
};
4343
use crate::drivers::{Driver, InterruptLine};
44+
use crate::executor::network::{NETWORK_WAKER, NIC};
4445
use crate::mm::device_alloc::DeviceAlloc;
4546

4647
/// A wrapper struct for the raw configuration structure.
@@ -415,7 +416,14 @@ impl NetworkDriver for VirtioNetDriver<Init> {
415416
todo!("Implement possibility to change config on the fly...")
416417
}
417418

419+
error!("virtio interrupt");
420+
418421
self.isr_stat.acknowledge();
422+
423+
debug!("Waking network waker");
424+
NETWORK_WAKER.lock().wake();
425+
426+
error!("meow after");
419427
}
420428
}
421429

src/executor/mod.rs

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -155,48 +155,12 @@ where
155155

156156
let now = crate::arch::kernel::systemtime::now_micros();
157157
if let Poll::Ready(t) = result {
158-
// allow network interrupts
159-
#[cfg(feature = "net")]
160-
{
161-
if let Some(mut guard) = crate::executor::network::NIC.try_lock() {
162-
let delay = if let Ok(nic) = guard.as_nic_mut() {
163-
nic.set_polling_mode(false);
164-
165-
nic.poll_delay(Instant::from_micros_const(now.try_into().unwrap()))
166-
.map(|d| d.total_micros())
167-
} else {
168-
None
169-
};
170-
core_local::core_scheduler().add_network_timer(
171-
delay.map(|d| crate::arch::processor::get_timer_ticks() + d),
172-
);
173-
}
174-
}
175-
176158
return t;
177159
}
178160

179161
if let Some(duration) = timeout
180162
&& Duration::from_micros(now - start) >= duration
181163
{
182-
// allow network interrupts
183-
#[cfg(feature = "net")]
184-
{
185-
if let Some(mut guard) = crate::executor::network::NIC.try_lock() {
186-
let delay = if let Ok(nic) = guard.as_nic_mut() {
187-
nic.set_polling_mode(false);
188-
189-
nic.poll_delay(Instant::from_micros_const(now.try_into().unwrap()))
190-
.map(|d| d.total_micros())
191-
} else {
192-
None
193-
};
194-
core_local::core_scheduler().add_network_timer(
195-
delay.map(|d| crate::arch::processor::get_timer_ticks() + d),
196-
);
197-
}
198-
}
199-
200164
return Err(Errno::Time);
201165
}
202166

@@ -227,7 +191,7 @@ where
227191

228192
// restore default values
229193
if let Ok(nic) = crate::executor::network::NIC.lock().as_nic_mut() {
230-
nic.set_polling_mode(true);
194+
//nic.set_polling_mode(true);
231195
}
232196

233197
backoff.reset();

src/executor/network.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::arch;
2626
use crate::drivers::net::{NetworkDevice, NetworkDriver};
2727
#[cfg(feature = "dns")]
2828
use crate::errno::Errno;
29-
use crate::executor::spawn;
29+
use crate::executor::{WakerRegistration, spawn};
3030
#[cfg(feature = "dns")]
3131
use crate::io;
3232
use crate::scheduler::PerCoreSchedulerExt;
@@ -189,14 +189,36 @@ async fn dhcpv4_run() {
189189
.await;
190190
}
191191

192+
pub(crate) static NETWORK_WAKER: InterruptTicketMutex<WakerRegistration> =
193+
InterruptTicketMutex::new(WakerRegistration::new());
194+
192195
async fn network_run() {
193196
future::poll_fn(|cx| {
194197
if let Some(mut guard) = NIC.try_lock() {
195198
match &mut *guard {
196199
NetworkState::Initialized(nic) => {
197-
nic.poll_common(now());
198-
// FIXME: only wake when progress can be made
199-
cx.waker().wake_by_ref();
200+
let now = now();
201+
202+
// TODO: smoltcp is probably not exposing enough information here
203+
// Well, how could it! Impossible :)
204+
match nic.poll_common(now) {
205+
PollResult::SocketStateChanged => {
206+
// Progress was made
207+
cx.waker().wake_by_ref();
208+
}
209+
PollResult::None => {
210+
// Very likely no progress can be made, so set up a timer interrupt to wake the waker
211+
NETWORK_WAKER.lock().register(cx.waker());
212+
nic.set_polling_mode(false);
213+
let wakeup_time = nic.poll_delay(now).map(|d| {
214+
crate::arch::processor::get_timer_ticks() + d.total_micros()
215+
});
216+
crate::core_scheduler().add_network_timer(wakeup_time);
217+
info!("Configured an interrupt for {wakeup_time:?}");
218+
//cx.waker().wake_by_ref();
219+
}
220+
}
221+
200222
Poll::Pending
201223
}
202224
_ => Poll::Ready(()),

src/fd/socket/tcp.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use smoltcp::wire::{IpEndpoint, Ipv4Address, Ipv6Address};
1313

1414
use crate::errno::Errno;
1515
use crate::executor::block_on;
16-
use crate::executor::network::{Handle, NIC};
16+
use crate::executor::network::{Handle, NETWORK_WAKER, NIC};
1717
use crate::fd::{self, Endpoint, ListenEndpoint, ObjectInterface, PollEvent, SocketOption};
1818
use crate::syscalls::socket::Af;
1919
use crate::{DEFAULT_KEEP_ALIVE_INTERVAL, io};
@@ -65,14 +65,20 @@ impl Socket {
6565
fn with<R>(&self, f: impl FnOnce(&mut tcp::Socket<'_>) -> R) -> R {
6666
let mut guard = NIC.lock();
6767
let nic = guard.as_nic_mut().unwrap();
68-
f(nic.get_mut_socket::<tcp::Socket<'_>>(*self.handle.first().unwrap()))
68+
let r = f(nic.get_mut_socket::<tcp::Socket<'_>>(*self.handle.first().unwrap()));
69+
// FIXME: Ideally this would be our send/recv waker, but we can only have one
70+
NETWORK_WAKER.lock().wake();
71+
r
6972
}
7073

7174
fn with_context<R>(&self, f: impl FnOnce(&mut tcp::Socket<'_>, &mut iface::Context) -> R) -> R {
7275
let mut guard = NIC.lock();
7376
let nic = guard.as_nic_mut().unwrap();
7477
let (s, cx) = nic.get_socket_and_context::<tcp::Socket<'_>>(*self.handle.first().unwrap());
75-
f(s, cx)
78+
let r = f(s, cx);
79+
// FIXME: Ideally this would be our send/recv waker, but we can only have one
80+
NETWORK_WAKER.lock().wake();
81+
r
7682
}
7783

7884
async fn close(&self) -> io::Result<()> {

src/fd/socket/udp.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use smoltcp::wire::{IpEndpoint, Ipv4Address, Ipv6Address};
1010

1111
use crate::errno::Errno;
1212
use crate::executor::block_on;
13-
use crate::executor::network::{Handle, NIC};
13+
use crate::executor::network::{Handle, NETWORK_WAKER, NIC};
1414
use crate::fd::{self, Endpoint, ListenEndpoint, ObjectInterface, PollEvent};
1515
use crate::io;
1616
use crate::syscalls::socket::Af;
@@ -44,7 +44,9 @@ impl Socket {
4444
fn with<R>(&self, f: impl FnOnce(&mut udp::Socket<'_>) -> R) -> R {
4545
let mut guard = NIC.lock();
4646
let nic = guard.as_nic_mut().unwrap();
47-
f(nic.get_mut_socket::<udp::Socket<'_>>(self.handle))
47+
let r = f(nic.get_mut_socket::<udp::Socket<'_>>(self.handle));
48+
NETWORK_WAKER.lock().wake();
49+
r
4850
}
4951

5052
async fn close(&self) -> io::Result<()> {

0 commit comments

Comments
 (0)