Skip to content

Commit d3a3407

Browse files
committed
WIP
1 parent f250a72 commit d3a3407

File tree

9 files changed

+74
-97
lines changed

9 files changed

+74
-97
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/loopback.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use smoltcp::time::Instant;
88

99
use crate::drivers::net::NetworkDriver;
1010
use crate::drivers::{Driver, InterruptLine};
11+
use crate::executor::network::NETWORK_WAKER;
1112
use crate::mm::device_alloc::DeviceAlloc;
1213

1314
pub(crate) struct LoopbackDriver {
@@ -122,7 +123,8 @@ impl NetworkDriver for LoopbackDriver {
122123
}
123124

124125
fn handle_interrupt(&mut self) {
125-
// no-op
126+
debug!("Waking network waker");
127+
NETWORK_WAKER.lock().wake();
126128
}
127129
}
128130

src/drivers/net/rtl8139.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::drivers::Driver;
2121
use crate::drivers::error::DriverError;
2222
use crate::drivers::net::{NetworkDriver, mtu};
2323
use crate::drivers::pci::PciDevice;
24+
use crate::executor::network::NETWORK_WAKER;
2425
use crate::mm::device_alloc::DeviceAlloc;
2526

2627
/// size of the receive buffer
@@ -687,6 +688,9 @@ impl NetworkDriver for RTL8139Driver {
687688
self.regs.as_mut_ptr().isr().write(le16::from(
688689
isr_contents & (ISR_RXOVW | ISR_TER | ISR_RER | ISR_TOK | ISR_ROK),
689690
));
691+
692+
debug!("Waking network waker");
693+
NETWORK_WAKER.lock().wake();
690694
}
691695
}
692696

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;
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: 9 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,11 @@ use core::time::Duration;
1818

1919
use crossbeam_utils::Backoff;
2020
use hermit_sync::without_interrupts;
21-
#[cfg(feature = "net")]
22-
use smoltcp::time::Instant;
2321

2422
use crate::arch::core_local;
2523
use crate::errno::Errno;
2624
use crate::executor::task::AsyncTask;
2725
use crate::io;
28-
#[cfg(feature = "net")]
29-
use crate::scheduler::PerCoreSchedulerExt;
3026
use crate::synch::futex::*;
3127

3228
/// WakerRegistration is derived from smoltcp's
@@ -155,101 +151,27 @@ where
155151

156152
let now = crate::arch::kernel::systemtime::now_micros();
157153
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-
176154
return t;
177155
}
178156

179157
if let Some(duration) = timeout
180158
&& Duration::from_micros(now - start) >= duration
181159
{
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-
200160
return Err(Errno::Time);
201161
}
202162

203-
#[cfg(feature = "net")]
163+
// TODO: I have no idea whether this is correct
204164
if backoff.is_completed() {
205-
let delay = if let Some(mut guard) = crate::executor::network::NIC.try_lock() {
206-
if let Ok(nic) = guard.as_nic_mut() {
207-
nic.set_polling_mode(false);
208-
209-
nic.poll_delay(Instant::from_micros_const(now.try_into().unwrap()))
210-
.map(|d| d.total_micros())
211-
} else {
212-
None
213-
}
214-
} else {
215-
None
216-
};
217-
218-
if delay.unwrap_or(10_000_000) > 10_000 {
219-
core_local::core_scheduler().add_network_timer(
220-
delay.map(|d| crate::arch::processor::get_timer_ticks() + d),
221-
);
222-
let wakeup_time =
223-
timeout.map(|duration| start + u64::try_from(duration.as_micros()).unwrap());
224-
225-
// switch to another task
226-
task_notify.wait(wakeup_time);
227-
228-
// restore default values
229-
if let Ok(nic) = crate::executor::network::NIC.lock().as_nic_mut() {
230-
nic.set_polling_mode(true);
231-
}
232-
233-
backoff.reset();
234-
}
235-
} else {
236-
backoff.snooze();
237-
}
238-
239-
#[cfg(not(feature = "net"))]
240-
{
241-
if backoff.is_completed() {
242-
let wakeup_time =
243-
timeout.map(|duration| start + u64::try_from(duration.as_micros()).unwrap());
165+
let wakeup_time =
166+
timeout.map(|duration| start + u64::try_from(duration.as_micros()).unwrap());
244167

245-
// switch to another task
246-
task_notify.wait(wakeup_time);
168+
// switch to another task
169+
task_notify.wait(wakeup_time);
247170

248-
// restore default values
249-
backoff.reset();
250-
} else {
251-
backoff.snooze();
252-
}
171+
// restore default values
172+
backoff.reset();
173+
} else {
174+
backoff.snooze();
253175
}
254176
}
255177
}

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)