ealanos: Implemented support for static cells aka bricks.

This commit is contained in:
Michael Mueller
2025-06-17 19:26:10 +02:00
parent 6c9dee3f71
commit c3e8e0d89c
8 changed files with 53 additions and 60 deletions

View File

@@ -27,8 +27,8 @@ struct Ealan::Habitat_client : Genode::Rpc_client<Ealan::Habitat_session>
{ {
explicit Habitat_client(Habitat_capability session) : Rpc_client<Habitat_session>(session) {} explicit Habitat_client(Habitat_capability session) : Rpc_client<Habitat_session>(session) {}
Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd, Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label) override { Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd, Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label, bool is_brick) override {
return call<Rpc_create_cell>(pd, affinity, prio, label); return call<Rpc_create_cell>(pd, affinity, prio, label, is_brick);
} }
Genode::Affinity affinity() override Genode::Affinity affinity() override

View File

@@ -28,8 +28,8 @@ struct Ealan::Habitat_connection : Genode::Connection<Ealan::Habitat_session>, H
Habitat_connection(Genode::Env &env, Genode::Affinity &affinity, Label const &label = Label()) Habitat_connection(Genode::Env &env, Genode::Affinity &affinity, Label const &label = Label())
: Connection<Habitat_session>(env, label, Genode::Ram_quota { RAM_QUOTA }, affinity, Args("")), Habitat_client(cap()) {} : Connection<Habitat_session>(env, label, Genode::Ram_quota { RAM_QUOTA }, affinity, Args("")), Habitat_client(cap()) {}
Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd_cap, Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label) override { Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd_cap, Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label, bool is_brick) override {
return Habitat_client::create_cell(pd_cap, affinity, prio, label); return Habitat_client::create_cell(pd_cap, affinity, prio, label, is_brick);
} }
Genode::Affinity affinity() override Genode::Affinity affinity() override

View File

