From 70bf0cbe84abe430a9f50aed999dd32d215f0d45 Mon Sep 17 00:00:00 2001 From: Johannes Schlatow Date: Wed, 9 Feb 2022 17:14:32 +0100 Subject: [PATCH] vfs/lwip: add missing signal handlers Note, without batching from the Nic server this may slow down the throughput a bit. genodelabs/genode#4427 --- repos/libports/include/lwip/nic_netif.h | 21 ++++++++++++++++++++- repos/libports/src/lib/vfs/lwip/vfs.cc | 12 ++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/repos/libports/include/lwip/nic_netif.h b/repos/libports/include/lwip/nic_netif.h index 167abecb3f..004ad00a55 100644 --- a/repos/libports/include/lwip/nic_netif.h +++ b/repos/libports/include/lwip/nic_netif.h @@ -95,6 +95,7 @@ class Lwip::Nic_netif Genode::Io_signal_handler _link_state_handler; Genode::Io_signal_handler _rx_packet_handler; + Genode::Io_signal_handler _tx_ready_handler; bool _dhcp { false }; @@ -167,6 +168,21 @@ class Lwip::Nic_netif } } + /** + * Handle tx ack_avail and ready_to_submit signals + */ + void handle_tx_ready() + { + auto &tx = *_nic.tx(); + + /* flush acknowledgements */ + while (tx.ack_avail()) + tx.release_packet(tx.get_acked_packet()); + + /* notify subclass to resume pending transmissions */ + status_callback(); + } + void configure(Genode::Xml_node const &config) { _dhcp = config.attribute_value("dhcp", false); @@ -232,7 +248,8 @@ class Lwip::Nic_netif BUF_SIZE, BUF_SIZE, config.attribute_value("label", Genode::String<160>("lwip")).string()), _link_state_handler(env.ep(), *this, &Nic_netif::handle_link_state), - _rx_packet_handler( env.ep(), *this, &Nic_netif::handle_rx_packets) + _rx_packet_handler( env.ep(), *this, &Nic_netif::handle_rx_packets), + _tx_ready_handler( env.ep(), *this, &Nic_netif::handle_tx_ready) { Genode::memset(&_netif, 0x00, sizeof(_netif)); @@ -307,6 +324,8 @@ class Lwip::Nic_netif _nic.link_state_sigh(_link_state_handler); _nic.rx_channel()->sigh_packet_avail(_rx_packet_handler); _nic.rx_channel()->sigh_ready_to_ack(_rx_packet_handler); + _nic.tx_channel()->sigh_ready_to_submit(_tx_ready_handler); + _nic.tx_channel()->sigh_ack_avail (_tx_ready_handler); return ERR_OK; } diff --git a/repos/libports/src/lib/vfs/lwip/vfs.cc b/repos/libports/src/lib/vfs/lwip/vfs.cc index e0721cbb89..c3b592d49c 100644 --- a/repos/libports/src/lib/vfs/lwip/vfs.cc +++ b/repos/libports/src/lib/vfs/lwip/vfs.cc @@ -1006,7 +1006,9 @@ class Lwip::Udp_socket_dir final : err_t err = udp_sendto(_pcb, buf, &_to_addr, _to_port); pbuf_free(buf); - if (err != ERR_OK) + if (err == ERR_WOULDBLOCK) + return Write_result::WRITE_ERR_WOULD_BLOCK; + else if (err != ERR_OK) return Write_result::WRITE_ERR_IO; remain -= buf->tot_len; src += buf->tot_len; @@ -1496,7 +1498,13 @@ class Lwip::Tcp_socket_dir final : } /* send queued data */ - if (out > 0) tcp_output(_pcb); + if (out > 0) { + err_t err = tcp_output(_pcb); + if (err == ERR_WOULDBLOCK) + return Write_result::WRITE_ERR_WOULD_BLOCK; + else if (err != ERR_OK) + return Write_result::WRITE_ERR_IO; + } out_count = out; return res;