diff --git a/task/net/src/main.rs b/task/net/src/main.rs index 417435438..10a70e105 100644 --- a/task/net/src/main.rs +++ b/task/net/src/main.rs @@ -257,9 +257,17 @@ fn main() -> ! { // who was waiting to hear back on their TX queue becoming non-full will // snap out of it. // - // This only works because we've set waiting_to_send to true for all sockets - // above. - server.wake_sockets(); + // Note that we don't, actually, need to check whether the TX queue is empty + // or not here. We just reset, so any previously buffered packets that we + // had in the TX queue for that socket are definitely gone and the queue + // will be empty. + // + // Once we have woken everyone once, we can then only wake tasks when we are + // sure they actually are trying to send. + for (task_id, notification) in generated::SOCKET_OWNERS { + let task_id = sys_refresh_task_id(task_id); + sys_post(task_id, notification); + } // Go! loop { diff --git a/task/net/src/server.rs b/task/net/src/server.rs index 116130a9d..6f35b2477 100644 --- a/task/net/src/server.rs +++ b/task/net/src/server.rs @@ -570,9 +570,15 @@ where Self { eth, - // The 'true' here is load-bearing: it ensures that sockets receive - // a notification on stack restart. - client_waiting_to_send: [true; SOCKET_COUNT], + // This only gets set if a client task has *definitely* tried to + // send on its socket. We do one big all-call wake everyone as soon + // as the net task starts, in case they were previously trying to + // send but their queue was full. If we were to keep waking any time + // a task's tx queue was not full, we will spuriously wake that task + // over and over again until it actually decides to send something + // --- which, given that communication on the management network is + // not generally initiated by the SP, could be a while! + client_waiting_to_send: [false; SOCKET_COUNT], vlan_state: enum_map::EnumMap::from_array( vlan_state.into_array().unwrap_lite(), ),