mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 20:42:56 +01:00
Update each cell's cores upon cell destruction.
This commit is contained in:
@@ -22,7 +22,9 @@
|
||||
#include <base/heap.h>
|
||||
|
||||
namespace Genode { class Sandbox; }
|
||||
|
||||
namespace Sandbox {
|
||||
class Child;
|
||||
}
|
||||
|
||||
class Genode::Sandbox : Noncopyable
|
||||
{
|
||||
@@ -43,6 +45,7 @@ class Genode::Sandbox : Noncopyable
|
||||
struct State_handler : Interface
|
||||
{
|
||||
virtual void handle_sandbox_state() = 0;
|
||||
virtual void handle_child_state(::Sandbox::Child &child) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -108,8 +111,9 @@ class Genode::Sandbox : Noncopyable
|
||||
* \throw Xml_generator::Buffer_exceeded
|
||||
*/
|
||||
void generate_state_report(Xml_generator &) const;
|
||||
};
|
||||
|
||||
void update(::Sandbox::Child &child);
|
||||
};
|
||||
|
||||
class Genode::Sandbox::Local_service_base : public Service
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <os/reporter.h>
|
||||
#include <base/log.h>
|
||||
#include <tukija/syscall-generic.h>
|
||||
|
||||
#include <child.h>
|
||||
namespace Init {
|
||||
|
||||
using namespace Genode;
|
||||
@@ -27,11 +27,11 @@ namespace Init {
|
||||
}
|
||||
|
||||
|
||||
struct Init::Main : Sandbox::State_handler
|
||||
struct Init::Main : Genode::Sandbox::State_handler
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
Sandbox _sandbox { _env, *this };
|
||||
Genode::Sandbox _sandbox { _env, *this };
|
||||
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
@@ -96,6 +96,16 @@ struct Init::Main : Sandbox::State_handler
|
||||
}
|
||||
}
|
||||
|
||||
void handle_child_state(::Sandbox::Child &child) override {
|
||||
try {
|
||||
Genode::log("Updating sandbox state");
|
||||
_sandbox.update(child);
|
||||
} catch (Genode::Quota_guard<Genode::Cap_quota>::Limit_exceeded) {
|
||||
Genode::log("Caps exceeded while handling child state");
|
||||
_env.parent().exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
_config.sigh(_config_handler);
|
||||
|
||||
@@ -7,6 +7,7 @@ CONFIG_XSD = config.xsd
|
||||
|
||||
# statically link sandbox library to avoid dependency from sandbox.lib.so
|
||||
SRC_CC += library.cc child.cc server.cc config_model.cc
|
||||
INC_DIR += $(REP_DIR)/include
|
||||
INC_DIR += $(REP_DIR)/src/lib/sandbox
|
||||
vpath %.cc $(REP_DIR)/src/lib/sandbox
|
||||
|
||||
|
||||
@@ -755,10 +755,12 @@ Sandbox::Child::Child(Env &env,
|
||||
Registry<Routed_service> &child_services,
|
||||
Registry<Local_service> &local_services,
|
||||
Pd_intrinsics &pd_intrinsics,
|
||||
Ealan::Habitat_connection &habitat)
|
||||
Ealan::Habitat_connection &habitat,
|
||||
Genode::Sandbox::State_handler &habitat_handler)
|
||||
:
|
||||
_env(env), _alloc(alloc), _verbose(verbose), _id(id),
|
||||
_report_update_trigger(report_update_trigger),
|
||||
_habitat_handler(habitat_handler),
|
||||
_list_element(this),
|
||||
_start_node(_alloc, start_node),
|
||||
_default_route_accessor(default_route_accessor),
|
||||
@@ -776,8 +778,7 @@ Sandbox::Child::Child(Env &env,
|
||||
_child_services(child_services),
|
||||
_local_services(local_services),
|
||||
_session_requester(_env.ep().rpc_ep(), _env.ram(), _env.rm()),
|
||||
_habitat(habitat)
|
||||
{
|
||||
_habitat(habitat){
|
||||
log("Creating new cell <", _unique_name, ">");
|
||||
if (_verbose.enabled()) {
|
||||
log("child \"", _unique_name, "\"");
|
||||
|
||||
@@ -35,9 +35,11 @@
|
||||
#include <service.h>
|
||||
#include <utils.h>
|
||||
#include <route_model.h>
|
||||
#include <sandbox/sandbox.h>
|
||||
|
||||
/* EalánOS includes */
|
||||
#include <habitat/connection.h>
|
||||
#include <cell/client.h>
|
||||
|
||||
namespace Sandbox { class Child; }
|
||||
|
||||
@@ -105,6 +107,46 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||
{
|
||||
pd_intrinsics.with_intrinsics(cap, pd, Pd_intrinsics::With_intrinsics::Fn { fn });
|
||||
}
|
||||
|
||||
/**
|
||||
* Resources assigned to the child
|
||||
*/
|
||||
struct Resources
|
||||
{
|
||||
long prio_levels_log2;
|
||||
long priority;
|
||||
Affinity affinity;
|
||||
Ram_quota assigned_ram_quota;
|
||||
Cap_quota assigned_cap_quota;
|
||||
Cpu_quota assigned_cpu_quota;
|
||||
|
||||
Ram_quota effective_ram_quota() const
|
||||
{
|
||||
return Genode::Child::effective_quota(assigned_ram_quota);
|
||||
}
|
||||
|
||||
Cap_quota effective_cap_quota() const
|
||||
{
|
||||
/* capabilities consumed by 'Genode::Child' */
|
||||
Cap_quota const effective =
|
||||
Genode::Child::effective_quota(assigned_cap_quota);
|
||||
|
||||
/* capabilities additionally consumed by init */
|
||||
enum {
|
||||
STATIC_COSTS = 1 /* possible heap backing-store
|
||||
allocation for session object */
|
||||
+ 1 /* buffered XML start node */
|
||||
+ 2 /* dynamic ROM for config */
|
||||
+ 2 /* dynamic ROM for session requester */
|
||||
};
|
||||
|
||||
if (effective.value < STATIC_COSTS)
|
||||
return Cap_quota{0};
|
||||
|
||||
return Cap_quota{effective.value - STATIC_COSTS};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -149,6 +191,8 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||
|
||||
Report_update_trigger &_report_update_trigger;
|
||||
|
||||
Genode::Sandbox::State_handler &_habitat_handler;
|
||||
|
||||
List_element<Child> _list_element;
|
||||
|
||||
Reconstructible<Buffered_xml> _start_node;
|
||||
@@ -237,45 +281,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||
return _heartbeat_enabled && (_state == State::ALIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resources assigned to the child
|
||||
*/
|
||||
struct Resources
|
||||
{
|
||||
long prio_levels_log2;
|
||||
long priority;
|
||||
Affinity affinity;
|
||||
Ram_quota assigned_ram_quota;
|
||||
Cap_quota assigned_cap_quota;
|
||||
Cpu_quota assigned_cpu_quota;
|
||||
|
||||
Ram_quota effective_ram_quota() const
|
||||
{
|
||||
return Genode::Child::effective_quota(assigned_ram_quota);
|
||||
}
|
||||
|
||||
Cap_quota effective_cap_quota() const
|
||||
{
|
||||
/* capabilities consumed by 'Genode::Child' */
|
||||
Cap_quota const effective =
|
||||
Genode::Child::effective_quota(assigned_cap_quota);
|
||||
|
||||
/* capabilities additionally consumed by init */
|
||||
enum {
|
||||
STATIC_COSTS = 1 /* possible heap backing-store
|
||||
allocation for session object */
|
||||
+ 1 /* buffered XML start node */
|
||||
+ 2 /* dynamic ROM for config */
|
||||
+ 2 /* dynamic ROM for session requester */
|
||||
};
|
||||
|
||||
if (effective.value < STATIC_COSTS)
|
||||
return Cap_quota{0};
|
||||
|
||||
return Cap_quota{effective.value - STATIC_COSTS};
|
||||
}
|
||||
};
|
||||
|
||||
static
|
||||
Resources _resources_from_start_node(Xml_node start_node, Prio_levels prio_levels,
|
||||
Affinity::Space const &affinity_space, Affinity::Location const &location,
|
||||
@@ -421,6 +426,8 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||
|
||||
Genode::Child _child { _env.rm(), _env.ep().rpc_ep(), *this };
|
||||
|
||||
Ealan::Cell_capability _cell_cap { };
|
||||
|
||||
struct Pd_accessor : Routed_service::Pd_accessor
|
||||
{
|
||||
Genode::Child &_child;
|
||||
@@ -528,6 +535,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||
bool _exited { false };
|
||||
int _exit_value { -1 };
|
||||
|
||||
|
||||
/**
|
||||
* Return true if it's safe to call the PD for requesting resource
|
||||
* information
|
||||
@@ -606,7 +614,8 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||
Registry<Routed_service> &child_services,
|
||||
Registry<Local_service> &local_services,
|
||||
Pd_intrinsics &pd_intrinsics,
|
||||
Ealan::Habitat_connection &habitat);
|
||||
Ealan::Habitat_connection &habitat,
|
||||
Genode::Sandbox::State_handler &habitat_handler);
|
||||
|
||||
virtual ~Child();
|
||||
|
||||
@@ -640,8 +649,9 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||
_child.initiate_env_sessions();
|
||||
|
||||
if (_child.active()) {
|
||||
_habitat.create_cell(_child.pd_session_cap(), _resources.affinity, static_cast<uint16_t>(_priority));
|
||||
_state = State::ALIVE;
|
||||
_cell_cap = _habitat.create_cell(_child.pd_session_cap(), _resources.affinity, static_cast<uint16_t>(_priority), Genode::Session_label(_unique_name));
|
||||
Genode::log("Created new cell ", _unique_name, " ", _cell_cap);
|
||||
_state = State::ALIVE;
|
||||
} else
|
||||
_uncertain_dependencies = true;
|
||||
}
|
||||
@@ -668,6 +678,8 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||
bool restart_scheduled() const { return _state == State::RESTART_SCHEDULED; }
|
||||
|
||||
bool stuck() const { return _state == State::STUCK; }
|
||||
|
||||
bool exited() { return _exited; }
|
||||
|
||||
bool env_sessions_closed() const { return _child.env_sessions_closed(); }
|
||||
|
||||
@@ -726,19 +738,16 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||
|
||||
struct Resources &resources() { return _resources; }
|
||||
|
||||
void update_affinity(Genode::Affinity affinity) {
|
||||
//Genode::log("Updating affinity to ", affinity.location(), " in space ", affinity.space());
|
||||
void update(Genode::Affinity affinity) {
|
||||
Genode::log("Updating affinity to ", affinity.location(), " in space ", affinity.space());
|
||||
_resources.affinity = affinity;
|
||||
//Genode::log("Moving CPU session ", _env.cpu_session_cap());
|
||||
if (_child.active()) {
|
||||
}
|
||||
}
|
||||
|
||||
void shrink_cores(Genode::Affinity::Location &cores) {
|
||||
}
|
||||
|
||||
void grow_cores(Genode::Affinity::Location &cores) {
|
||||
}
|
||||
Ealan::Cell_client cell(_cell_cap);
|
||||
Genode::log("Updating cell ", _cell_cap);
|
||||
cell.update(affinity);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_brick() { return false; }
|
||||
|
||||
@@ -800,6 +809,9 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||
* printed by the default implementation of 'Child_policy::exit'.
|
||||
*/
|
||||
Child_policy::exit(exit_value);
|
||||
|
||||
Genode::log("Notifying Hoitaja");
|
||||
_habitat_handler.handle_child_state(*this);
|
||||
}
|
||||
|
||||
void session_state_changed() override
|
||||
|
||||
@@ -86,7 +86,7 @@ class Hoitaja::Core_allocator
|
||||
void update(::Sandbox::Child &cell, int *xpos, int *lower_limit) {
|
||||
if (cell.abandoned())
|
||||
return;
|
||||
/*::Sandbox::Child::Resources resources = cell.resources();
|
||||
::Sandbox::Child::Resources resources = cell.resources();
|
||||
long priority = (resources.priority == 0)? 1 : resources.priority;
|
||||
|
||||
unsigned int cores_share = _calculate_resource_share(priority);
|
||||
@@ -100,13 +100,14 @@ class Hoitaja::Core_allocator
|
||||
|
||||
Genode::Affinity::Location location(*xpos - cores_share, resources.affinity.location().ypos(), cores_share, resources.affinity.location().height());
|
||||
|
||||
if (resources.affinity.location() != location) { // Only update, if location has actually changed
|
||||
/*if (resources.affinity.location() != location) { // Only update, if location has actually changed
|
||||
cell.update_affinity(Genode::Affinity(resources.affinity.space(), location));
|
||||
}
|
||||
|
||||
if (location.width() > resources.affinity.location().width()) {
|
||||
cell.grow_cores(location);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
*xpos = location.xpos();
|
||||
// TODO: Update affinity of existing sessions for cell
|
||||
@@ -114,8 +115,9 @@ class Hoitaja::Core_allocator
|
||||
|
||||
if (cores_to_reclaim > 0) {
|
||||
log("Need to reclaim ", cores_to_reclaim, " cores from ", cell.name());
|
||||
cell.shrink_cores(location);
|
||||
}*/
|
||||
}
|
||||
|
||||
cell.update(Genode::Affinity(resources.affinity.space(), location));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
||||
Constructible<Affinity::Space> _affinity_space { };
|
||||
Preservation _preservation { };
|
||||
|
||||
State_handler &_habitat_handler;
|
||||
|
||||
Affinity::Space _effective_affinity_space() const
|
||||
{
|
||||
return _affinity_space.constructed() ? *_affinity_space
|
||||
@@ -289,7 +291,7 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
||||
State_handler &state_handler, Pd_intrinsics &pd_intrinsics)
|
||||
:
|
||||
_env(env), _heap(heap), _core_allocator(), _pd_intrinsics(pd_intrinsics),
|
||||
_local_services(local_services), _state_reporter(_env, *this, state_handler)
|
||||
_local_services(local_services), _habitat_handler(state_handler), _state_reporter(_env, *this, state_handler)
|
||||
{ }
|
||||
|
||||
Library(Env &env, Heap &heap, Registry<Local_service> &local_services,
|
||||
@@ -304,8 +306,18 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
||||
{
|
||||
_state_reporter.generate(xml);
|
||||
}
|
||||
};
|
||||
|
||||
void maintain_cells();
|
||||
|
||||
void update(Child &child) {
|
||||
if (child.exited()) {
|
||||
_children.remove(&child);
|
||||
_core_allocator->free_cores_from_cell(child);
|
||||
Genode::log("Starting new maintenance cycle");
|
||||
maintain_cells();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void Genode::Sandbox::Library::_destroy_abandoned_parent_services()
|
||||
{
|
||||
@@ -400,9 +412,11 @@ bool Genode::Sandbox::Library::ready_to_create_child(Start_model::Name const
|
||||
start_node, *this, *this, _children, *this, *this, *this, *this,
|
||||
_prio_levels, _effective_affinity_space(), allocation,
|
||||
_parent_services, _child_services, _local_services,
|
||||
_pd_intrinsics, *_habitat);
|
||||
_pd_intrinsics, *_habitat, _habitat_handler);
|
||||
_children.insert(&child);
|
||||
|
||||
maintain_cells();
|
||||
|
||||
_avail_cpu.percent -= min(_avail_cpu.percent, child.cpu_quota().percent);
|
||||
|
||||
if (start_node.has_sub_node("provides"))
|
||||
@@ -537,6 +551,16 @@ void Genode::Sandbox::Library::apply_config(Xml_node const &config)
|
||||
_state_reporter.trigger_immediate_report_update();
|
||||
}
|
||||
|
||||
void Genode::Sandbox::Library::maintain_cells()
|
||||
{
|
||||
int xpos = _affinity_space->total();
|
||||
int lower_limit = _affinity_space->total() - _core_allocator->cores_available();
|
||||
_children.for_each_child([&](Child &child)
|
||||
{
|
||||
log(child.name(), " ram: ", child.ram_quota());
|
||||
if (!(child.is_brick()))
|
||||
_core_allocator->update(child, &xpos, &lower_limit); });
|
||||
}
|
||||
|
||||
/*********************************
|
||||
** Sandbox::Local_service_base **
|
||||
@@ -682,6 +706,10 @@ void Genode::Sandbox::generate_state_report(Xml_generator &xml) const
|
||||
_library.generate_state_report(xml);
|
||||
}
|
||||
|
||||
void Genode::Sandbox::update(::Sandbox::Child &child)
|
||||
{
|
||||
_library.update(child);
|
||||
}
|
||||
|
||||
Genode::Sandbox::Sandbox(Env &env, State_handler &state_handler, Pd_intrinsics &pd_intrinsics)
|
||||
:
|
||||
|
||||
Reference in New Issue
Block a user