mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
nic_router/nic_bridge: free MAC addresses
Free a MAC address of a session as soon as the session gets destructed. Adds also according tests to the autopilot list. Fixes #2470
This commit is contained in:
parent
bafe3c3fc3
commit
3a59f11708
2
repos/os/run/nic_bridge_stress.run
Normal file
2
repos/os/run/nic_bridge_stress.run
Normal file
@ -0,0 +1,2 @@
|
||||
set type "nic_bridge"
|
||||
source ${genode_dir}/repos/os/run/nic_stress.inc
|
2
repos/os/run/nic_router_stress.run
Normal file
2
repos/os/run/nic_router_stress.run
Normal file
@ -0,0 +1,2 @@
|
||||
set type "nic_router"
|
||||
source ${genode_dir}/repos/os/run/nic_stress.inc
|
167
repos/os/run/nic_stress.inc
Normal file
167
repos/os/run/nic_stress.inc
Normal file
@ -0,0 +1,167 @@
|
||||
append build_components {
|
||||
core init timer
|
||||
server/nic_router
|
||||
test/nic_stress
|
||||
}
|
||||
|
||||
append_if [string equal $type "nic_bridge"] build_components { server/nic_bridge }
|
||||
|
||||
proc exit_support {} {
|
||||
if {[have_spec fiasco]} {
|
||||
return "no"
|
||||
}
|
||||
return "yes"
|
||||
}
|
||||
|
||||
proc done_string {} {
|
||||
set done_string ""
|
||||
if {[have_spec fiasco]} {
|
||||
append done_string {.*?finished NIC stress test}
|
||||
append done_string {.*?\n}
|
||||
append done_string {.*?finished NIC stress test}
|
||||
append done_string {.*?\n}
|
||||
} else {
|
||||
append done_string {.*?"nic_stress_." exited with exit value 0}
|
||||
append done_string {.*?\n}
|
||||
append done_string {.*?"nic_stress_." exited with exit value 0}
|
||||
append done_string {.*?\n}
|
||||
}
|
||||
return $done_string
|
||||
}
|
||||
|
||||
proc nr_of_rounds { test_id } {
|
||||
if {[have_spec sel4]} {
|
||||
switch $test_id {
|
||||
1 { return 19 }
|
||||
2 { return 12 }
|
||||
}
|
||||
} else {
|
||||
switch $test_id {
|
||||
1 { return 22 }
|
||||
2 { return 16 }
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
proc nr_of_sessions { test_id } {
|
||||
switch $test_id {
|
||||
1 { return 11 }
|
||||
2 { return 17 }
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
append config {
|
||||
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>
|
||||
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>}
|
||||
|
||||
append_if [string equal $type "nic_router"] config {
|
||||
|
||||
<start name="nic_router" caps="1000">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config>
|
||||
<policy label_prefix="nic_stress_2" domain="default"/>
|
||||
<policy label_prefix="nic_stress_1" domain="default"/>
|
||||
<domain name="default" interface="10.0.2.55/24"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<alias name="nic_server" child="nic_router"/>}
|
||||
|
||||
append_if [string equal $type "nic_bridge"] config {
|
||||
|
||||
<start name="nic_router" caps="1000">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config>
|
||||
<policy label_prefix="nic_bridge" domain="default"/>
|
||||
<domain name="default" interface="10.0.2.55/24"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="nic_bridge" caps="1000">
|
||||
<resource name="RAM" quantum="50M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config mac="02:02:02:02:42:00">
|
||||
<policy label_prefix="nic_stress_2"/>
|
||||
<policy label_prefix="nic_stress_1"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_router"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<alias name="nic_server" child="nic_bridge"/>}
|
||||
|
||||
append config {
|
||||
|
||||
<start name="nic_stress_1" caps="1000">
|
||||
<binary name="test-nic_stress"/>
|
||||
<resource name="RAM" quantum="50M"/>
|
||||
<config exit_support="} [exit_support] {">
|
||||
<construct_destruct nr_of_rounds="} [nr_of_rounds 1] {"
|
||||
nr_of_sessions="} [nr_of_sessions 1] {"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_server"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="nic_stress_2" caps="1000">
|
||||
<binary name="test-nic_stress"/>
|
||||
<resource name="RAM" quantum="100M"/>
|
||||
<config exit_support="} [exit_support] {">
|
||||
<construct_destruct nr_of_rounds="} [nr_of_rounds 2] {"
|
||||
nr_of_sessions="} [nr_of_rounds 2] {"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_server"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
</config>}
|
||||
|
||||
install_config $config
|
||||
|
||||
append boot_modules {
|
||||
core init timer
|
||||
nic_router
|
||||
test-nic_stress
|
||||
ld.lib.so
|
||||
}
|
||||
|
||||
append_if [string equal $type "nic_bridge"] boot_modules { nic_bridge }
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -nographic "
|
||||
|
||||
run_genode_until [done_string] 300
|
@ -68,7 +68,7 @@ class Net::Address_node : public Genode::Avl_node<Address_node<ADDRESS> >,
|
||||
***************/
|
||||
|
||||
void addr(Address addr) { _addr = addr; }
|
||||
Address addr() { return _addr; }
|
||||
Address addr() const { return _addr; }
|
||||
Session_component &component() { return _component; }
|
||||
|
||||
|
||||
|
@ -191,6 +191,8 @@ class Net::Session_component : private Net::Stream_allocator,
|
||||
Size_guard &size_guard) override;
|
||||
|
||||
void finalize_packet(Ethernet_frame *, Genode::size_t) override;
|
||||
|
||||
Mac_address vmac() const { return _mac_node.addr(); }
|
||||
};
|
||||
|
||||
|
||||
@ -240,6 +242,13 @@ class Net::Root : public Genode::Root_component<Net::Session_component>
|
||||
policy.attribute_value("ip_addr", Session_component::Ip_addr()));
|
||||
}
|
||||
|
||||
|
||||
void _destroy_session(Session_component *session) override
|
||||
{
|
||||
_mac_alloc.free(session->vmac());
|
||||
Genode::destroy(md_alloc(), session);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Env &env,
|
||||
|
@ -223,6 +223,8 @@ Session_component *Net::Root::_create_session(char const *args)
|
||||
|
||||
void Net::Root::_destroy_session(Session_component *session)
|
||||
{
|
||||
Mac_address const mac = session->mac_address();
|
||||
|
||||
/* read out initial dataspace and session env and destruct session */
|
||||
Ram_dataspace_capability ram_ds { session->ram_ds() };
|
||||
Session_env const &session_env { session->session_env() };
|
||||
@ -235,6 +237,8 @@ void Net::Root::_destroy_session(Session_component *session)
|
||||
session_env_stack.detach(&session_env);
|
||||
session_env_stack.free(ram_ds);
|
||||
|
||||
_mac_alloc.free(mac);
|
||||
|
||||
/* check for leaked quota */
|
||||
if (session_env_stack.ram_guard().used().value) {
|
||||
error("NIC session component \"", session_label, "\" leaks RAM quota of ",
|
||||
|
24
repos/os/src/test/nic_stress/config.xsd
Normal file
24
repos/os/src/test/nic_stress/config.xsd
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<xs:include schemaLocation="base_types.xsd"/>
|
||||
|
||||
<xs:element name="config">
|
||||
<xs:complexType>
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
|
||||
<xs:element name="construct_destruct">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="nr_of_rounds" type="xs:nonNegativeInteger" />
|
||||
<xs:attribute name="nr_of_sessions" type="xs:nonNegativeInteger" />
|
||||
</xs:complexType>
|
||||
</xs:element><!-- construct_destruct -->
|
||||
|
||||
</xs:choice>
|
||||
|
||||
<xs:attribute name="exit_support" type="Boolean" />
|
||||
|
||||
</xs:complexType>
|
||||
</xs:element><!-- config -->
|
||||
|
||||
</xs:schema>
|
149
repos/os/src/test/nic_stress/main.cc
Normal file
149
repos/os/src/test/nic_stress/main.cc
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* \brief Stress test for low level NIC interactions
|
||||
* \author Martin Stein
|
||||
* \date 2019-03-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/component.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <nic_session/connection.h>
|
||||
|
||||
namespace Local {
|
||||
|
||||
using namespace Genode;
|
||||
struct Construct_destruct_test;
|
||||
struct Main;
|
||||
}
|
||||
|
||||
|
||||
struct Local::Construct_destruct_test
|
||||
{
|
||||
enum { DEFAULT_NR_OF_ROUNDS = 10 };
|
||||
enum { DEFAULT_NR_OF_SESSIONS = 10 };
|
||||
enum { PKT_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE };
|
||||
enum { BUF_SIZE = 100 * PKT_SIZE };
|
||||
|
||||
using Nic_slot = Constructible<Nic::Connection>;
|
||||
|
||||
Env &_env;
|
||||
Allocator &_alloc;
|
||||
Signal_context_capability &_completed_sigh;
|
||||
Xml_node const &_config;
|
||||
Nic::Packet_allocator _pkt_alloc { &_alloc };
|
||||
bool const _config_exists { _config.has_sub_node("construct_destruct") };
|
||||
|
||||
unsigned long const _nr_of_rounds {
|
||||
_config_exists ?
|
||||
_config.sub_node("construct_destruct").
|
||||
attribute_value("nr_of_rounds",
|
||||
(unsigned long)DEFAULT_NR_OF_ROUNDS) :
|
||||
(unsigned long)DEFAULT_NR_OF_ROUNDS };
|
||||
|
||||
unsigned long const _nr_of_sessions {
|
||||
_config_exists ?
|
||||
_config.sub_node("construct_destruct").
|
||||
attribute_value("nr_of_sessions",
|
||||
(unsigned long)DEFAULT_NR_OF_SESSIONS) :
|
||||
(unsigned long)DEFAULT_NR_OF_SESSIONS };
|
||||
|
||||
void construct_all(Nic_slot *const nic,
|
||||
unsigned const round)
|
||||
{
|
||||
for (unsigned idx = 0; idx < _nr_of_sessions; idx++) {
|
||||
try {
|
||||
nic[idx].construct(_env, &_pkt_alloc, BUF_SIZE, BUF_SIZE);
|
||||
log("round ", round + 1, "/", _nr_of_rounds, " nic ", idx + 1,
|
||||
"/", _nr_of_sessions, " mac ", nic[idx]->mac_address());
|
||||
}
|
||||
catch (...) {
|
||||
for (unsigned destruct_idx = 0; destruct_idx < idx; destruct_idx++) {
|
||||
nic[destruct_idx].destruct();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void destruct_all(Nic_slot *const nic)
|
||||
{
|
||||
for (unsigned idx = 0; idx < _nr_of_sessions; idx++) {
|
||||
nic[idx].destruct();
|
||||
}
|
||||
}
|
||||
|
||||
Construct_destruct_test(Env &env,
|
||||
Allocator &alloc,
|
||||
Signal_context_capability completed_sigh,
|
||||
Xml_node const &config)
|
||||
:
|
||||
_env { env },
|
||||
_alloc { alloc },
|
||||
_completed_sigh { completed_sigh },
|
||||
_config { config }
|
||||
{
|
||||
if (!_nr_of_rounds && !_nr_of_sessions) {
|
||||
Signal_transmitter(_completed_sigh).submit(); }
|
||||
|
||||
size_t const ram_size { _nr_of_sessions * sizeof(Nic_slot) };
|
||||
Attached_ram_dataspace ram_ds { _env.ram(), _env.rm(), ram_size };
|
||||
Nic_slot *const nic { ram_ds.local_addr<Nic_slot>() };
|
||||
|
||||
try {
|
||||
for (unsigned round = 0; round < _nr_of_rounds; round++) {
|
||||
construct_all(nic, round);
|
||||
destruct_all(nic);
|
||||
}
|
||||
Signal_transmitter(_completed_sigh).submit();
|
||||
}
|
||||
catch (...) {
|
||||
error("Construct_destruct_test failed"); }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Local::Main
|
||||
{
|
||||
Env &_env;
|
||||
Heap _heap { &_env.ram(), &_env.rm() };
|
||||
Attached_rom_dataspace _config_rom { _env, "config" };
|
||||
Xml_node const _config { _config_rom.xml() };
|
||||
Constructible<Construct_destruct_test> _test_1 { };
|
||||
|
||||
bool const _exit_support {
|
||||
_config.attribute_value("exit_support", true) };
|
||||
|
||||
Signal_handler<Main> _test_completed_handler {
|
||||
_env.ep(), *this, &Main::_handle_test_completed };
|
||||
|
||||
void _handle_test_completed()
|
||||
{
|
||||
if (_test_1.constructed()) {
|
||||
_test_1.destruct();
|
||||
log("--- finished NIC stress test ---");
|
||||
if (_exit_support) {
|
||||
_env.parent().exit(0); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
log("--- NIC stress test ---");
|
||||
_test_1.construct(_env, _heap, _test_completed_handler, _config);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env) { static Local::Main main(env); }
|
4
repos/os/src/test/nic_stress/target.mk
Normal file
4
repos/os/src/test/nic_stress/target.mk
Normal file
@ -0,0 +1,4 @@
|
||||
TARGET = test-nic_stress
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
CONFIG_XSD = config.xsd
|
@ -33,9 +33,11 @@ netperf_lxip_router
|
||||
netperf_lxip_usb30
|
||||
netperf_lxip_wifi
|
||||
nic_bridge
|
||||
nic_bridge_stress
|
||||
nic_dump
|
||||
nic_router
|
||||
nic_router_flood
|
||||
nic_router_stress
|
||||
nic_router_uplinks
|
||||
noux
|
||||
noux_tool_chain_auto
|
||||
|
Loading…
x
Reference in New Issue
Block a user