From d0f73b0b6e903f7bbc0c53820830bfd2c8565866 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Sun, 14 Apr 2019 18:56:47 +0200 Subject: [PATCH] Refactor nic_bus service --- src/server/nic_bus/bus.h | 63 ++++++++++++++++---------- src/server/nic_bus/main.cc | 17 ++----- src/server/nic_bus/session_component.h | 51 ++++++++++----------- 3 files changed, 68 insertions(+), 63 deletions(-) diff --git a/src/server/nic_bus/bus.h b/src/server/nic_bus/bus.h index 08cfd61ad..5a0cfa35e 100644 --- a/src/server/nic_bus/bus.h +++ b/src/server/nic_bus/bus.h @@ -23,56 +23,54 @@ namespace Nic_bus { using namespace Net; using namespace Genode; + template struct Bus; - class Session_component; - - Mac_address mac_address(Session_component &session); } +template struct Nic_bus::Bus { + struct Element; + /* static array of sessions on the bus */ enum { BUS_SIZE = 0xffU }; - Session_component *_sessions[BUS_SIZE] { nullptr }; + Element *_elements[BUS_SIZE] { nullptr }; static uint8_t _index(Mac_address const &mac) { return mac.addr[1]; }; - Bus() { } - void remove(Mac_address const mac) { - _sessions[_index(mac)] = nullptr; } + _elements[_index(mac)] = nullptr; } - Mac_address insert(Session_label const &label, - Session_component &session) + Mac_address insert(Element &elem, char const *label) { /** * Derive a MAC address using the FNV-1a algorithm. */ enum { - FNV_32_PRIME = 16777619U, - FNV_32_OFFSET = 2166136261U, + FNV_64_PRIME = 1099511628211U, + FNV_64_OFFSET = 14695981039346656037U, }; - uint32_t hash = FNV_32_OFFSET; + uint64_t hash = FNV_64_OFFSET; - char const *p = label.string(); + char const *p = label; while (*p) { hash ^= *p++; - hash *= FNV_32_PRIME; + hash *= FNV_64_PRIME; } for (;;) { /* add the terminating zero */ - hash *= FNV_32_PRIME; + hash *= FNV_64_PRIME; - uint8_t index = hash >> 24; + uint8_t index = hash >> 32; - if (_sessions[index] != nullptr) + if (_elements[index] != nullptr) continue; /* hash until a free slot is found */ - _sessions[index] = &session; + _elements[index] = &elem; Mac_address mac; mac.addr[0] = 0x02; @@ -86,14 +84,29 @@ struct Nic_bus::Bus } } + struct Element + { + Bus &bus; + T &obj; + + Mac_address const mac; + + Element(Bus &b, T &o, char const *label) + : bus(b), obj(o), mac(bus.insert(*this, label)) { } + + ~Element() { bus.remove(mac); } + }; + + Bus() { } + template void apply(Mac_address mac, PROC proc) { uint8_t const index = _index(mac); - Session_component *session = _sessions[index]; - if (session != nullptr) { - if (mac_address(*session) == mac) { - proc(*session); + Element *elem = _elements[index]; + if (elem != nullptr) { + if (elem->mac == mac) { + proc(elem->obj); } } } @@ -102,9 +115,9 @@ struct Nic_bus::Bus void apply_all(PROC proc) { for (auto i = 0U; i < BUS_SIZE; ++i) { - Session_component *session = _sessions[i]; - if (session != nullptr) { - proc(*session); + Element *elem = _elements[i]; + if (elem != nullptr) { + proc(elem->obj); } } } diff --git a/src/server/nic_bus/main.cc b/src/server/nic_bus/main.cc index c9fab85a1..0e6d43735 100644 --- a/src/server/nic_bus/main.cc +++ b/src/server/nic_bus/main.cc @@ -25,10 +25,6 @@ namespace Nic_bus { using namespace Genode; class Root; struct Main; - - /* used by the bus */ - Mac_address mac_address(Session_component &session) { - return session.mac_address(); } } @@ -40,7 +36,7 @@ class Nic_bus::Root : public Genode::Root_component Attached_rom_dataspace _config_rom { _env, "config" }; - Bus _bus { }; + Session_bus _bus { }; protected: @@ -67,10 +63,8 @@ class Nic_bus::Root : public Genode::Root_component Root(Genode::Env &env, Genode::Allocator &md_alloc) - : - Genode::Root_component( - env.ep(), md_alloc), - _env(env) + : Genode::Root_component(env.ep(), md_alloc), + _env(env) { } }; @@ -81,9 +75,8 @@ struct Nic_bus::Main Nic_bus::Root _root; Main(Genode::Env &env) - : - _sliced_heap(env.ram(), env.rm()), - _root(env, _sliced_heap) + : _sliced_heap(env.ram(), env.rm()), + _root(env, _sliced_heap) { env.parent().announce(env.ep().manage(_root)); } diff --git a/src/server/nic_bus/session_component.h b/src/server/nic_bus/session_component.h index ef9997e4f..3acac2c76 100644 --- a/src/server/nic_bus/session_component.h +++ b/src/server/nic_bus/session_component.h @@ -32,6 +32,8 @@ namespace Nic_bus { class Session_resources; class Session_component; + + typedef Bus Session_bus; } @@ -70,14 +72,12 @@ class Nic_bus::Session_component : private Session_resources, { private: - Bus &_bus; + Session_bus::Element _bus_elem; Genode::Session_label const _label; Genode::Io_signal_handler _packet_handler; - Mac_address const _mac { _bus.insert(_label, *this) }; - Nic::Packet_stream_sink<::Nic::Session::Policy> &sink() { return *_tx.sink(); } @@ -89,31 +89,15 @@ class Nic_bus::Session_component : private Session_resources, while (source().ack_avail()) source().release_packet(source().get_acked_packet()); + if (!source().ready_to_submit()) return; + /* drop the packet if the queue is congested */ + Nic::Packet_descriptor pkt = source().alloc_packet(size); void *content = source().packet_content(pkt); Genode::memcpy(content, (void*)ð, size); source().submit_packet(pkt); } - void _handle_ethernet(Ethernet_frame const ð, - Genode::size_t const size) - { - if (eth.src() != _mac) { - Genode::warning( - eth.src(), " is not the managed MAC adress, " - "dropping packet from ", _label); - return; - } - - auto send = [&] (Session_component &other) { other._send(eth, size); }; - - if (eth.dst().addr[0] & 1) { - _bus.apply_all(send); - } else { - _bus.apply(eth.dst(), send); - } - } - void _handle_packet(Nic::Packet_descriptor const &pkt) { if (!pkt.size() || !sink().packet_valid(pkt)) return; @@ -122,7 +106,22 @@ class Nic_bus::Session_component : private Session_resources, Ethernet_frame const ð = Ethernet_frame::cast_from( sink().packet_content(pkt), size_guard); - _handle_ethernet(eth, pkt.size()); + if (eth.src() != _bus_elem.mac) { + Genode::warning( + eth.src(), " is not the managed MAC adress, " + "dropping packet from ", _label); + return; + } + + auto send = [&] (Session_component &other) { other._send(eth, pkt.size()); }; + + if (eth.dst().addr[0] & 1) { + /* multicast */ + _bus_elem.bus.apply_all(send); + } else { + /* unicast */ + _bus_elem.bus.apply(eth.dst(), send); + } } void _handle_packets() @@ -142,7 +141,7 @@ class Nic_bus::Session_component : private Session_resources, Genode::Cap_quota cap_quota, Tx_size tx_size, Rx_size rx_size, - Bus &bus, + Session_bus &bus, Genode::Session_label const &label) : Session_resources(ram, region_map, @@ -151,14 +150,14 @@ class Nic_bus::Session_component : private Session_resources, Nic::Session_rpc_object(region_map, _tx_ds.cap(), _rx_ds.cap(), &_rx_pkt_alloc, ep.rpc_ep()), - _bus(bus), _label(label), + _bus_elem(bus, *this, label.string()), _label(label), _packet_handler(ep, *this, &Session_component::_handle_packets) { _tx.sigh_packet_avail(_packet_handler); _tx.sigh_ready_to_ack(_packet_handler); } - Nic::Mac_address mac_address() override { return _mac; } + Nic::Mac_address mac_address() override { return _bus_elem.mac; } bool link_state() override { return true; }