@@ -35,7 +35,7 @@ struct Ealan::Habitat_session : Genode::Session
/** /**
* Attach cell info page to the cells virtual memory space * Attach cell info page to the cells virtual memory space
*/ */
virtual Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd, Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label) = 0; virtual Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd, Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label, bool is_brick) = 0;
/** /**
* @brief Clean up the habitat by removing terminated cells and freeing their memory * @brief Clean up the habitat by removing terminated cells and freeing their memory
@@ -45,7 +45,7 @@ struct Ealan::Habitat_session : Genode::Session
virtual Genode::Affinity affinity() = 0; virtual Genode::Affinity affinity() = 0;
GENODE_RPC_THROW(Rpc_create_cell, Cell_capability, create_cell, GENODE_TYPE_LIST(Ealan::Cell::Cell_creation_error), Genode::Capability<Genode::Pd_session>, Genode::Affinity &, Genode::uint16_t, Genode::Session_label const &); GENODE_RPC_THROW(Rpc_create_cell, Cell_capability, create_cell, GENODE_TYPE_LIST(Ealan::Cell::Cell_creation_error), Genode::Capability<Genode::Pd_session>, Genode::Affinity &, Genode::uint16_t, Genode::Session_label const &, bool);
GENODE_RPC(Rpc_affinity, Genode::Affinity, affinity); GENODE_RPC(Rpc_affinity, Genode::Affinity, affinity);
GENODE_RPC(Rpc_groom, void, groom); GENODE_RPC(Rpc_groom, void, groom);

View File

@@ -83,7 +83,7 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
public: public:
Cell_component(Genode::Pd_session_capability pd_cap, Genode::uint16_t prio, Genode::Affinity &affinity, Genode::Rpc_entrypoint &ep, Genode::Region_map &rm, Genode::Session_label const &label) : _ep(ep), _session_label(label), _rm(rm), _pd_cap(pd_cap), _pd(pd_cap), _native_pd(_pd.native_pd()) { Cell_component(Genode::Pd_session_capability pd_cap, Genode::uint16_t prio, Genode::Affinity &affinity, Genode::Rpc_entrypoint &ep, Genode::Region_map &rm, Genode::Session_label const &label, bool is_brick) : _ep(ep), _session_label(label), _rm(rm), _pd_cap(pd_cap), _pd(pd_cap), _native_pd(_pd.native_pd()), _is_brick(is_brick) {
Tukija::mword_t cell_pd_sel = _native_pd.sel(); Tukija::mword_t cell_pd_sel = _native_pd.sel();
Tukija::mword_t cip_phys = 0; Tukija::mword_t cip_phys = 0;

View File

@@ -54,9 +54,9 @@ class Core::Habitat_session_component : public Genode::Session_object<Ealan::Hab
public: public:
Habitat_session_component(Genode::Rpc_entrypoint &ep, Genode::Session::Resources const &resources, Genode::Session_label const &label, Genode::Session::Diag const &diag, Genode::Ram_allocator &ram, Genode::Region_map &rm, Genode::Affinity const &affinity) : Genode::Session_object<Ealan::Habitat_session>(ep, resources, label, diag), _local_rm(rm), _affinity(affinity), _label(label), _ram_alloc(ram, _ram_quota_guard(), _cap_quota_guard()), _md_alloc(_ram_alloc, rm), _ep(ep) {} Habitat_session_component(Genode::Rpc_entrypoint &ep, Genode::Session::Resources const &resources, Genode::Session_label const &label, Genode::Session::Diag const &diag, Genode::Ram_allocator &ram, Genode::Region_map &rm, Genode::Affinity const &affinity) : Genode::Session_object<Ealan::Habitat_session>(ep, resources, label, diag), _local_rm(rm), _affinity(affinity), _label(label), _ram_alloc(ram, _ram_quota_guard(), _cap_quota_guard()), _md_alloc(_ram_alloc, rm), _ep(ep) {}
Ealan::Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd_cap, [[maybe_unused]] Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label) override { Ealan::Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd_cap, [[maybe_unused]] Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label, bool is_brick) override {
Ealan::Cell_component *cell = new (_md_alloc) Ealan::Cell_component(pd_cap, prio, affinity, _ep, _local_rm, label); Ealan::Cell_component *cell = new (_md_alloc) Ealan::Cell_component(pd_cap, prio, affinity, _ep, _local_rm, label, is_brick);
_managed_cells.insert(cell); _managed_cells.insert(cell);

View File

@@ -12,6 +12,7 @@
*/ */
/* Genode includes */ /* Genode includes */
#include "utils.h"
#include <vm_session/vm_session.h> #include <vm_session/vm_session.h>
/* local includes */ /* local includes */
@@ -735,50 +736,32 @@ void Sandbox::Child::resource_request(Parent::Resource_args const &args)
} }
Sandbox::Child::Child(Env &env, Sandbox::Child::Child(
Allocator &alloc, Env &env, Allocator &alloc, Verbose const &verbose, Id id,
Verbose const &verbose, Report_update_trigger &report_update_trigger, Xml_node start_node,
Id id, Default_route_accessor &default_route_accessor, Default_caps_accessor &default_caps_accessor,
Report_update_trigger &report_update_trigger, Name_registry &name_registry, Ram_limit_accessor &ram_limit_accessor,
Xml_node start_node, Cap_limit_accessor &cap_limit_accessor, Cpu_limit_accessor &cpu_limit_accessor,
Default_route_accessor &default_route_accessor, Cpu_quota_transfer &cpu_quota_transfer, Prio_levels prio_levels,
Default_caps_accessor &default_caps_accessor, Affinity::Space const &affinity_space, Affinity::Location &location,
Name_registry &name_registry, Registry<Parent_service> &parent_services, Registry<Routed_service> &child_services,
Ram_limit_accessor &ram_limit_accessor, Registry<Local_service> &local_services, Pd_intrinsics &pd_intrinsics,
Cap_limit_accessor &cap_limit_accessor, Ealan::Habitat_connection &habitat, Genode::Sandbox::State_handler &habitat_handler)
Cpu_limit_accessor &cpu_limit_accessor, : _env(env), _alloc(alloc), _verbose(verbose), _id(id),
Cpu_quota_transfer &cpu_quota_transfer, _report_update_trigger(report_update_trigger), _habitat_handler(habitat_handler),
Prio_levels prio_levels, _list_element(this), _start_node(_alloc, start_node),
Affinity::Space const &affinity_space, _default_route_accessor(default_route_accessor),
Affinity::Location &location, _default_caps_accessor(default_caps_accessor), _ram_limit_accessor(ram_limit_accessor),
Registry<Parent_service> &parent_services, _cap_limit_accessor(cap_limit_accessor), _cpu_limit_accessor(cpu_limit_accessor),
Registry<Routed_service> &child_services, _cpu_quota_transfer(cpu_quota_transfer), _name_registry(name_registry),
Registry<Local_service> &local_services, _heartbeat_enabled(start_node.has_sub_node("heartbeat")),
Pd_intrinsics &pd_intrinsics, _resources(_resources_from_start_node(start_node, prio_levels, affinity_space, location,
Ealan::Habitat_connection &habitat, default_caps_accessor.default_caps())),
Genode::Sandbox::State_handler &habitat_handler) _pd_intrinsics(pd_intrinsics), _parent_services(parent_services),
: _child_services(child_services), _local_services(local_services),
_env(env), _alloc(alloc), _verbose(verbose), _id(id), _session_requester(_env.ep().rpc_ep(), _env.ram(), _env.rm()), _habitat(habitat),
_report_update_trigger(report_update_trigger), _is_brick(Sandbox::is_brick_from_xml(start_node))
_habitat_handler(habitat_handler), {
_list_element(this),
_start_node(_alloc, start_node),
_default_route_accessor(default_route_accessor),
_default_caps_accessor(default_caps_accessor),
_ram_limit_accessor(ram_limit_accessor),
_cap_limit_accessor(cap_limit_accessor),
_cpu_limit_accessor(cpu_limit_accessor),
_cpu_quota_transfer(cpu_quota_transfer),
_name_registry(name_registry),
_heartbeat_enabled(start_node.has_sub_node("heartbeat")),
_resources(_resources_from_start_node(start_node, prio_levels, affinity_space, location,
default_caps_accessor.default_caps())),
_pd_intrinsics(pd_intrinsics),
_parent_services(parent_services),
_child_services(child_services),
_local_services(local_services),
_session_requester(_env.ep().rpc_ep(), _env.ram(), _env.rm()),
_habitat(habitat){
//log("Creating new cell <", _unique_name, ">"); //log("Creating new cell <", _unique_name, ">");
if (_verbose.enabled()) { if (_verbose.enabled()) {
log("child \"", _unique_name, "\""); log("child \"", _unique_name, "\"");

View File

@@ -390,6 +390,8 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
Ealan::Habitat_connection &_habitat; Ealan::Habitat_connection &_habitat;
bool _is_brick;
/** /**
* CPU-session priority parameters * CPU-session priority parameters
*/ */
@@ -650,7 +652,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
if (_child.active()) { if (_child.active()) {
try { try {
_cell_cap = _habitat.create_cell(_child.pd_session_cap(), _resources.affinity, static_cast<uint16_t>(_priority), Genode::Session_label(_unique_name)); _cell_cap = _habitat.create_cell(_child.pd_session_cap(), _resources.affinity, static_cast<uint16_t>(_priority), Genode::Session_label(_unique_name), _is_brick);
} catch (Ealan::Cell::Cell_creation_error) { } catch (Ealan::Cell::Cell_creation_error) {
Genode::error("Failed to create cell"); Genode::error("Failed to create cell");
abandon(); abandon();
@@ -756,7 +758,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
} }
} }
bool is_brick() { return false; } bool is_brick() { return _is_brick; }
/**************************** /****************************
** Child-policy interface ** ** Child-policy interface **

View File

@@ -55,11 +55,11 @@ class Hoitaja::Core_allocator
Genode::Affinity::Location allocate_cores_for_cell(Genode::Xml_node const &start_node) Genode::Affinity::Location allocate_cores_for_cell(Genode::Xml_node const &start_node)
{ {
/*if (::Sandbox::is_brick_from_xml(start_node)) { if (::Sandbox::is_brick_from_xml(start_node)) {
Genode::Affinity::Location brick = ::Sandbox::affinity_location_from_xml(_affinity_space, start_node); Genode::Affinity::Location brick = ::Sandbox::affinity_location_from_xml(_affinity_space, start_node);
_cores_for_cells -= brick.width(); _cores_for_cells -= brick.width();
return brick; return brick;
}*/ }
// Calculate affinity from global affinity space and priority // Calculate affinity from global affinity space and priority
long priority = ::Sandbox::priority_from_xml(start_node, _prio_levels); long priority = ::Sandbox::priority_from_xml(start_node, _prio_levels);
@@ -73,7 +73,12 @@ class Hoitaja::Core_allocator
} }
void free_cores_from_cell(::Sandbox::Child &cell) void free_cores_from_cell(::Sandbox::Child &cell)
{ {
if (cell.is_brick()) {
_cores_for_cells += cell.resources().affinity.location().width();
return;
}
/* Remove cell's coefficient from the global resource coefficient. /* Remove cell's coefficient from the global resource coefficient.
* This is necessary in order to be able to redistribute the freed resources correctly. We do not trigger the redistribution itself here, because the child has not been fully destroyed yet, thus its resources might still be occupied at this point. */ * This is necessary in order to be able to redistribute the freed resources correctly. We do not trigger the redistribution itself here, because the child has not been fully destroyed yet, thus its resources might still be occupied at this point. */
_resource_coeff -= 1.0 / static_cast<double>(cell.resources().priority); _resource_coeff -= 1.0 / static_cast<double>(cell.resources().priority);
@@ -84,8 +89,11 @@ class Hoitaja::Core_allocator
* *
*/ */
void update(::Sandbox::Child &cell, int *xpos, int *lower_limit) { void update(::Sandbox::Child &cell, int *xpos, int *lower_limit) {
if (cell.abandoned()) if (cell.abandoned()) return;
return;
if (cell.is_brick()) {
return;
}
::Sandbox::Child::Resources resources = cell.resources(); ::Sandbox::Child::Resources resources = cell.resources();
long priority = (resources.priority == 0)? 1 : resources.priority; long priority = (resources.priority == 0)? 1 : resources.priority;