diff --git a/repos/gems/src/app/sculpt_manager/deploy.h b/repos/gems/src/app/sculpt_manager/deploy.h index 3bf5297ed7..d39da81484 100644 --- a/repos/gems/src/app/sculpt_manager/deploy.h +++ b/repos/gems/src/app/sculpt_manager/deploy.h @@ -62,12 +62,16 @@ struct Sculpt::Deploy Arch _arch { }; Child_state cached_depot_rom_state { - _child_states, "depot_rom", Priority::STORAGE, - Ram_quota{24*1024*1024}, Cap_quota{200} }; + _child_states, { .name = "depot_rom", + .priority = Priority::STORAGE, + .initial = { Ram_quota{24*1024*1024}, Cap_quota{200} }, + .max = { Ram_quota{2*1024*1024*1024UL}, { } } } }; Child_state uncached_depot_rom_state { - _child_states, "dynamic_depot_rom", Priority::STORAGE, - Ram_quota{8*1024*1024}, Cap_quota{200} }; + _child_states, { .name = "dynamic_depot_rom", + .priority = Priority::STORAGE, + .initial = { Ram_quota{8*1024*1024}, Cap_quota{200} }, + .max = { Ram_quota{2*1024*1024*1024UL}, { } } } }; /* * Report written to '/config/managed/deploy' diff --git a/repos/gems/src/app/sculpt_manager/model/child_state.h b/repos/gems/src/app/sculpt_manager/model/child_state.h index 9ce39f71da..abad939971 100644 --- a/repos/gems/src/app/sculpt_manager/model/child_state.h +++ b/repos/gems/src/app/sculpt_manager/model/child_state.h @@ -30,43 +30,58 @@ struct Sculpt::Child_state : Noncopyable struct Version { unsigned value; }; + struct Attr + { + Start_name name; + Priority priority; + + struct Initial { Ram_quota ram; Cap_quota caps; } initial; + struct Max { Ram_quota ram; Cap_quota caps; } max; + + static constexpr Max DEFAULT_MAX = { .ram = { 256*1024*1024 }, + .caps = { 5000 } }; + }; + private: Registry::Element _element; - Start_name const _name; + Attr const _attr; - Priority const _priority; + static Attr _init_attr(Attr const attr) + { + Attr result = attr; + if (!result.max.ram .value) result.max.ram = Attr::DEFAULT_MAX.ram; + if (!result.max.caps.value) result.max.caps = Attr::DEFAULT_MAX.caps; + return result; + } - Ram_quota const _initial_ram_quota; - Cap_quota const _initial_cap_quota; + Ram_quota _ram_quota = _attr.initial.ram; + Cap_quota _cap_quota = _attr.initial.caps; - Ram_quota _ram_quota = _initial_ram_quota; - Cap_quota _cap_quota = _initial_cap_quota; + struct Warned_once { bool ram, caps; } _warned_once { }; Version _version { 0 }; public: - /** - * Constructor - * - * \param ram_quota initial RAM quota - * \param cap_quota initial capability quota - */ - Child_state(Registry ®istry, Start_name const &name, - Priority priority, Ram_quota ram_quota, Cap_quota cap_quota) + Child_state(Registry ®istry, Attr const attr) + : _element(registry, *this), _attr(_init_attr(attr)) { } + + Child_state(Registry ®istry, auto const &name, + Priority priority, Ram_quota initial_ram, Cap_quota initial_caps) : - _element(registry, *this), - _name(name), _priority(priority), - _initial_ram_quota(ram_quota), _initial_cap_quota(cap_quota) + Child_state(registry, { .name = name, + .priority = priority, + .initial = { initial_ram, initial_caps }, + .max = { } }) { } void trigger_restart() { _version.value++; - _ram_quota = _initial_ram_quota; - _cap_quota = _initial_cap_quota; + _ram_quota = _attr.initial.ram; + _cap_quota = _attr.initial.caps; } void gen_start_node_version(Xml_generator &xml) const @@ -77,12 +92,12 @@ struct Sculpt::Child_state : Noncopyable void gen_start_node_content(Xml_generator &xml) const { - xml.attribute("name", _name); + xml.attribute("name", _attr.name); gen_start_node_version(xml); xml.attribute("caps", _cap_quota.value); - xml.attribute("priority", (int)_priority); + xml.attribute("priority", (int)_attr.priority); gen_named_node(xml, "resource", "RAM", [&] { Number_of_bytes const bytes(_ram_quota.value); xml.attribute("quantum", String<64>(bytes)); }); @@ -102,25 +117,33 @@ struct Sculpt::Child_state : Noncopyable { bool result = false; - if (child.attribute_value("name", Start_name()) != _name) + if (child.attribute_value("name", Start_name()) != _attr.name) return false; - if (child.has_sub_node("ram") && child.sub_node("ram").has_attribute("requested")) { - _ram_quota.value = min(_ram_quota.value*2, 256*1024*1024u); - result = true; - } + auto upgrade = [&] (auto const &msg, auto "a, auto &max_quota, bool &warned_once) + { + if (quota.value == max_quota.value) { + if (!warned_once) + warning(msg, " consumption of ", _attr.name, " exceeeded maximum of ", max_quota); + warned_once = true; + } else { + quota.value = min(quota.value*2, max_quota.value); + result = true; + } + }; - if (child.has_sub_node("caps") && child.sub_node("caps").has_attribute("requested")) { - _cap_quota.value = min(_cap_quota.value + 100, 5000u); - result = true; - } + if (child.has_sub_node("ram") && child.sub_node("ram").has_attribute("requested")) + upgrade("RAM", _ram_quota, _attr.max.ram, _warned_once.ram); + + if (child.has_sub_node("caps") && child.sub_node("caps").has_attribute("requested")) + upgrade("caps", _cap_quota, _attr.max.caps, _warned_once.caps); return result; } Ram_quota ram_quota() const { return _ram_quota; } - Start_name name() const { return _name; } + Start_name name() const { return _attr.name; } }; #endif /* _MODEL__CHILD_STATE_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/model/ram_fs_state.h b/repos/gems/src/app/sculpt_manager/model/ram_fs_state.h index 0288f3340c..21493e07bf 100644 --- a/repos/gems/src/app/sculpt_manager/model/ram_fs_state.h +++ b/repos/gems/src/app/sculpt_manager/model/ram_fs_state.h @@ -34,8 +34,10 @@ struct Sculpt::Ram_fs_state : Child_state, File_system Ram_fs_state(Registry ®istry, Start_name const &name) : - Child_state(registry, name, Priority::LEITZENTRALE, - Ram_quota{1024*1024}, Cap_quota{300}), + Child_state(registry, { .name = name, + .priority = Priority::LEITZENTRALE, + .initial = { Ram_quota{1024*1024}, Cap_quota{300} }, + .max = { Ram_quota{2*1024*1024*1024UL}, { } } }), File_system(File_system::UNKNOWN) { } };