ealanos: Fixed affinities when nesting habitats.

This commit is contained in:
Michael Mueller
2025-12-09 19:56:17 +01:00
parent 2a6cb2a97f
commit 17befa5c44
6 changed files with 67 additions and 29 deletions

View File

@@ -25,8 +25,13 @@ namespace Ealan { struct Habitat_connection; }
struct Ealan::Habitat_connection : Genode::Connection<Ealan::Habitat_session>, Habitat_client struct Ealan::Habitat_connection : Genode::Connection<Ealan::Habitat_session>, Habitat_client
{ {
Habitat_connection(Genode::Env &env, Genode::Affinity &affinity, Label const &label = Label()) Habitat_connection(Genode::Env &env, Genode::Affinity &affinity,
: Connection<Habitat_session>(env, label, Genode::Ram_quota { RAM_QUOTA }, affinity, Args("")), Habitat_client(cap()) {} Label const &label = Label())
: 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, bool is_brick) 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, is_brick); return Habitat_client::create_cell(pd_cap, affinity, prio, label, is_brick);

View File

@@ -15,6 +15,7 @@
#define _CORE__INCLUDE__CELL_COMPONENT_H_ #define _CORE__INCLUDE__CELL_COMPONENT_H_
/* Genode includes */ /* Genode includes */
#include "base/affinity.h"
#include "tukija/stdint.h" #include "tukija/stdint.h"
#include <base/rpc_server.h> #include <base/rpc_server.h>
#include <base/session_label.h> #include <base/session_label.h>
@@ -51,6 +52,7 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
Genode::Pd_session_capability _pd_cap; Genode::Pd_session_capability _pd_cap;
Genode::Pd_session_client _pd; Genode::Pd_session_client _pd;
Genode::Tukija_native_pd_client _native_pd; Genode::Tukija_native_pd_client _native_pd;
Genode::Affinity _habitat;
Tukija::Cip *_cip{nullptr}; Tukija::Cip *_cip{nullptr};
@@ -84,7 +86,13 @@ 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, bool is_brick, Tukija::mword_t habitat_sel) : _ep(ep), _session_label(label), _rm(rm), _pd_cap(pd_cap), _pd(pd_cap), _native_pd(_pd.native_pd()), _is_brick(is_brick) { 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,
Tukija::mword_t habitat_sel, Genode::Affinity habitat_affinity)
: _ep(ep), _session_label(label), _rm(rm), _pd_cap(pd_cap), _pd(pd_cap),
_native_pd(_pd.native_pd()), _habitat(habitat_affinity), _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;
@@ -149,9 +157,10 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
/* TODO: implement */ /* TODO: implement */
Genode::log("Changing cell ", _session_label,"'s affinity to ", affinity); Genode::log("Changing cell ", _session_label,"'s affinity to ", affinity);
_cip->cores_reserved.clear(); _cip->cores_reserved.clear();
if (_cip->cores_reserved.count() != 0) if (_cip->cores_reserved.count() != 0)
Genode::error("Failed clearing reserved cores"); Genode::error("Failed clearing reserved cores");
_calculate_mask_for_location(&_cip->cores_reserved, affinity.location()); _calculate_mask_for_location(&_cip->cores_reserved, affinity.location().transpose(_habitat.location().xpos(), _habitat.location().ypos()));
Genode::log(_session_label, "'s cores: ", _cip->cores_reserved); Genode::log(_session_label, "'s cores: ", _cip->cores_reserved);
Tukija::cell_ctrl(_native_pd.sel(), Tukija::Cell_control::UPDATE_AFFINITY); Tukija::cell_ctrl(_native_pd.sel(), Tukija::Cell_control::UPDATE_AFFINITY);
} }

View File

