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.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.
*/
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();
}
}
/*
* 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 ?"); }
}
_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()
{
if (_config().verbose()) {
@ -2254,14 +2278,13 @@ void Interface::handle_config_3()
void Interface::_ack_packet(Packet_descriptor const &pkt)
{
if (!_sink.ready_to_ack()) {
if (!_sink.try_ack_packet(pkt)) {
if (_config().verbose()) {
log("[", _domain(), "] leak packet (sink not ready to "
"acknowledge)");
}
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_submit();
void _failed_to_send_packet_alloc();
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();
return;
}
if (!_source.ready_to_submit()) {
_failed_to_send_packet_submit();
return;
}
try {
Packet_descriptor pkt;
void *pkt_base;
@ -456,6 +462,8 @@ class Net::Interface : private Interface_list::Element
Interface_link_stats &icmp_stats() { return _icmp_stats; }
Interface_object_stats &arp_stats() { return _arp_stats; }
Interface_object_stats &dhcp_stats() { return _dhcp_stats; }
void wakeup_source() { _source.wakeup(); }
void wakeup_sink() { _sink.wakeup(); }
};
#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());
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 */
Nic::Connection::link_state_sigh(_session_link_state_handler);
_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 */
_tx.sigh_packet_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 */
_tx.sigh_packet_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.
*/
}