nic_router: batch packet stream signals

genodelabs/genode#4555
This commit is contained in:
Johannes Schlatow 2022-07-01 16:52:59 +02:00 committed by Christian Helmuth
parent 359283968a
commit 8193f5571a
6 changed files with 55 additions and 4 deletions

View File

@ -228,4 +228,6 @@ void Dhcp_client::_send(Message_type msg_type,
ip.total_length(size_guard.head_size() - ip_off); ip.total_length(size_guard.head_size() - ip_off);
ip.update_checksum(); ip.update_checksum();
}); });
_interface.wakeup_source();
} }

View File

@ -1538,7 +1538,7 @@ void Interface::_handle_pkt_stream_signal()
* sending new packets in the subsequent steps of this handler. * sending new packets in the subsequent steps of this handler.
*/ */
while (_source.ack_avail()) { while (_source.ack_avail()) {
_source.release_packet(_source.get_acked_packet()); _source.release_packet(_source.try_get_acked_packet());
} }
/* /*
@ -1567,6 +1567,23 @@ void Interface::_handle_pkt_stream_signal()
_handle_pkt(); _handle_pkt();
} }
} }
/*
* Since we use the try_*() variants of the packet-stream API, we
* haven't emitted any packet_avail, ack_avail, ready_to_submit or
* ready_to_ack signal up to now. We've removed packets from our sink's
* submit queue and might have forwarded it to any interface. We may have
* also removed acks from our sink's ack queue.
*
* We therefore wakeup all sources and our sink. Note that the packet-stream
* API takes care of emitting only the signals that are actually needed.
*/
_config().domains().for_each([&] (Domain &domain) {
domain.interfaces().for_each([&] (Interface &interface) {
interface.wakeup_source();
});
});
wakeup_sink();
} }
@ -1810,7 +1827,7 @@ void Interface::_send_submit_pkt(Packet_descriptor &pkt,
} }
catch (Size_guard::Exceeded) { log("[", local_domain, "] snd ?"); } catch (Size_guard::Exceeded) { log("[", local_domain, "] snd ?"); }
} }
_source.submit_packet(pkt); _source.try_submit_packet(pkt);
} }
@ -2132,6 +2149,13 @@ void Interface::_failed_to_send_packet_link()
} }
void Interface::_failed_to_send_packet_submit()
{
if (_config().verbose()) {
log("[", _domain(), "] failed to send packet (queue full)"); }
}
void Interface::_failed_to_send_packet_alloc() void Interface::_failed_to_send_packet_alloc()
{ {
if (_config().verbose()) { if (_config().verbose()) {
@ -2254,14 +2278,13 @@ void Interface::handle_config_3()
void Interface::_ack_packet(Packet_descriptor const &pkt) void Interface::_ack_packet(Packet_descriptor const &pkt)
{ {
if (!_sink.ready_to_ack()) { if (!_sink.try_ack_packet(pkt)) {
if (_config().verbose()) { if (_config().verbose()) {
log("[", _domain(), "] leak packet (sink not ready to " log("[", _domain(), "] leak packet (sink not ready to "
"acknowledge)"); "acknowledge)");
} }
return; return;
} }
_sink.acknowledge_packet(pkt);
} }

View File

@ -345,6 +345,8 @@ class Net::Interface : private Interface_list::Element
void _failed_to_send_packet_link(); void _failed_to_send_packet_link();
void _failed_to_send_packet_submit();
void _failed_to_send_packet_alloc(); void _failed_to_send_packet_alloc();
void _send_icmp_dst_unreachable(Ipv4_address_prefix const &local_intf, void _send_icmp_dst_unreachable(Ipv4_address_prefix const &local_intf,
@ -394,6 +396,10 @@ class Net::Interface : private Interface_list::Element
_failed_to_send_packet_link(); _failed_to_send_packet_link();
return; return;
} }
if (!_source.ready_to_submit()) {
_failed_to_send_packet_submit();
return;
}
try { try {
Packet_descriptor pkt; Packet_descriptor pkt;
void *pkt_base; void *pkt_base;
@ -456,6 +462,8 @@ class Net::Interface : private Interface_list::Element
Interface_link_stats &icmp_stats() { return _icmp_stats; } Interface_link_stats &icmp_stats() { return _icmp_stats; }
Interface_object_stats &arp_stats() { return _arp_stats; } Interface_object_stats &arp_stats() { return _arp_stats; }
Interface_object_stats &dhcp_stats() { return _dhcp_stats; } Interface_object_stats &dhcp_stats() { return _dhcp_stats; }
void wakeup_source() { _source.wakeup(); }
void wakeup_sink() { _sink.wakeup(); }
}; };
#endif /* _INTERFACE_H_ */ #endif /* _INTERFACE_H_ */

View File

@ -170,6 +170,12 @@ Net::Nic_client_interface::Nic_client_interface(Env &env,
rx_channel()->sigh_packet_avail(_interface.pkt_stream_signal_handler()); rx_channel()->sigh_packet_avail(_interface.pkt_stream_signal_handler());
tx_channel()->sigh_ack_avail (_interface.pkt_stream_signal_handler()); tx_channel()->sigh_ack_avail (_interface.pkt_stream_signal_handler());
/*
* We do not install ready_to_submit because submission is only triggered
* by incoming packets (and dropped if the submit queue is full).
* The ack queue should never be full otherwise we'll be leaking packets.
*/
/* initialize link state handling */ /* initialize link state handling */
Nic::Connection::link_state_sigh(_session_link_state_handler); Nic::Connection::link_state_sigh(_session_link_state_handler);
_session_link_state = Nic::Connection::link_state(); _session_link_state = Nic::Connection::link_state();

View File

@ -256,6 +256,12 @@ Nic_session_component(Session_env &session_env,
/* install packet stream signal handlers */ /* install packet stream signal handlers */
_tx.sigh_packet_avail(_interface.pkt_stream_signal_handler()); _tx.sigh_packet_avail(_interface.pkt_stream_signal_handler());
_rx.sigh_ack_avail (_interface.pkt_stream_signal_handler()); _rx.sigh_ack_avail (_interface.pkt_stream_signal_handler());
/*
* We do not install ready_to_submit because submission is only triggered by
* incoming packets (and dropped if the submit queue is full).
* The ack queue should never be full otherwise we'll be leaking packets.
*/
} }

View File

@ -104,6 +104,12 @@ Net::Uplink_session_component::Uplink_session_component(Session_env
/* install packet stream signal handlers */ /* install packet stream signal handlers */
_tx.sigh_packet_avail(_interface.pkt_stream_signal_handler()); _tx.sigh_packet_avail(_interface.pkt_stream_signal_handler());
_rx.sigh_ack_avail (_interface.pkt_stream_signal_handler()); _rx.sigh_ack_avail (_interface.pkt_stream_signal_handler());
/*
* We do not install ready_to_submit because submission is only triggered by
* incoming packets (and dropped if the submit queue is full).
* The ack queue should never be full otherwise we'll be leaking packets.
*/
} }