From 95e55857529315bc77a6d1e8f1995f069cf5b27d Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Fri, 20 Jun 2025 17:42:30 +0200 Subject: [PATCH] WiP for MxIP. --- repos/ealanos/include/mxip/lwipopts.h | 4 +- repos/ealanos/include/mxip/mxip_lock.h | 8 ++ repos/ealanos/include/mxip/mxnic_netif.h | 71 ++++++++++----- .../src/lib/mxip/platform/mxnic_netif.cc | 86 +++++++++++-------- .../ealanos/src/lib/mxip/platform/sys_arch.cc | 2 + 5 files changed, 111 insertions(+), 60 deletions(-) create mode 100644 repos/ealanos/include/mxip/mxip_lock.h diff --git a/repos/ealanos/include/mxip/lwipopts.h b/repos/ealanos/include/mxip/lwipopts.h index 8149942677..2f487497a3 100644 --- a/repos/ealanos/include/mxip/lwipopts.h +++ b/repos/ealanos/include/mxip/lwipopts.h @@ -40,8 +40,8 @@ extern "C" { #define LWIP_TCP_TIMESTAMPS 0 #define TCP_LISTEN_BACKLOG 255 #define TCP_MSS 1460 -#define TCP_WND (80 * TCP_MSS) -#define TCP_SND_BUF (80 * TCP_MSS) +#define TCP_WND (46 * TCP_MSS) +#define TCP_SND_BUF (46 * TCP_MSS) #define LWIP_WND_SCALE 3 #define TCP_RCV_SCALE 2 #define TCP_SND_QUEUELEN ((512 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) diff --git a/repos/ealanos/include/mxip/mxip_lock.h b/repos/ealanos/include/mxip/mxip_lock.h new file mode 100644 index 0000000000..e91b82f216 --- /dev/null +++ b/repos/ealanos/include/mxip/mxip_lock.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include + +namespace Mxip { + extern mx::synchronization::OptimisticLock mxip_lock; +} \ No newline at end of file diff --git a/repos/ealanos/include/mxip/mxnic_netif.h b/repos/ealanos/include/mxip/mxnic_netif.h index 651ca12dc9..6f50e72780 100644 --- a/repos/ealanos/include/mxip/mxnic_netif.h +++ b/repos/ealanos/include/mxip/mxnic_netif.h @@ -28,6 +28,9 @@ #include "base/allocator.h" #include "mx/memory/global_heap.h" +#include "mx/system/environment.h" +#include "os/packet_stream.h" +#include "trace/timestamp.h" #include #if ETH_PAD_SIZE #error ETH_PAD_SIZE defined but unsupported by lwip/nic_netif.h @@ -46,6 +49,7 @@ #include #include +#include "mxip_lock.h" /* EalanOS includes */ #include @@ -92,14 +96,20 @@ namespace Lwip { { struct pbuf_custom p { }; Mxip::Nic_netif &netif; - void *payload; + void *payload; + Genode::Packet_descriptor packet; - Nic_netif_pbuf(Mxip::Nic_netif &nic, void *pl) - : netif(nic), payload(pl) + Nic_netif_pbuf(Mxip::Nic_netif &nic, void *pl, Genode::Packet_descriptor pkt) + : netif(nic), payload(pl), packet(pkt) { p.custom_free_function = nic_netif_pbuf_free; } }; + + struct Rx_task_stats { + Genode::Trace::Timestamp waiting_time; + Genode::Trace::Timestamp execution_time; + }; } class Mxip::Nic_netif @@ -116,7 +126,7 @@ class Mxip::Nic_netif }; enum { TASK_SIZE = 128, SB_SIZE = 2 * 2048 }; - + private: Genode::Entrypoint _ep; @@ -153,22 +163,23 @@ class Mxip::Nic_netif bool _dhcp { false }; + Lwip::Rx_task_stats _rx_stats[10000100]; public: void free_pbuf(Lwip::Nic_netif_pbuf &pbuf) { - /*bool msg_once = true; + bool msg_once = true; while (!_nic.rx()->ready_to_ack()) { - if (msg_once) - Genode::error("Nic rx acknowledgement queue congested, blocking to free pbuf"); + //if (msg_once) + //Genode::error("Nic rx acknowledgement queue congested, blocking to free pbuf"); msg_once = false; _ep.wait_and_dispatch_one_io_signal(); } _nic.rx()->try_ack_packet(pbuf.packet); - _wakeup_scheduler.schedule_nic_server_wakeup();*/ - _packet_alloc->free(pbuf.payload); - _task_alloc->free(&pbuf);//destroy(_pbuf_alloc, &pbuf); + _wakeup_scheduler.schedule_nic_server_wakeup(); + //_packet_alloc->free(pbuf.payload); + _packet_alloc->free(&pbuf);//destroy(_pbuf_alloc, &pbuf); } /************************* @@ -401,6 +412,14 @@ class Mxip::Nic_netif _nic.rx()->wakeup(); _nic.tx()->wakeup(); } + + void print_stats() + { + for (int id = 0; id < 1000000; id++) { + Genode::log("rx: id =", id, " wait=", _rx_stats[id].waiting_time, " etime: ", _rx_stats[id].execution_time); + } + } + }; /************************** @@ -411,21 +430,23 @@ class Mxip::Receive_task : public mx::tasking::TaskInterface { public: - Receive_task(void *payload, size_t len, struct Lwip::netif &netif, Mxip::Nic_netif &net) - : _netif(netif), _payload(payload), _length(len), _net(net) + Receive_task(void *payload, size_t len, struct Lwip::netif &netif, Mxip::Nic_netif &net, Genode::Trace::Timestamp arrival, unsigned long id, Genode::Packet_descriptor packet) + : _netif(netif), _payload(payload), _length(len), _net(net), _arrival(arrival), _id(id), _packet(packet) { } mx::tasking::TaskResult execute(std::uint16_t, std::uint16_t) override { - Lwip::Nic_netif_pbuf *nic_pbuf = new (_net._task_alloc->alloc(sizeof(Lwip::Nic_netif_pbuf))) - Lwip::Nic_netif_pbuf(_net, _payload); + Genode::Trace::Timestamp execution = Genode::Trace::timestamp(); + Lwip::Nic_netif_pbuf *nic_pbuf = new (_net._packet_alloc->alloc(sizeof(Lwip::Nic_netif_pbuf))) + Lwip::Nic_netif_pbuf(_net, _payload, _packet); if (!nic_pbuf) { Genode::warning("Could not allocate pbuf "); _net._task_alloc->free(this); return mx::tasking::TaskResult::make_null(); } + pbuf *p = pbuf_alloced_custom(PBUF_RAW, _length, PBUF_REF, &nic_pbuf->p, _payload, _length); LINK_STATS_INC(link.recv); @@ -435,14 +456,19 @@ class Mxip::Receive_task : public mx::tasking::TaskInterface _net._task_alloc->free(this); return mx::tasking::TaskResult::make_null(); } - err_t rc = _netif.input(p, &_netif); + err_t rc = _netif.input(p, &_netif); + if (rc != ERR_OK) { Genode::error("error forwarding Nic packet to lwIP: error=", static_cast(rc)); pbuf_free(p); } + Genode::Trace::Timestamp processed = Genode::Trace::timestamp(); + _net._rx_stats[_id].waiting_time = + ((execution - _arrival) * 1000) / mx::system::Environment::get_cpu_freq(); + _net._rx_stats[_id].execution_time = ((processed - execution) * 1000) / mx::system::Environment::get_cpu_freq(); _net._task_alloc->free(this); return mx::tasking::TaskResult::make_null(); //return mx::tasking::TaskResult::make_remove(); @@ -454,7 +480,9 @@ class Mxip::Receive_task : public mx::tasking::TaskInterface void *_payload; std::size_t _length; Mxip::Nic_netif &_net; - + Genode::Trace::Timestamp _arrival; + unsigned long _id; + Genode::Packet_descriptor _packet; }; class Mxip::Tx_ready_task : public mx::tasking::TaskInterface @@ -464,12 +492,13 @@ class Mxip::Tx_ready_task : public mx::tasking::TaskInterface Tx_ready_task(Nic::Connection &nic, Mxip::Nic_netif &netif) : _nic(nic), _netif(netif) { } mx::tasking::TaskResult execute(std::uint16_t, std::uint16_t) override { + //GENODE_LOG_TSC(1); auto &tx = *_nic.tx(); bool progress = false; while (tx.ack_avail()) { tx.release_packet(tx.try_get_acked_packet()); - _netif._tx_saturated = false; + //_netif._tx_saturated = false; progress = true; } @@ -504,6 +533,8 @@ class Mxip::Link_state_task : public mx::tasking::TaskInterface * if the application wants to be informed of the * link state then it should use 'set_link_callback' */ + + //GENODE_LOG_TSC_NAMED(1, "Link state task"); if (_nic.link_state()) { Lwip::netif_set_link_up(&_netif); if (_dhcp) { @@ -520,9 +551,9 @@ class Mxip::Link_state_task : public mx::tasking::TaskInterface Lwip::dhcp_release_and_stop(&_netif); } } - _nic_netif._task_alloc->free(this); - return mx::tasking::TaskResult::make_null(); - //return mx::tasking::TaskResult::make_remove(); + //_nic_netif._task_alloc->free(this); + //return mx::tasking::TaskResult::make_null(); + return mx::tasking::TaskResult::make_remove(); } private: diff --git a/repos/ealanos/src/lib/mxip/platform/mxnic_netif.cc b/repos/ealanos/src/lib/mxip/platform/mxnic_netif.cc index 28943eb52e..6f99f6de91 100644 --- a/repos/ealanos/src/lib/mxip/platform/mxnic_netif.cc +++ b/repos/ealanos/src/lib/mxip/platform/mxnic_netif.cc @@ -1,62 +1,69 @@ #include "lwip/pbuf.h" +#include "mx/synchronization/optimistic_lock.h" +#include "trace/timestamp.h" #include #include #include #include #include +mx::synchronization::OptimisticLock Mxip::mxip_lock{}; + void Mxip::Nic_netif::handle_rx_packets() { -Nic::Session::Rx::Sink *rx = _nic.rx(); + Nic::Session::Rx::Sink *rx = _nic.rx(); -bool progress = false; + bool progress = false; -while (rx->packet_avail() && rx->ready_to_ack()) { + // TODO: Reduce time spent in the loops body as it is executed hundreds of times + //GENODE_LOG_TSC(1); + while (rx->packet_avail() && rx->ready_to_ack()) { - try - { - Nic::Packet_descriptor packet = rx->try_get_packet(); - progress = true; + Genode::Trace::Timestamp arrival = Genode::Trace::timestamp(); + try { + static unsigned long id = 0; + + Nic::Packet_descriptor packet = rx->try_get_packet(); + progress = true; - void *payload = _packet_alloc->alloc(sizeof(packet.size())); - memcpy(payload, rx->packet_content(packet), packet.size()); + /*void *payload = _packet_alloc->alloc(sizeof(packet.size())); + memcpy(payload, rx->packet_content(packet), packet.size());*/ + void *payload = rx->packet_content(packet); - Mxip::Receive_task *task = new (_task_alloc->alloc(sizeof(Mxip::Receive_task))) Mxip::Receive_task(payload, packet.size(), _netif, *this); - if (task == nullptr) + Mxip::Receive_task *task = new (_task_alloc->alloc(sizeof(Mxip::Receive_task))) Mxip::Receive_task(payload, packet.size(), _netif, *this, arrival, id++, packet); + + //auto task = mx::tasking::runtime::new_task(1, payload, packet.size(), _netif, *this, arrival, id++, packet); + if (task == nullptr) + { + Genode::warning("Could not allocate task object."); + return; + } + task->annotate(static_cast(0)); + mx::tasking::runtime::spawn(*task); + + if (progress) { + _wakeup_scheduler.schedule_nic_server_wakeup(); + } + } + catch (Genode::Exception) { - Genode::warning("Could not allocate task object."); - return; - } - task->annotate(static_cast(0)); - mx::tasking::runtime::spawn(*task); - - if (progress) { - - while (!_nic.rx()->ready_to_ack()) { _ep.wait_and_dispatch_one_io_signal(); } - - rx->try_ack_packet(packet); - _wakeup_scheduler.schedule_nic_server_wakeup(); + Genode::warning("Got signal without actual packet in queue"); } } - catch (Genode::Exception) - { - Genode::warning("Got signal without actual packet in queue"); - } -} } void Mxip::Nic_netif::handle_tx_ready() { -/*Mxip::Tx_ready_task *task = new (_task_alloc->alloc(sizeof(Mxip::Tx_ready_task))) -Mxip::Tx_ready_task(_nic, *this); if (task == nullptr) -{ - Genode::warning("Could not allocate tx_ready task object."); - return; -} -task->annotate(static_cast(0)); -mx::tasking::runtime::spawn(*task);*/ - + //GENODE_LOG_TSC(1); + /*Mxip::Tx_ready_task *task = new (_task_alloc->alloc(sizeof(Mxip::Tx_ready_task))) + Mxip::Tx_ready_task(_nic, *this); if (task == nullptr) + { + Genode::warning("Could not allocate tx_ready task object."); + return; + } + task->annotate(static_cast(0)); + mx::tasking::runtime::spawn(*task);*/ auto &tx = *_nic.tx(); bool progress = false; @@ -76,7 +83,10 @@ mx::tasking::runtime::spawn(*task);*/ void Mxip::Nic_netif::handle_link_state() { -Mxip::Link_state_task *task = new (_task_alloc->alloc(sizeof(Mxip::Link_state_task))) Mxip::Link_state_task(_nic, _netif, *this, _dhcp); +//Mxip::Link_state_task *task = new (_task_alloc->alloc(sizeof(Mxip::Link_state_task))) Mxip::Link_state_task(_nic, _netif, *this, _dhcp); + +auto task = mx::tasking::runtime::new_task(0, _nic, _netif, *this, _dhcp); + if (task == nullptr) { Genode::warning("Could not allocate link state task object."); return; diff --git a/repos/ealanos/src/lib/mxip/platform/sys_arch.cc b/repos/ealanos/src/lib/mxip/platform/sys_arch.cc index 7db0048013..76ccfbdcb8 100644 --- a/repos/ealanos/src/lib/mxip/platform/sys_arch.cc +++ b/repos/ealanos/src/lib/mxip/platform/sys_arch.cc @@ -13,11 +13,13 @@ */ /* Genode includes */ +#include "mxip_lock.h" #include #include #include #include +#include #include #include