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
{
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()) {}
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())
{
}
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);

View File

@@ -15,6 +15,7 @@
#define _CORE__INCLUDE__CELL_COMPONENT_H_
/* Genode includes */
#include "base/affinity.h"
#include "tukija/stdint.h"
#include <base/rpc_server.h>
#include <base/session_label.h>
@@ -50,7 +51,8 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
Genode::Region_map &_rm;
Genode::Pd_session_capability _pd_cap;
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};
@@ -84,8 +86,14 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
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) {
Tukija::mword_t cell_pd_sel = _native_pd.sel();
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 cip_phys = 0;
/* Allocate a region map for mapping the CIP of this new cell.
@@ -128,9 +136,9 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
_map_location_to_kernel(Genode::Affinity(affinity.space(), Genode::Affinity::Location(0,0,affinity.space().width(), affinity.space().height())));
_ep.manage(this);
}
}
~Cell_component()
~Cell_component()
{
Genode::log("Destroying Cell session");
Core::platform().region_alloc().free(_cip);
@@ -148,10 +156,11 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
void update(Genode::Affinity &affinity) override {
/* TODO: implement */
Genode::log("Changing cell ", _session_label,"'s affinity to ", affinity);
_cip->cores_reserved.clear();
_cip->cores_reserved.clear();
if (_cip->cores_reserved.count() != 0)
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);
Tukija::cell_ctrl(_native_pd.sel(), Tukija::Cell_control::UPDATE_AFFINITY);
}

View File

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

View File

@@ -13,6 +13,7 @@
#ifndef _CORE__HABITAT_SESSION_COMPONENT_H_
#define _CORE__HABITAT_SESSION_COMPONENT_H_
#include "base/affinity.h"
#include "base/ram_allocator.h"
#include "base/stdint.h"
#include "dataspace_component.h"
@@ -41,26 +42,31 @@ class Core::Habitat_session_component : public Genode::Session_object<Ealan::Hab
{
private:
Genode::Region_map &_local_rm;
Genode::Affinity const &_affinity;
Genode::Affinity const _affinity;
Genode::Session_label const &_label;
Genode::Constrained_ram_allocator _ram_alloc;
Genode::Sliced_heap _md_alloc;
Genode::Rpc_entrypoint &_ep;
Genode::List<Ealan::Cell_component> _managed_cells{};
Genode::addr_t _id_base;
Tukija::Habitat_info_page *haip{};
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)
{
unsigned kernel_cpu = Core::platform_specific().kernel_cpu_id(location);
coreset->set(kernel_cpu);
});
}
}
Habitat_session_component(const Habitat_session_component &);
Habitat_session_component& operator=(const Habitat_session_component&);
public:
@@ -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),
_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; });
if (!haip) { Genode::error("Failed to allocate Habitat Info Page"); }
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);
}
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);

View File

@@ -691,22 +691,24 @@ Genode::Affinity Sandbox::Child::filter_session_affinity(Affinity const &session
if (session_affinity.space().total() == 0)
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();
/* scale resolution of resulting space */
Affinity::Space space(child_space.multiply(session_space));
Affinity::Location child_session(child_location.xpos(), child_location.ypos(),
child_location.width() * session_location.width(),
child_location.height() * session_location.height());
/* scale resolution of resulting space */
//Affinity::Space space(child_space.multiply(session_space));
Affinity::Location child_session(child_location.xpos(), child_location.ypos(),
session_location.width(),
session_location.height() );
/* subordinate session affinity to child affinity subspace */
Affinity::Location location(child_session
.multiply_position(session_space)
.transpose(session_location.xpos() * child_location.width(),
session_location.ypos() * child_location.height()));
//.multiply_position(session_space)
.transpose(session_location.xpos() ,
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()) {
log("Creating new core allocator for ", _affinity_space->total(), " cores.");
_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);