@@ -1,6 +1,8 @@
#ifndef __CORE_HABITAT_ROOT_H #ifndef __CORE_HABITAT_ROOT_H
#define __CORE_HABITAT_ROOT_H #define __CORE_HABITAT_ROOT_H
#include "base/affinity.h"
#include "platform_generic.h"
#include <root/component.h> #include <root/component.h>
#include <base/log.h> #include <base/log.h>
@@ -20,6 +22,8 @@ namespace Core {
Habitat_session_component *_create_session(char const *args, Genode::Affinity const &affinity) override { Habitat_session_component *_create_session(char const *args, Genode::Affinity const &affinity) override {
Genode::log("Creating new habitat ", affinity);
size_t ram_quota = size_t ram_quota =
Arg_string::find_arg(args, "ram_quota").ulong_value(0); Arg_string::find_arg(args, "ram_quota").ulong_value(0);
@@ -31,6 +35,10 @@ namespace Core {
throw Genode::Service_denied(); throw Genode::Service_denied();
} }
Genode::Affinity::Location session_location =
affinity.scale_to(Core::platform().affinity_space());
return new (md_alloc()) Habitat_session_component( return new (md_alloc()) Habitat_session_component(
*this->ep(), *this->ep(),
session_resources_from_args(args), session_resources_from_args(args),
@@ -38,7 +46,7 @@ namespace Core {
session_diag_from_args(args), session_diag_from_args(args),
_ram_alloc, _ram_alloc,
_local_rm, _local_rm,
affinity); Genode::Affinity(Core::platform().affinity_space(), session_location));
} }
void _upgrade_session(Habitat_session_component *habitat, const char *args) override void _upgrade_session(Habitat_session_component *habitat, const char *args) override

View File

@@ -13,6 +13,7 @@
#ifndef _CORE__HABITAT_SESSION_COMPONENT_H_ #ifndef _CORE__HABITAT_SESSION_COMPONENT_H_
#define _CORE__HABITAT_SESSION_COMPONENT_H_ #define _CORE__HABITAT_SESSION_COMPONENT_H_
#include "base/affinity.h"
#include "base/ram_allocator.h" #include "base/ram_allocator.h"
#include "base/stdint.h" #include "base/stdint.h"
#include "dataspace_component.h" #include "dataspace_component.h"
@@ -41,20 +42,21 @@ class Core::Habitat_session_component : public Genode::Session_object<Ealan::Hab
{ {
private: private:
Genode::Region_map &_local_rm; Genode::Region_map &_local_rm;
Genode::Affinity const &_affinity; Genode::Affinity const _affinity;
Genode::Session_label const &_label; Genode::Session_label const &_label;
Genode::Constrained_ram_allocator _ram_alloc; Genode::Constrained_ram_allocator _ram_alloc;
Genode::Sliced_heap _md_alloc; Genode::Sliced_heap _md_alloc;
Genode::Rpc_entrypoint &_ep; Genode::Rpc_entrypoint &_ep;
Genode::List<Ealan::Cell_component> _managed_cells{}; Genode::List<Ealan::Cell_component> _managed_cells{};
Genode::addr_t _id_base; Genode::addr_t _id_base;
Tukija::Habitat_info_page *haip{};
Genode::addr_t _sel() const { return _id_base; } Genode::addr_t _sel() const { return _id_base; }
void _calculate_mask_for_location(Tukija::Cpuset *coreset, const Genode::Affinity::Space &space) void _calculate_mask_for_location(Tukija::Cpuset *coreset, const Genode::Affinity::Location &location)
{ {
const_cast<Genode::Affinity::Space&>(space).for_each( const_cast<Genode::Affinity::Location&>(location).for_each(
[&](Genode::Affinity::Location const &location) [&](Genode::Affinity::Location const &location)
{ {
unsigned kernel_cpu = Core::platform_specific().kernel_cpu_id(location); unsigned kernel_cpu = Core::platform_specific().kernel_cpu_id(location);
@@ -62,6 +64,10 @@ class Core::Habitat_session_component : public Genode::Session_object<Ealan::Hab
}); });
} }
Habitat_session_component(const Habitat_session_component &);
Habitat_session_component& operator=(const Habitat_session_component&);
public: public:
Habitat_session_component(Genode::Rpc_entrypoint &ep, Habitat_session_component(Genode::Rpc_entrypoint &ep,
@@ -74,22 +80,30 @@ class Core::Habitat_session_component : public Genode::Session_object<Ealan::Hab
_ram_alloc(ram, _ram_quota_guard(), _cap_quota_guard()), _md_alloc(_ram_alloc, rm), _ram_alloc(ram, _ram_quota_guard(), _cap_quota_guard()), _md_alloc(_ram_alloc, rm),
_ep(ep), _id_base(cap_map().insert(1)) _ep(ep), _id_base(cap_map().insert(1))
{ {
Genode::log("Habitat's affinity is ", _affinity);
Tukija::Habitat_info_page *haip;
Core::platform().region_alloc().alloc_aligned(Tukija::PAGE_SIZE_BYTE, Tukija::PAGE_SIZE_LOG2).with_result([&](void *ptr) { haip = static_cast<Tukija::Habitat_info_page*>(ptr); }, [&](Genode::Range_allocator::Alloc_error) { haip = nullptr; }); Core::platform().region_alloc().alloc_aligned(Tukija::PAGE_SIZE_BYTE, Tukija::PAGE_SIZE_LOG2).with_result([&](void *ptr) { haip = static_cast<Tukija::Habitat_info_page*>(ptr); }, [&](Genode::Range_allocator::Alloc_error) { haip = nullptr; });
if (!haip) { Genode::error("Failed to allocate Habitat Info Page"); } if (!haip) { Genode::error("Failed to allocate Habitat Info Page"); }
Tukija::create_habitat(_sel(), reinterpret_cast<Tukija::mword_t>(haip)); Tukija::create_habitat(_sel(), reinterpret_cast<Tukija::mword_t>(haip));
_calculate_mask_for_location(&haip->reserved_cores, _affinity.space()); _calculate_mask_for_location(&haip->reserved_cores, _affinity.location());
Genode::log("Created habitat: ", haip->reserved_cores); Genode::log("Created habitat: ", haip->reserved_cores);
} }
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_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, is_brick, _sel()); Genode::log("Habitat ", _affinity);
Genode::log(haip->reserved_cores);
Genode::Affinity::Location location = affinity.location().transpose(
_affinity.location().xpos(), _affinity.location().ypos());
Genode::Affinity session_affinity(Core::platform().affinity_space(), location);
Genode::log(label, ": ", affinity, "->", session_affinity);
Ealan::Cell_component *cell = new (_md_alloc) Ealan::Cell_component(pd_cap, prio, session_affinity, _ep, _local_rm, label, is_brick, _sel(), _affinity);
_managed_cells.insert(cell); _managed_cells.insert(cell);

View File

@@ -691,22 +691,24 @@ Genode::Affinity Sandbox::Child::filter_session_affinity(Affinity const &session
if (session_affinity.space().total() == 0) if (session_affinity.space().total() == 0)
return Affinity(child_space, child_location); return Affinity(child_space, child_location);
Affinity::Space const &session_space = session_affinity.space(); //Affinity::Space const &session_space = session_affinity.space();
Affinity::Location const &session_location = session_affinity.location(); Affinity::Location const &session_location = session_affinity.location();
/* scale resolution of resulting space */ /* scale resolution of resulting space */
Affinity::Space space(child_space.multiply(session_space)); //Affinity::Space space(child_space.multiply(session_space));
Affinity::Location child_session(child_location.xpos(), child_location.ypos(), Affinity::Location child_session(child_location.xpos(), child_location.ypos(),
child_location.width() * session_location.width(), session_location.width(),
child_location.height() * session_location.height()); session_location.height() );
/* subordinate session affinity to child affinity subspace */ /* subordinate session affinity to child affinity subspace */
Affinity::Location location(child_session Affinity::Location location(child_session
.multiply_position(session_space) //.multiply_position(session_space)
.transpose(session_location.xpos() * child_location.width(), .transpose(session_location.xpos() ,
session_location.ypos() * child_location.height())); session_location.ypos() ));
return Affinity(space, location); return Affinity(child_space, location);
} }

View File

@@ -467,7 +467,7 @@ bool Genode::Sandbox::Library::ready_to_create_child(Start_model::Name const
if (_affinity_space.constructed() && !_core_allocator.constructed()) { if (_affinity_space.constructed() && !_core_allocator.constructed()) {
log("Creating new core allocator for ", _affinity_space->total(), " cores."); log("Creating new core allocator for ", _affinity_space->total(), " cores.");
_core_allocator.construct(*_affinity_space, _prio_levels); _core_allocator.construct(*_affinity_space, _prio_levels);
_habitat.construct(_env, Affinity(*_affinity_space, Affinity::Location(0,0))); _habitat.construct(_env, Affinity(*_affinity_space, Affinity::Location(0,0, _affinity_space->width(), _affinity_space->height())));
} }
Affinity::Location allocation = _core_allocator->allocate_cores_for_cell(start_node); Affinity::Location allocation = _core_allocator->allocate_cores_for_cell(start_node);