diff --git a/repos/base-foc/src/core/include/vm_session_component.h b/repos/base-foc/src/core/include/vm_session_component.h index b0408087c..96d7ee664 100644 --- a/repos/base-foc/src/core/include/vm_session_component.h +++ b/repos/base-foc/src/core/include/vm_session_component.h @@ -15,7 +15,6 @@ #define _CORE__VM_SESSION_COMPONENT_H_ /* Genode includes */ -#include #include #include #include diff --git a/repos/base-nova/src/core/include/vm_session_component.h b/repos/base-nova/src/core/include/vm_session_component.h index 748d0397f..7ed695fde 100644 --- a/repos/base-nova/src/core/include/vm_session_component.h +++ b/repos/base-nova/src/core/include/vm_session_component.h @@ -15,11 +15,8 @@ #define _CORE__VM_SESSION_COMPONENT_H_ /* Genode includes */ -#include #include - #include - #include #include diff --git a/repos/base-sel4/src/core/include/vm_session_component.h b/repos/base-sel4/src/core/include/vm_session_component.h index 63544ea75..e1348df2a 100644 --- a/repos/base-sel4/src/core/include/vm_session_component.h +++ b/repos/base-sel4/src/core/include/vm_session_component.h @@ -15,7 +15,6 @@ #define _CORE__VM_SESSION_COMPONENT_H_ /* Genode includes */ -#include #include #include diff --git a/repos/base/include/base/connection.h b/repos/base/include/base/connection.h index bfa29aab7..d242603af 100644 --- a/repos/base/include/base/connection.h +++ b/repos/base/include/base/connection.h @@ -14,6 +14,7 @@ #ifndef _INCLUDE__BASE__CONNECTION_H_ #define _INCLUDE__BASE__CONNECTION_H_ +#include #include #include #include @@ -52,7 +53,6 @@ class Genode::Connection_base : Noncopyable, Interface */ Connection_base(); - void upgrade(Session::Resources resources) { String<80> const args("ram_quota=", resources.ram_quota, ", " @@ -69,6 +69,29 @@ class Genode::Connection_base : Noncopyable, Interface { upgrade(Session::Resources { Ram_quota{0}, Cap_quota{caps} }); } + + /** + * Extend session quota on demand while calling an RPC function + * + * \param ram amount of RAM to upgrade as response to 'Out_of_ram' + * \param caps amount of caps to upgrade as response to 'Out_of_caps' + * + * \noapi + */ + template + auto retry_with_upgrade(Ram_quota ram, Cap_quota caps, FUNC func) -> decltype(func()) + { + enum { UPGRADE_ATTEMPTS = ~0U }; + return Genode::retry( + [&] () { + return Genode::retry( + [&] () { return func(); }, + [&] () { upgrade_caps(caps.value); }, + UPGRADE_ATTEMPTS); + }, + [&] () { upgrade_ram(ram.value); }, + UPGRADE_ATTEMPTS); + } }; diff --git a/repos/base/include/base/ram_allocator.h b/repos/base/include/base/ram_allocator.h index 84baf7b8d..03a6dc60b 100644 --- a/repos/base/include/base/ram_allocator.h +++ b/repos/base/include/base/ram_allocator.h @@ -82,7 +82,7 @@ class Genode::Constrained_ram_allocator : public Ram_allocator _ram_alloc(ram_alloc), _ram_guard(ram_guard), _cap_guard(cap_guard) { } - Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override + Ram_dataspace_capability alloc(size_t size, Cache_attribute cached = CACHED) override { size_t page_aligned_size = align_addr(size, 12); diff --git a/repos/base/include/cpu_session/connection.h b/repos/base/include/cpu_session/connection.h index 8a2af3536..ac0368abf 100644 --- a/repos/base/include/cpu_session/connection.h +++ b/repos/base/include/cpu_session/connection.h @@ -41,6 +41,16 @@ struct Genode::Cpu_connection : Connection, Cpu_session_client priority, RAM_QUOTA, CAP_QUOTA, label)), Cpu_session_client(cap()) { } + + Thread_capability create_thread(Capability pd, + Name const &name, + Affinity::Location affinity, + Weight weight, + addr_t utcb = 0) override + { + return retry_with_upgrade(Ram_quota{8*1024}, Cap_quota{2}, [&] () { + return Cpu_session_client::create_thread(pd, name, affinity, weight, utcb); }); + } }; #endif /* _INCLUDE__CPU_SESSION__CONNECTION_H_ */ diff --git a/repos/base/include/cpu_session/cpu_session.h b/repos/base/include/cpu_session/cpu_session.h index 63f61bfb8..8b2253ca0 100644 --- a/repos/base/include/cpu_session/cpu_session.h +++ b/repos/base/include/cpu_session/cpu_session.h @@ -43,7 +43,7 @@ struct Genode::Cpu_session : Session * allocation, its session capability, the capability of the 'Native_cpu' * RPC interface, and a capability for the trace-control dataspace. */ - enum { CAP_QUOTA = 4 }; + enum { CAP_QUOTA = 6 }; typedef Cpu_session_client Client; diff --git a/repos/base/include/trace_session/client.h b/repos/base/include/trace_session/client.h index ac61e0439..d5df12eba 100644 --- a/repos/base/include/trace_session/client.h +++ b/repos/base/include/trace_session/client.h @@ -77,7 +77,7 @@ struct Genode::Trace::Session_client : Genode::Rpc_client(), dst_len); diff --git a/repos/base/include/trace_session/connection.h b/repos/base/include/trace_session/connection.h index 640fc3e04..6a7c6e753 100644 --- a/repos/base/include/trace_session/connection.h +++ b/repos/base/include/trace_session/connection.h @@ -14,6 +14,7 @@ #ifndef _INCLUDE__TRACE_SESSION__CONNECTION_H_ #define _INCLUDE__TRACE_SESSION__CONNECTION_H_ +#include #include #include @@ -23,6 +24,12 @@ namespace Genode { namespace Trace { struct Connection; } } struct Genode::Trace::Connection : Genode::Connection, Genode::Trace::Session_client { + template + auto _retry(FUNC func) -> decltype(func()) + { + return retry_with_upgrade(Ram_quota{8*1024}, Cap_quota{2}, func); + } + /** * Constructor * @@ -34,9 +41,33 @@ struct Genode::Trace::Connection : Genode::Connection, : Genode::Connection(env, session(env.parent(), "ram_quota=%lu, arg_buffer_size=%lu, parent_levels=%u", - ram_quota + 2048, arg_buffer_size, parent_levels)), + ram_quota + 10*1024, arg_buffer_size, parent_levels)), Session_client(env.rm(), cap()) { } + + Policy_id alloc_policy(size_t size) override + { + return _retry([&] () { + return Session_client::alloc_policy(size); }); + } + + void trace(Subject_id s, Policy_id p, size_t buffer_size) override + { + _retry([&] () { Session_client::trace(s, p, buffer_size); }); + } + + size_t subjects(Subject_id *dst, size_t dst_len) override + { + return _retry([&] () { + return Session_client::subjects(dst, dst_len); }); + } + + template + size_t for_each_subject_info(FN const &fn) + { + return _retry([&] () { + return Session_client::for_each_subject_info(fn); }); + } }; #endif /* _INCLUDE__TRACE_SESSION__CONNECTION_H_ */ diff --git a/repos/base/include/trace_session/trace_session.h b/repos/base/include/trace_session/trace_session.h index 0db6d3c9f..b180edb2e 100644 --- a/repos/base/include/trace_session/trace_session.h +++ b/repos/base/include/trace_session/trace_session.h @@ -29,7 +29,7 @@ struct Genode::Trace::Session : Genode::Session */ static const char *service_name() { return "TRACE"; } - enum { CAP_QUOTA = 4 }; + enum { CAP_QUOTA = 6 }; /** * Allocate policy-module backing store diff --git a/repos/base/src/core/cpu_session_component.cc b/repos/base/src/core/cpu_session_component.cc index f34b8399c..e16fb25e1 100644 --- a/repos/base/src/core/cpu_session_component.cc +++ b/repos/base/src/core/cpu_session_component.cc @@ -34,9 +34,7 @@ Thread_capability Cpu_session_component::create_thread(Capability pd { Trace::Thread_name thread_name(name.string()); - if (!_md_alloc.withdraw(_utcb_quota_size())) { - throw Out_of_ram(); - } + withdraw(Ram_quota{_utcb_quota_size()}); Cpu_thread_component *thread = 0; @@ -126,7 +124,7 @@ void Cpu_session_component::_unsynchronized_kill_thread(Thread_capability thread destroy(&_thread_alloc, thread); } - _md_alloc.upgrade(_utcb_quota_size()); + replenish(Ram_quota{_utcb_quota_size()}); } @@ -174,17 +172,6 @@ Dataspace_capability Cpu_session_component::trace_control() } -static size_t remaining_session_ram_quota(char const *args) -{ - /* - * We don't need to consider an underflow here because - * 'Cpu_root::_create_session' already checks for the condition. - */ - return Arg_string::find_arg(args, "ram_quota").ulong_value(0) - - Trace::Control_area::SIZE; -} - - void Cpu_session_component::_transfer_quota(Cpu_session_component &dst, size_t const quota) { @@ -254,28 +241,30 @@ int Cpu_session_component::ref_account(Cpu_session_capability ref_cap) } -Cpu_session_component::Cpu_session_component(Ram_allocator &ram, +Cpu_session_component::Cpu_session_component(Rpc_entrypoint &session_ep, + Resources const &resources, + Label const &label, + Diag const &diag, + Ram_allocator &ram_alloc, Region_map &local_rm, - Rpc_entrypoint &session_ep, Rpc_entrypoint &thread_ep, Pager_entrypoint &pager_ep, - Allocator &md_alloc, Trace::Source_registry &trace_sources, char const *args, Affinity const &affinity, size_t const quota) : - _label(label_from_args(args)), - _session_ep(session_ep), - _thread_ep(thread_ep), _pager_ep(pager_ep), - _md_alloc(&md_alloc, remaining_session_ram_quota(args)), + Session_object(session_ep, resources, label, diag), + _session_ep(session_ep), _thread_ep(thread_ep), _pager_ep(pager_ep), + _ram_alloc(ram_alloc, _ram_quota_guard(), _cap_quota_guard()), + _md_alloc(_ram_alloc, local_rm), _thread_alloc(_md_alloc), _priority(0), /* map affinity to a location within the physical affinity space */ _location(affinity.scale_to(platform().affinity_space())), _trace_sources(trace_sources), - _trace_control_area(ram, local_rm), + _trace_control_area(_ram_alloc, local_rm), _quota(quota), _ref(0), _native_cpu(*this, args) { diff --git a/repos/base/src/core/include/cpu_root.h b/repos/base/src/core/include/cpu_root.h index c1b9f96e6..2d26992a4 100644 --- a/repos/base/src/core/include/cpu_root.h +++ b/repos/base/src/core/include/cpu_root.h @@ -26,7 +26,7 @@ namespace Genode { { private: - Ram_allocator &_ram; + Ram_allocator &_ram_alloc; Region_map &_local_rm; Rpc_entrypoint &_thread_ep; Pager_entrypoint &_pager_ep; @@ -45,17 +45,19 @@ namespace Genode { throw Insufficient_ram_quota(); return new (md_alloc()) - Cpu_session_component( - _ram, _local_rm, - *Root_component::ep(), - _thread_ep, _pager_ep, _md_alloc, _trace_sources, - args, affinity, 0); + Cpu_session_component(*this->ep(), + session_resources_from_args(args), + session_label_from_args(args), + session_diag_from_args(args), + _ram_alloc, _local_rm, + _thread_ep, _pager_ep, _trace_sources, + args, affinity, 0); } void _upgrade_session(Cpu_session_component *cpu, const char *args) override { - size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - cpu->upgrade_ram_quota(ram_quota); + cpu->upgrade(ram_quota_from_args(args)); + cpu->upgrade(cap_quota_from_args(args)); } public: @@ -67,7 +69,7 @@ namespace Genode { * \param thread_ep entry point for managing threads * \param md_alloc meta data allocator to be used by root component */ - Cpu_root(Ram_allocator &ram, + Cpu_root(Ram_allocator &ram_alloc, Region_map &local_rm, Rpc_entrypoint &session_ep, Rpc_entrypoint &thread_ep, @@ -76,7 +78,7 @@ namespace Genode { Trace::Source_registry &trace_sources) : Root_component(&session_ep, &md_alloc), - _ram(ram), _local_rm(local_rm), + _ram_alloc(ram_alloc), _local_rm(local_rm), _thread_ep(thread_ep), _pager_ep(pager_ep), _md_alloc(md_alloc), _trace_sources(trace_sources) { } diff --git a/repos/base/src/core/include/cpu_session_component.h b/repos/base/src/core/include/cpu_session_component.h index fb9f05e1a..328a49891 100644 --- a/repos/base/src/core/include/cpu_session_component.h +++ b/repos/base/src/core/include/cpu_session_component.h @@ -16,10 +16,10 @@ /* Genode includes */ #include -#include +#include #include #include -#include +#include #include /* core includes */ @@ -35,16 +35,16 @@ namespace Genode { class Cpu_session_component; } -class Genode::Cpu_session_component : public Rpc_object, +class Genode::Cpu_session_component : public Session_object, private List::Element { private: - Session_label const _label; Rpc_entrypoint &_session_ep; Rpc_entrypoint &_thread_ep; Pager_entrypoint &_pager_ep; - Allocator_guard _md_alloc; /* guarded meta-data allocator */ + Constrained_ram_allocator _ram_alloc; + Sliced_heap _md_alloc; /* guarded meta-data allocator */ Cpu_thread_allocator _thread_alloc; /* meta-data allocator */ Mutex _thread_alloc_lock { }; /* protect allocator access */ List _thread_list { }; @@ -144,12 +144,14 @@ class Genode::Cpu_session_component : public Rpc_object, /** * Constructor */ - Cpu_session_component(Ram_allocator &ram, + Cpu_session_component(Rpc_entrypoint &session_ep, + Resources const &resources, + Label const &label, + Diag const &diag, + Ram_allocator &ram_alloc, Region_map &local_rm, - Rpc_entrypoint &session_ep, Rpc_entrypoint &thread_ep, Pager_entrypoint &pager_ep, - Allocator &md_alloc, Trace::Source_registry &trace_sources, const char *args, Affinity const &affinity, size_t quota); @@ -159,11 +161,6 @@ class Genode::Cpu_session_component : public Rpc_object, */ ~Cpu_session_component(); - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - /*************************** ** CPU session interface ** diff --git a/repos/base/src/core/include/pd_session_component.h b/repos/base/src/core/include/pd_session_component.h index 002f49c79..3ae88a0fc 100644 --- a/repos/base/src/core/include/pd_session_component.h +++ b/repos/base/src/core/include/pd_session_component.h @@ -18,7 +18,6 @@ /* Genode includes */ #include -#include #include #include #include diff --git a/repos/base/src/core/include/rm_root.h b/repos/base/src/core/include/rm_root.h index 80e2162e0..263564cc7 100644 --- a/repos/base/src/core/include/rm_root.h +++ b/repos/base/src/core/include/rm_root.h @@ -28,22 +28,26 @@ class Genode::Rm_root : public Root_component { private: + Ram_allocator &_ram_alloc; + Region_map &_local_rm; Pager_entrypoint &_pager_ep; protected: Rm_session_component *_create_session(const char *args) override { - size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - return new (md_alloc()) - Rm_session_component(*this->ep(), *md_alloc(), _pager_ep, ram_quota); + Rm_session_component(*this->ep(), + session_resources_from_args(args), + session_label_from_args(args), + session_diag_from_args(args), + _ram_alloc, _local_rm, _pager_ep); } void _upgrade_session(Rm_session_component *rm, const char *args) override { - size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - rm->upgrade_ram_quota(ram_quota); + rm->upgrade(ram_quota_from_args(args)); + rm->upgrade(cap_quota_from_args(args)); } public: @@ -52,15 +56,19 @@ class Genode::Rm_root : public Root_component * Constructor * * \param session_ep entry point for managing RM session objects - * \param md_alloc meta data allocator to be used by root component + * \param md_alloc meta data allocator to for session objects + * \param ram_alloc RAM allocator used for session-internal + * allocations * \param pager_ep pager entrypoint */ Rm_root(Rpc_entrypoint &session_ep, Allocator &md_alloc, + Ram_allocator &ram_alloc, + Region_map &local_rm, Pager_entrypoint &pager_ep) : Root_component(&session_ep, &md_alloc), - _pager_ep(pager_ep) + _ram_alloc(ram_alloc), _local_rm(local_rm), _pager_ep(pager_ep) { } }; diff --git a/repos/base/src/core/include/rm_session_component.h b/repos/base/src/core/include/rm_session_component.h index 9e74d0add..f90f3c4d7 100644 --- a/repos/base/src/core/include/rm_session_component.h +++ b/repos/base/src/core/include/rm_session_component.h @@ -15,9 +15,9 @@ #define _CORE__INCLUDE__RM_SESSION_COMPONENT_H_ /* Genode includes */ -#include #include #include +#include /* core includes */ #include @@ -25,13 +25,14 @@ namespace Genode { class Rm_session_component; } -class Genode::Rm_session_component : public Rpc_object +class Genode::Rm_session_component : public Session_object { private: - Rpc_entrypoint &_ep; - Allocator_guard _md_alloc; - Pager_entrypoint &_pager_ep; + Rpc_entrypoint &_ep; + Constrained_ram_allocator _ram_alloc; + Sliced_heap _md_alloc; + Pager_entrypoint &_pager_ep; Mutex _region_maps_lock { }; List _region_maps { }; @@ -42,11 +43,18 @@ class Genode::Rm_session_component : public Rpc_object * Constructor */ Rm_session_component(Rpc_entrypoint &ep, - Allocator &md_alloc, - Pager_entrypoint &pager_ep, - size_t ram_quota) + Resources const &resources, + Label const &label, + Diag const &diag, + Ram_allocator &ram_alloc, + Region_map &local_rm, + Pager_entrypoint &pager_ep) : - _ep(ep), _md_alloc(&md_alloc, ram_quota), _pager_ep(pager_ep) + Session_object(ep, resources, label, diag), + _ep(ep), + _ram_alloc(ram_alloc, _ram_quota_guard(), _cap_quota_guard()), + _md_alloc(_ram_alloc, local_rm), + _pager_ep(pager_ep) { } ~Rm_session_component() @@ -59,11 +67,6 @@ class Genode::Rm_session_component : public Rpc_object } } - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - /************************** ** Rm_session interface ** diff --git a/repos/base/src/core/include/signal_source_component.h b/repos/base/src/core/include/signal_source_component.h index 863b76f43..6a7dd0de5 100644 --- a/repos/base/src/core/include/signal_source_component.h +++ b/repos/base/src/core/include/signal_source_component.h @@ -15,7 +15,6 @@ #define _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ #include -#include #include #include #include diff --git a/repos/base/src/core/include/trace/root.h b/repos/base/src/core/include/trace/root.h index 1ae13dc61..d4008b6a9 100644 --- a/repos/base/src/core/include/trace/root.h +++ b/repos/base/src/core/include/trace/root.h @@ -44,15 +44,19 @@ class Genode::Trace::Root : public Genode::Root_component throw Service_denied(); return new (md_alloc()) - Session_component(_ram, _local_rm, *md_alloc(), ram_quota, + Session_component(*this->ep(), + session_resources_from_args(args), + session_label_from_args(args), + session_diag_from_args(args), + _ram, _local_rm, arg_buffer_size, parent_levels, - label_from_args(args).string(), _sources, _policies); + _sources, _policies); } void _upgrade_session(Session_component *s, const char *args) override { - size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - s->upgrade_ram_quota(ram_quota); + s->upgrade(ram_quota_from_args(args)); + s->upgrade(cap_quota_from_args(args)); } public: diff --git a/repos/base/src/core/include/trace/session_component.h b/repos/base/src/core/include/trace/session_component.h index f6e2a376e..3fdff80f5 100644 --- a/repos/base/src/core/include/trace/session_component.h +++ b/repos/base/src/core/include/trace/session_component.h @@ -15,9 +15,9 @@ #define _CORE__INCLUDE__TRACE__SESSION_COMPONENT_H_ /* Genode includes */ -#include -#include +#include #include +#include #include #include @@ -30,19 +30,18 @@ namespace Genode { namespace Trace { class Session_component; } } class Genode::Trace::Session_component : - public Genode::Rpc_object, - public Genode::Trace::Policy_owner + public Session_object, + public Trace::Policy_owner { private: - Ram_allocator &_ram; + Constrained_ram_allocator _ram; Region_map &_local_rm; - Allocator_guard _md_alloc; + Sliced_heap _md_alloc { _ram, _local_rm }; Tslab _subjects_slab; Tslab _policies_slab; unsigned const _parent_levels; - Session_label const _label; Source_registry &_sources; Policy_registry &_policies; Subject_registry _subjects; @@ -54,19 +53,19 @@ class Genode::Trace::Session_component /** * Constructor */ - Session_component(Ram_allocator &ram, Region_map &local_rm, - Allocator &md_alloc, size_t ram_quota, - size_t arg_buffer_size, unsigned parent_levels, - char const *label, Source_registry &sources, + Session_component(Rpc_entrypoint &ep, + Resources const &resources, + Label const &label, + Diag const &diag, + Ram_allocator &ram, + Region_map &local_rm, + size_t arg_buffer_size, + unsigned parent_levels, + Source_registry &sources, Policy_registry &policies); ~Session_component(); - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - /*********************** ** Session interface ** diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc index d8b2805c0..d48058522 100644 --- a/repos/base/src/core/main.cc +++ b/repos/base/src/core/main.cc @@ -252,7 +252,7 @@ int main() static Pager_entrypoint pager_ep(rpc_cap_factory); static Rom_root rom_root (ep, ep, platform().rom_fs(), sliced_heap); - static Rm_root rm_root (ep, sliced_heap, pager_ep); + static Rm_root rm_root (ep, sliced_heap, core_ram_alloc, local_rm, pager_ep); static Cpu_root cpu_root (core_ram_alloc, local_rm, ep, ep, pager_ep, sliced_heap, Trace::sources()); static Pd_root pd_root (ep, core_env().signal_ep(), pager_ep, @@ -300,9 +300,14 @@ int main() /* CPU session representing core */ static Cpu_session_component - core_cpu(core_ram_alloc, local_rm, ep, ep, pager_ep, sliced_heap, Trace::sources(), - "label=\"core\"", Affinity(), Cpu_session::QUOTA_LIMIT); - Cpu_session_capability core_cpu_cap = ep.manage(&core_cpu); + core_cpu(ep, + Session::Resources{{Cpu_connection::RAM_QUOTA}, + {Cpu_session::CAP_QUOTA}}, + "core", Session::Diag{false}, + core_ram_alloc, local_rm, ep, pager_ep, Trace::sources(), "", + Affinity(), Cpu_session::QUOTA_LIMIT); + + Cpu_session_capability core_cpu_cap = core_cpu.cap(); log("", init_ram_quota.value / (1024*1024), " MiB RAM and ", init_cap_quota, " caps " "assigned to init"); diff --git a/repos/base/src/core/trace_session_component.cc b/repos/base/src/core/trace_session_component.cc index bda700936..12fe8989b 100644 --- a/repos/base/src/core/trace_session_component.cc +++ b/repos/base/src/core/trace_session_component.cc @@ -59,17 +59,22 @@ Policy_id Session_component::alloc_policy(size_t size) */ Policy_id const id(++_policy_cnt); - if (!_md_alloc.withdraw(size)) - throw Out_of_ram(); + Ram_quota const amount { size }; + + /* + * \throw Out_of_ram + */ + withdraw(amount); try { - Ram_dataspace_capability ds = _ram.alloc(size); + Dataspace_capability ds_cap = _ram.alloc(size); + _policies.insert(*this, id, _policies_slab, ds_cap, size); - _policies.insert(*this, id, _policies_slab, ds, size); } catch (...) { + /* revert withdrawal or quota */ - _md_alloc.upgrade(size); - throw Out_of_ram(); + replenish(amount); + throw; } return id; @@ -91,30 +96,32 @@ void Session_component::unload_policy(Policy_id id) void Session_component::trace(Subject_id subject_id, Policy_id policy_id, size_t buffer_size) { - size_t const policy_size = _policies.size(*this, policy_id); - size_t const required_ram = buffer_size + policy_size; + size_t const policy_size = _policies.size(*this, policy_id); + + Ram_quota const required_ram { buffer_size + policy_size }; Trace::Subject &subject = _subjects.lookup_by_id(subject_id); + /* revert quota from previous call to trace */ if (subject.allocated_memory()) { - _md_alloc.upgrade(subject.allocated_memory()); + replenish(Ram_quota{subject.allocated_memory()}); subject.reset_allocated_memory(); } /* * Account RAM needed for trace buffer and policy buffer to the trace * session. + * + * \throw Out_of_ram */ - if (!_md_alloc.withdraw(required_ram)) { - throw Out_of_ram(); - } + withdraw(required_ram); try { subject.trace(policy_id, _policies.dataspace(*this, policy_id), policy_size, _ram, _local_rm, buffer_size); } catch (...) { /* revert withdrawal or quota */ - _md_alloc.upgrade(required_ram); + replenish(required_ram); throw; } } @@ -153,29 +160,35 @@ Dataspace_capability Session_component::buffer(Subject_id subject_id) void Session_component::free(Subject_id subject_id) { - size_t const released_ram = _subjects.release(subject_id); - _md_alloc.upgrade(released_ram); + Ram_quota const released_ram { _subjects.release(subject_id) }; + + replenish(released_ram); } -Session_component::Session_component(Ram_allocator &ram, Region_map &local_rm, - Allocator &md_alloc, size_t ram_quota, - size_t arg_buffer_size, unsigned parent_levels, - char const *label, Source_registry &sources, +Session_component::Session_component(Rpc_entrypoint &ep, + Resources const &resources, + Label const &label, + Diag const &diag, + Ram_allocator &ram, + Region_map &local_rm, + size_t arg_buffer_size, + unsigned parent_levels, + Source_registry &sources, Policy_registry &policies) : - _ram(ram), _local_rm(local_rm), - _md_alloc(&md_alloc, ram_quota), + Session_object(ep, resources, label, diag), + _ram(ram, _ram_quota_guard(), _cap_quota_guard()), + _local_rm(local_rm), _subjects_slab(&_md_alloc), _policies_slab(&_md_alloc), _parent_levels(parent_levels), - _label(label), _sources(sources), _policies(policies), _subjects(_subjects_slab, _ram, _sources), _argument_buffer(_ram, local_rm, arg_buffer_size) { - _md_alloc.withdraw(_argument_buffer.size()); + withdraw(Ram_quota{_argument_buffer.size()}); } diff --git a/repos/base/src/include/base/internal/expanding_cpu_session_client.h b/repos/base/src/include/base/internal/expanding_cpu_session_client.h index 1be6dd974..3b47b3a30 100644 --- a/repos/base/src/include/base/internal/expanding_cpu_session_client.h +++ b/repos/base/src/include/base/internal/expanding_cpu_session_client.h @@ -44,8 +44,12 @@ struct Genode::Expanding_cpu_session_client : Upgradeable_client( [&] () { - return Cpu_session_client::create_thread(pd, name, location, - weight, utcb); }, + return retry( + [&] () { + return Cpu_session_client::create_thread(pd, name, location, + weight, utcb); }, + [&] () { upgrade_caps(2); }); + }, [&] () { upgrade_ram(8*1024); }); } }; diff --git a/repos/dde_rump/run/rump_ext2.run b/repos/dde_rump/run/rump_ext2.run index 48919d8f0..3e51c955b 100644 --- a/repos/dde_rump/run/rump_ext2.run +++ b/repos/dde_rump/run/rump_ext2.run @@ -52,7 +52,7 @@ append config { - + diff --git a/repos/gems/recipes/raw/drivers_nic-pc/drivers.config b/repos/gems/recipes/raw/drivers_nic-pc/drivers.config index e993e54c7..4148c8b8c 100644 --- a/repos/gems/recipes/raw/drivers_nic-pc/drivers.config +++ b/repos/gems/recipes/raw/drivers_nic-pc/drivers.config @@ -47,7 +47,7 @@ - + @@ -70,7 +70,7 @@ - + diff --git a/repos/gems/run/fs_query.run b/repos/gems/run/fs_query.run index 02d2f400d..1b2ea0d92 100644 --- a/repos/gems/run/fs_query.run +++ b/repos/gems/run/fs_query.run @@ -72,7 +72,7 @@ install_config { - + diff --git a/repos/libports/recipes/pkg/test-sequence/runtime b/repos/libports/recipes/pkg/test-sequence/runtime index 7350a8890..63d6873a4 100644 --- a/repos/libports/recipes/pkg/test-sequence/runtime +++ b/repos/libports/recipes/pkg/test-sequence/runtime @@ -37,7 +37,7 @@ - + @@ -46,7 +46,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/repos/libports/run/nic_bridge.run b/repos/libports/run/nic_bridge.run index e3c4dd52a..cef6e64ae 100644 --- a/repos/libports/run/nic_bridge.run +++ b/repos/libports/run/nic_bridge.run @@ -68,7 +68,7 @@ install_config { - + @@ -86,7 +86,7 @@ install_config { - + diff --git a/repos/os/recipes/raw/drivers_interactive-muen/drivers.config b/repos/os/recipes/raw/drivers_interactive-muen/drivers.config index e8deef8bc..b5f38a367 100644 --- a/repos/os/recipes/raw/drivers_interactive-muen/drivers.config +++ b/repos/os/recipes/raw/drivers_interactive-muen/drivers.config @@ -59,7 +59,7 @@ - + @@ -72,7 +72,7 @@ - + diff --git a/repos/os/recipes/raw/drivers_interactive-pc/drivers.config b/repos/os/recipes/raw/drivers_interactive-pc/drivers.config index 3da3e502b..d6f2bd764 100644 --- a/repos/os/recipes/raw/drivers_interactive-pc/drivers.config +++ b/repos/os/recipes/raw/drivers_interactive-pc/drivers.config @@ -105,7 +105,7 @@ - + diff --git a/repos/os/run/nic_dump.run b/repos/os/run/nic_dump.run index 6c3fb17e3..e938fc690 100644 --- a/repos/os/run/nic_dump.run +++ b/repos/os/run/nic_dump.run @@ -59,7 +59,7 @@ append config { - + #include @@ -112,4 +112,4 @@ class Genode::Allocator_guard : public Allocator return _allocator->need_size_for_free(); } }; -#endif /* _INCLUDE__BASE__ALLOCATOR_GUARD_H_ */ +#endif /* _ALLOCATOR_GUARD_H_ */ diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index cbb82fd40..279c0f9fb 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -12,7 +12,6 @@ */ /* Genode includes */ -#include #include #include #include @@ -34,6 +33,7 @@ #include /* local includes */ +#include #include #include #include diff --git a/repos/os/src/drivers/gpu/intel/ppgtt_allocator.h b/repos/os/src/drivers/gpu/intel/ppgtt_allocator.h index 3bfb42d8e..7789fe075 100644 --- a/repos/os/src/drivers/gpu/intel/ppgtt_allocator.h +++ b/repos/os/src/drivers/gpu/intel/ppgtt_allocator.h @@ -14,12 +14,10 @@ #ifndef _PPGTT_ALLOCATOR_H_ #define _PPGTT_ALLOCATOR_H_ -/* Genode includes */ -#include - /* local includes */ #include #include +#include namespace Igd { diff --git a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h index 3004dcb63..f86668348 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h @@ -14,7 +14,6 @@ #pragma once /* base */ -#include #include #include #include @@ -30,7 +29,6 @@ #include #include #include -#include /* local */ #include "device_pd.h" diff --git a/repos/os/src/server/nic_dump/component.cc b/repos/os/src/server/nic_dump/component.cc index 011b946ba..ac0100120 100644 --- a/repos/os/src/server/nic_dump/component.cc +++ b/repos/os/src/server/nic_dump/component.cc @@ -38,15 +38,20 @@ Communication_buffer::Communication_buffer(Ram_allocator &ram, ****************************/ Session_component_base:: -Session_component_base(Allocator &guarded_alloc_backing, - size_t const guarded_alloc_amount, - Ram_allocator &buf_ram, - size_t const tx_buf_size, - size_t const rx_buf_size) +Session_component_base(Ram_allocator &ram, + Region_map &local_rm, + Ram_quota const ram_quota, + Cap_quota const cap_quota, + size_t const tx_buf_size, + size_t const rx_buf_size) : - _guarded_alloc(&guarded_alloc_backing, guarded_alloc_amount), - _range_alloc(&_guarded_alloc), _tx_buf(buf_ram, tx_buf_size), - _rx_buf(buf_ram, rx_buf_size) + _ram_quota_guard(ram_quota), + _cap_quota_guard(cap_quota), + _ram(ram, _ram_quota_guard, _cap_quota_guard), + _alloc(_ram, local_rm), + _range_alloc(&_alloc), + _tx_buf(ram, tx_buf_size), + _rx_buf(ram, rx_buf_size) { } @@ -54,22 +59,23 @@ Session_component_base(Allocator &guarded_alloc_backing, ** Session_component ** ***********************/ -Net::Session_component::Session_component(Allocator &alloc, - size_t const amount, - size_t const tx_buf_size, - size_t const rx_buf_size, - Xml_node config, +Net::Session_component::Session_component(Ram_quota const ram_quota, + Cap_quota const cap_quota, + size_t const tx_buf_size, + size_t const rx_buf_size, + Xml_node const config, Timer::Connection &timer, Duration &curr_time, Env &env) : - Session_component_base(alloc, amount, env.ram(), tx_buf_size, rx_buf_size), + Session_component_base(env.ram(), env.rm(), ram_quota, cap_quota, + tx_buf_size, rx_buf_size), Session_rpc_object(env.rm(), _tx_buf, _rx_buf, &_range_alloc, env.ep().rpc_ep()), Interface(env.ep(), config.attribute_value("downlink", Interface_label()), timer, curr_time, config.attribute_value("time", false), - _guarded_alloc, config), - _uplink(env, config, timer, curr_time, alloc), + Session_component_base::_alloc, config), + _uplink(env, config, timer, curr_time, Session_component_base::_alloc), _link_state_handler(env.ep(), *this, &Session_component::_handle_link_state) { _tx.sigh_ready_to_ack(_sink_ack); @@ -120,8 +126,8 @@ Net::Root::Root(Env &env, Session_component *Net::Root::_create_session(char const *args) { try { - size_t const ram_quota = - Arg_string::find_arg(args, "ram_quota").ulong_value(0); + Ram_quota const ram_quota = ram_quota_from_args(args); + Cap_quota const cap_quota = cap_quota_from_args(args); size_t const tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0); @@ -132,19 +138,19 @@ Session_component *Net::Root::_create_session(char const *args) size_t const session_size = max((size_t)4096, sizeof(Session_component)); - if (ram_quota < session_size) { + if (ram_quota.value < session_size) { throw Insufficient_ram_quota(); } - if (tx_buf_size > ram_quota - session_size || - rx_buf_size > ram_quota - session_size || - tx_buf_size + rx_buf_size > ram_quota - session_size) + if (tx_buf_size > ram_quota.value - session_size || + rx_buf_size > ram_quota.value - session_size || + tx_buf_size + rx_buf_size > ram_quota.value - session_size) { error("insufficient 'ram_quota' for session creation"); throw Insufficient_ram_quota(); } return new (md_alloc()) - Session_component(*md_alloc(), ram_quota - session_size, - tx_buf_size, rx_buf_size, _config, _timer, + Session_component(Ram_quota{ram_quota.value - session_size}, + cap_quota, tx_buf_size, rx_buf_size, _config, _timer, _curr_time, _env); } catch (...) { throw Service_denied(); } diff --git a/repos/os/src/server/nic_dump/component.h b/repos/os/src/server/nic_dump/component.h index cd61edcd7..813ee3afe 100644 --- a/repos/os/src/server/nic_dump/component.h +++ b/repos/os/src/server/nic_dump/component.h @@ -15,10 +15,10 @@ #define _COMPONENT_H_ /* Genode includes */ -#include #include #include #include +#include /* local includes */ #include @@ -52,24 +52,28 @@ class Net::Session_component_base { protected: - Genode::Allocator_guard _guarded_alloc; - Nic::Packet_allocator _range_alloc; - Communication_buffer _tx_buf; - Communication_buffer _rx_buf; + Genode::Ram_quota_guard _ram_quota_guard; + Genode::Cap_quota_guard _cap_quota_guard; + Genode::Constrained_ram_allocator _ram; + Genode::Sliced_heap _alloc; + Nic::Packet_allocator _range_alloc; + Communication_buffer _tx_buf; + Communication_buffer _rx_buf; public: - Session_component_base(Genode::Allocator &guarded_alloc_backing, - Genode::size_t const guarded_alloc_amount, - Genode::Ram_allocator &buf_ram, - Genode::size_t const tx_buf_size, - Genode::size_t const rx_buf_size); + Session_component_base(Genode::Ram_allocator &ram, + Genode::Region_map &local_rm, + Genode::Ram_quota ram_quota, + Genode::Cap_quota cap_quota, + Genode::size_t const tx_buf_size, + Genode::size_t const rx_buf_size); }; class Net::Session_component : private Session_component_base, public ::Nic::Session_rpc_object, - public Interface + private Interface { private: @@ -90,14 +94,14 @@ class Net::Session_component : private Session_component_base, public: - Session_component(Genode::Allocator &alloc, - Genode::size_t const amount, - Genode::size_t const tx_buf_size, - Genode::size_t const rx_buf_size, - Genode::Xml_node config, - Timer::Connection &timer, - Genode::Duration &curr_time, - Genode::Env &env); + Session_component(Genode::Ram_quota ram_quota, + Genode::Cap_quota cap_quota, + Genode::size_t tx_buf_size, + Genode::size_t rx_buf_size, + Genode::Xml_node config, + Timer::Connection &timer, + Genode::Duration &curr_time, + Genode::Env &env); /****************** diff --git a/repos/os/src/server/nic_router/component.h b/repos/os/src/server/nic_router/component.h index 7fc65982e..43d7e673f 100644 --- a/repos/os/src/server/nic_router/component.h +++ b/repos/os/src/server/nic_router/component.h @@ -16,7 +16,6 @@ /* Genode includes */ #include -#include #include #include #include diff --git a/repos/os/src/server/nitpicker/main.cc b/repos/os/src/server/nitpicker/main.cc index 4277358d2..17486fc36 100644 --- a/repos/os/src/server/nitpicker/main.cc +++ b/repos/os/src/server/nitpicker/main.cc @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -87,26 +86,17 @@ class Nitpicker::Root : public Root_component, Session_component *_create_session(const char *args) override { - size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - - size_t const required_quota = Input::Session_component::ev_ds_size() - + align_addr(sizeof(Session::Command_buffer), 12); - - if (ram_quota < required_quota) { - warning("Insufficient dontated ram_quota (", ram_quota, - " bytes), require ", required_quota, " bytes"); - throw Insufficient_ram_quota(); - } - - size_t const unused_quota = ram_quota - required_quota; - Session_label const label = label_from_args(args); + bool const provides_default_bg = (label == "backdrop"); Session_component *session = new (md_alloc()) - Session_component(_env, label, _view_stack, _font, _focus_updater, + Session_component(_env, + session_resources_from_args(args), label, + session_diag_from_args(args), + _view_stack, _font, _focus_updater, _pointer_origin, _builtin_background, _framebuffer, - provides_default_bg, *md_alloc(), unused_quota, + provides_default_bg, _focus_reporter, *this); session->apply_session_policy(_config.xml(), _domain_registry); @@ -119,8 +109,8 @@ class Nitpicker::Root : public Root_component, void _upgrade_session(Session_component *s, const char *args) override { - size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - s->upgrade_ram_quota(ram_quota); + s->upgrade(ram_quota_from_args(args)); + s->upgrade(cap_quota_from_args(args)); } void _destroy_session(Session_component *session) override diff --git a/repos/os/src/server/nitpicker/session_component.cc b/repos/os/src/server/nitpicker/session_component.cc index 59f5c9d27..94bec3ea4 100644 --- a/repos/os/src/server/nitpicker/session_component.cc +++ b/repos/os/src/server/nitpicker/session_component.cc @@ -31,7 +31,7 @@ void Session_component::_release_buffer() destroy(&_session_alloc, const_cast *>(cdt)); - _session_alloc.upgrade(_buffer_size); + replenish(Ram_quota{_buffer_size}); _buffer_size = 0; } @@ -427,9 +427,13 @@ Framebuffer::Mode Session_component::mode() void Session_component::buffer(Framebuffer::Mode mode, bool use_alpha) { /* check if the session quota suffices for the specified mode */ - if (_session_alloc.quota() < ram_quota(mode, use_alpha)) + if (_buffer_size + _ram_quota_guard().avail().value < ram_quota(mode, use_alpha)) throw Out_of_ram(); + /* buffer re-allocation may consume new dataspace capability if buffer is new */ + if (_cap_quota_guard().avail().value < 1) + throw Out_of_caps(); + _framebuffer_session_component.notify_mode_change(mode, use_alpha); } @@ -477,7 +481,7 @@ Buffer *Session_component::realloc_buffer(Framebuffer::Mode mode, bool use_alpha /* * Preserve the content of the original buffer if nitpicker has - * enough lack memory to temporarily keep the original pixels. + * enough slack memory to temporarily keep the original pixels. */ Texture const *src_texture = nullptr; if (texture()) { @@ -491,8 +495,22 @@ Buffer *Session_component::realloc_buffer(Framebuffer::Mode mode, bool use_alpha } } - Chunky_texture * const texture = new (&_session_alloc) - Chunky_texture(_env.ram(), _env.rm(), size, use_alpha); + Ram_quota const temporary_ram_upgrade = src_texture + ? Ram_quota{_buffer_size} : Ram_quota{0}; + + _ram_quota_guard().upgrade(temporary_ram_upgrade); + + auto try_alloc_texture = [&] () + { + try { + return new (&_session_alloc) + Chunky_texture(_env.ram(), _env.rm(), size, use_alpha); + } catch (...) { + return (Chunky_texture*)nullptr; + } + }; + + Chunky_texture * const texture = try_alloc_texture(); /* copy old buffer content into new buffer and release old buffer */ if (src_texture) { @@ -503,9 +521,14 @@ Buffer *Session_component::realloc_buffer(Framebuffer::Mode mode, bool use_alpha Texture_painter::paint(surface, *src_texture, Color(), Point(0, 0), Texture_painter::SOLID, false); _release_buffer(); + + if (!_ram_quota_guard().try_downgrade(temporary_ram_upgrade)) + warning("accounting error during framebuffer realloc"); + } - if (!_session_alloc.withdraw(_buffer_size)) { + try { withdraw(Ram_quota{_buffer_size}); } + catch (...) { destroy(&_session_alloc, texture); _buffer_size = 0; return nullptr; diff --git a/repos/os/src/server/nitpicker/session_component.h b/repos/os/src/server/nitpicker/session_component.h index a345cba4d..65434c391 100644 --- a/repos/os/src/server/nitpicker/session_component.h +++ b/repos/os/src/server/nitpicker/session_component.h @@ -16,12 +16,12 @@ /* Genode includes */ #include -#include +#include +#include #include #include #include #include -#include /* local includes */ #include "canvas.h" @@ -52,7 +52,7 @@ struct Nitpicker::Visibility_controller : Interface }; -class Nitpicker::Session_component : public Rpc_object, +class Nitpicker::Session_component : public Session_object, public View_owner, public Buffer_provider, private Session_list::Element @@ -61,6 +61,8 @@ class Nitpicker::Session_component : public Rpc_object, friend class List; + using Nitpicker::Session::Label; + /* * Noncopyable */ @@ -69,7 +71,7 @@ class Nitpicker::Session_component : public Rpc_object, Env &_env; - Session_label const _label; + Constrained_ram_allocator _ram; Domain_registry::Entry const *_domain = nullptr; Texture_base const *_texture = nullptr; @@ -89,12 +91,15 @@ class Nitpicker::Session_component : public Rpc_object, bool _uses_alpha = false; bool _visible = true; - Allocator_guard _session_alloc; + Sliced_heap _session_alloc; Framebuffer::Session &_framebuffer; Framebuffer::Session_component _framebuffer_session_component; + bool const _input_session_accounted = ( + withdraw(Ram_quota{Input::Session_component::ev_ds_size()}), true ); + Input::Session_component _input_session_component { _env }; View_stack &_view_stack; @@ -125,6 +130,9 @@ class Nitpicker::Session_component : public Rpc_object, Attached_ram_dataspace _command_ds { _env.ram(), _env.rm(), sizeof(Command_buffer) }; + bool const _command_buffer_accounted = ( + withdraw(Ram_quota{align_addr(sizeof(Session::Command_buffer), 12)}), true ); + Command_buffer &_command_buffer = *_command_ds.local_addr(); typedef Handle_registry View_handle_registry; @@ -166,7 +174,9 @@ class Nitpicker::Session_component : public Rpc_object, public: Session_component(Env &env, - Session_label const &label, + Resources const &resources, + Label const &label, + Diag const &diag, View_stack &view_stack, Font const &font, Focus_updater &focus_updater, @@ -174,14 +184,13 @@ class Nitpicker::Session_component : public Rpc_object, View_component &builtin_background, Framebuffer::Session &framebuffer, bool provides_default_bg, - Allocator &session_alloc, - size_t ram_quota, Reporter &focus_reporter, Visibility_controller &visibility_controller) : + Session_object(env.ep(), resources, label, diag), _env(env), - _label(label), - _session_alloc(&session_alloc, ram_quota), + _ram(env.ram(), _ram_quota_guard(), _cap_quota_guard()), + _session_alloc(_ram, env.rm()), _framebuffer(framebuffer), _framebuffer_session_component(view_stack, *this, framebuffer, *this), _view_stack(view_stack), _font(font), _focus_updater(focus_updater), @@ -193,9 +202,7 @@ class Nitpicker::Session_component : public Rpc_object, _view_handle_registry(_session_alloc), _focus_reporter(focus_reporter), _visibility_controller(visibility_controller) - { - _session_alloc.upgrade(ram_quota); - } + { } ~Session_component() { @@ -338,8 +345,6 @@ class Nitpicker::Session_component : public Rpc_object, Signal_transmitter(_mode_sigh).submit(); } - void upgrade_ram_quota(size_t ram_quota) { _session_alloc.upgrade(ram_quota); } - /** * Deliver sync signal to the client's virtual frame buffer */ diff --git a/repos/os/src/server/vfs/main.cc b/repos/os/src/server/vfs/main.cc index f84e0cf50..c8a527d58 100644 --- a/repos/os/src/server/vfs/main.cc +++ b/repos/os/src/server/vfs/main.cc @@ -22,12 +22,9 @@ #include #include #include -#include -#include #include /* local includes */ -#include "assert.h" #include "node.h" diff --git a/repos/os/src/test/slab/main.cc b/repos/os/src/test/slab/main.cc index 108808fc7..60cadebdf 100644 --- a/repos/os/src/test/slab/main.cc +++ b/repos/os/src/test/slab/main.cc @@ -15,7 +15,6 @@ #include #include #include -#include #include @@ -79,7 +78,36 @@ void Component::construct(Genode::Env & env) static Timer::Connection timer(env); enum { SLAB_SIZE = 16, BLOCK_SIZE = 256 }; - static Genode::Allocator_guard alloc(&heap, ~0UL); + + struct Tracked_alloc : Genode::Allocator + { + size_t _consumed = 0; + + Allocator &_alloc; + + bool alloc(size_t size, void **out_addr) override + { + if (_alloc.alloc(size, out_addr)) { + _consumed += size; + return true; + } + return false; + } + + void free(void *addr, size_t size) override + { + _alloc.free(addr, size); + _consumed -= size; + } + + size_t overhead(size_t) const override { return 0; } + size_t consumed() const override { return _consumed; } + bool need_size_for_free() const override { return true; } + + Tracked_alloc(Allocator &alloc) : _alloc(alloc) { } + }; + + Tracked_alloc alloc { heap }; { Genode::Slab slab(SLAB_SIZE, BLOCK_SIZE, nullptr, &alloc); diff --git a/repos/ports/include/vmm/vcpu_dispatcher.h b/repos/ports/include/vmm/vcpu_dispatcher.h index 66cf4d6f4..556a0d71e 100644 --- a/repos/ports/include/vmm/vcpu_dispatcher.h +++ b/repos/ports/include/vmm/vcpu_dispatcher.h @@ -70,7 +70,7 @@ class Vmm::Vcpu_dispatcher : public T unsigned int exit_reason = 0; Vcpu_dispatcher(Genode::Env &env, Genode::size_t stack_size, - Cpu_session * cpu_session, + Cpu_connection *, Genode::Affinity::Location location, const char * name = "vCPU dispatcher") : diff --git a/repos/ports/include/vmm/vcpu_thread.h b/repos/ports/include/vmm/vcpu_thread.h index 3e189bc8f..34052b042 100644 --- a/repos/ports/include/vmm/vcpu_thread.h +++ b/repos/ports/include/vmm/vcpu_thread.h @@ -51,7 +51,7 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread Genode::Capability _pd_cap; Genode::Affinity::Location _location; - Genode::Cpu_session *_cpu_session; + Genode::Cpu_connection *_cpu_connection; Genode::addr_t _exc_pt_sel; @@ -63,12 +63,12 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread public: - Vcpu_other_pd(Cpu_session * cpu_session, + Vcpu_other_pd(Cpu_connection * cpu_connection, Genode::Affinity::Location location, Genode::Capability pd_cap, Genode::size_t = 0 /* stack_size */) : - _pd_cap(pd_cap), _location(location), _cpu_session(cpu_session), + _pd_cap(pd_cap), _location(location), _cpu_connection(cpu_connection), _exc_pt_sel(Genode::cap_map().insert(Nova::NUM_INITIAL_VCPU_PT_LOG2)) { } @@ -77,13 +77,17 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread using namespace Genode; Thread_capability vcpu_vm = - _cpu_session->create_thread(_pd_cap, "vCPU", - _location, Cpu_session::Weight()); + _cpu_connection->retry_with_upgrade(Ram_quota{8*1024}, Cap_quota{2}, + [&] () + { + return _cpu_connection->create_thread(_pd_cap, "vCPU", _location, + Cpu_session::Weight()); + }); /* tell parent that this will be a vCPU */ Nova_native_cpu::Thread_type thread_type { Nova_native_cpu::Thread_type::VCPU }; Nova_native_cpu::Exception_base exception_base { _exc_pt_sel }; - Nova_native_cpu_client native_cpu(_cpu_session->native_cpu()); + Nova_native_cpu_client native_cpu(_cpu_connection->native_cpu()); native_cpu.thread_type(vcpu_vm, thread_type, exception_base); Cpu_thread_client cpu_thread(vcpu_vm); @@ -123,12 +127,12 @@ class Vmm::Vcpu_same_pd : public Vmm::Vcpu_thread, Genode::Thread public: - Vcpu_same_pd(Cpu_session * cpu_session, + Vcpu_same_pd(Cpu_connection * cpu_connection, Genode::Affinity::Location location, Genode::Capability, Genode::size_t stack_size) : - Thread(WEIGHT, "vCPU", stack_size, Type::NORMAL, cpu_session, location) + Thread(WEIGHT, "vCPU", stack_size, Type::NORMAL, cpu_connection, location) { /* release pre-allocated selectors of Thread */ Genode::cap_map().remove(native_thread().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2); diff --git a/repos/ports/run/netperf.inc b/repos/ports/run/netperf.inc index 2d89afd63..04bd42378 100644 --- a/repos/ports/run/netperf.inc +++ b/repos/ports/run/netperf.inc @@ -196,7 +196,7 @@ append config { } elseif { $use_usb_driver } { append_platform_drv_config append config { - + @@ -219,7 +219,7 @@ append config { } append_if $use_nic_router config { - + diff --git a/repos/ports/src/virtualbox5/generic/sup_vmm.cc b/repos/ports/src/virtualbox5/generic/sup_vmm.cc index dfe9d8d05..703a0c993 100644 --- a/repos/ports/src/virtualbox5/generic/sup_vmm.cc +++ b/repos/ports/src/virtualbox5/generic/sup_vmm.cc @@ -759,7 +759,7 @@ extern "C" int sched_yield(void) bool create_emt_vcpu(pthread_t * thread, ::size_t stack_size, void *(*start_routine)(void *), void *arg, - Genode::Cpu_session * cpu_session, + Genode::Cpu_connection * cpu_connection, Genode::Affinity::Location location, unsigned int cpu_id, const char * name, long prio) { @@ -791,7 +791,7 @@ bool create_emt_vcpu(pthread_t * thread, ::size_t stack_size, vcpu_handler_list().insert(vcpu_handler); Libc::pthread_create(thread, start_routine, arg, - stack_size, name, cpu_session, location); + stack_size, name, cpu_connection, location); return true; } diff --git a/repos/ports/src/virtualbox5/spec/nova/sup.cc b/repos/ports/src/virtualbox5/spec/nova/sup.cc index 37ad11515..41531615d 100644 --- a/repos/ports/src/virtualbox5/spec/nova/sup.cc +++ b/repos/ports/src/virtualbox5/spec/nova/sup.cc @@ -779,7 +779,7 @@ void *operator new (__SIZE_TYPE__ size, int log2_align) bool create_emt_vcpu(pthread_t * pthread, ::size_t stack, void *(*start_routine)(void *), void *arg, - Genode::Cpu_session * cpu_session, + Genode::Cpu_connection * cpu_connection, Genode::Affinity::Location location, unsigned int cpu_id, const char * name, long) { @@ -797,13 +797,13 @@ bool create_emt_vcpu(pthread_t * pthread, ::size_t stack, if (vmx) vcpu_handler = new (0x10) Vcpu_handler_vmx(genode_env(), stack, start_routine, - arg, cpu_session, location, + arg, cpu_connection, location, cpu_id, name, pd_vcpus.rpc_cap()); if (svm) vcpu_handler = new (0x10) Vcpu_handler_svm(genode_env(), stack, start_routine, - arg, cpu_session, location, + arg, cpu_connection, location, cpu_id, name, pd_vcpus.rpc_cap()); Assert(!(reinterpret_cast(vcpu_handler) & 0xf)); diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu.h b/repos/ports/src/virtualbox5/spec/nova/vcpu.h index 2d2397929..f45a5c3fd 100644 --- a/repos/ports/src/virtualbox5/spec/nova/vcpu.h +++ b/repos/ports/src/virtualbox5/spec/nova/vcpu.h @@ -820,17 +820,17 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher, Vcpu_handler(Genode::Env &env, size_t stack_size, pthread::start_routine_t start_routine, void *arg, - Genode::Cpu_session * cpu_session, + Genode::Cpu_connection * cpu_connection, Genode::Affinity::Location location, unsigned int cpu_id, const char * name, Genode::Pd_session_capability pd_vcpu) : - Vmm::Vcpu_dispatcher(env, stack_size, cpu_session, + Vmm::Vcpu_dispatcher(env, stack_size, cpu_connection, location, name), _pthread(*this), _start_routine(start_routine), _start_routine_arg(arg), - _vcpu(cpu_session, location, pd_vcpu), + _vcpu(cpu_connection, location, pd_vcpu), _ec_sel(Genode::cap_map().insert()), _cpu_id(cpu_id) { } diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h b/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h index 77f94b438..63156ab15 100644 --- a/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h +++ b/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h @@ -91,12 +91,12 @@ class Vcpu_handler_svm : public Vcpu_handler Vcpu_handler_svm(Genode::Env &env, size_t stack_size, void *(*start_routine) (void *), void *arg, - Genode::Cpu_session * cpu_session, + Genode::Cpu_connection * cpu_connection, Genode::Affinity::Location location, unsigned int cpu_id, const char * name, Genode::Pd_session_capability pd_vcpu) : - Vcpu_handler(env, stack_size, start_routine, arg, cpu_session, + Vcpu_handler(env, stack_size, start_routine, arg, cpu_connection, location, cpu_id, name, pd_vcpu) { using namespace Nova; diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h b/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h index a16ab3571..c13f5f7ba 100644 --- a/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h +++ b/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h @@ -177,12 +177,12 @@ class Vcpu_handler_vmx : public Vcpu_handler Vcpu_handler_vmx(Genode::Env &env, size_t stack_size, void *(*start_routine) (void *), void *arg, - Genode::Cpu_session * cpu_session, + Genode::Cpu_connection * cpu_connection, Genode::Affinity::Location location, unsigned int cpu_id, const char * name, Genode::Pd_session_capability pd_vcpu) : - Vcpu_handler(env, stack_size, start_routine, arg, cpu_session, + Vcpu_handler(env, stack_size, start_routine, arg, cpu_connection, location, cpu_id, name, pd_vcpu) { using namespace Nova; diff --git a/repos/ports/src/virtualbox5/sup.h b/repos/ports/src/virtualbox5/sup.h index c07a14571..ca87f0f9b 100644 --- a/repos/ports/src/virtualbox5/sup.h +++ b/repos/ports/src/virtualbox5/sup.h @@ -16,6 +16,7 @@ /* Genode includes */ #include +#include /* VirtualBox includes */ #include @@ -34,7 +35,7 @@ HRESULT genode_check_memory_config(ComObjPtr machine, size_t); */ bool create_emt_vcpu(pthread_t * pthread, size_t stack, void *(*start_routine)(void *), void *arg, - Genode::Cpu_session * cpu_session, + Genode::Cpu_connection *, Genode::Affinity::Location location, unsigned int cpu_id, const char * name, long prio); @@ -43,7 +44,7 @@ bool create_emt_vcpu(pthread_t * pthread, size_t stack, uint64_t genode_cpu_hz(); void genode_update_tsc(void (*update_func)(void), Genode::uint64_t update_us); -Genode::Cpu_session * get_vcpu_cpu_session(); +Genode::Cpu_connection * get_vcpu_cpu_connection(); void genode_VMMR0_DO_GVMM_CREATE_VM(PSUPVMMR0REQHDR pReqHdr); void genode_VMMR0_DO_GVMM_REGISTER_VMCPU(PVMR0 pVMR0, VMCPUID idCpu); diff --git a/repos/ports/src/virtualbox5/thread.cc b/repos/ports/src/virtualbox5/thread.cc index 779a974fa..02eb9131e 100644 --- a/repos/ports/src/virtualbox5/thread.cc +++ b/repos/ports/src/virtualbox5/thread.cc @@ -104,12 +104,12 @@ static int create_thread(pthread_t *thread, const pthread_attr_t *attr, unsigned int cpu_id = 0; sscanf(rtthread->szName, "EMT-%u", &cpu_id); - Genode::Cpu_session * cpu_session = cpu_connection(RTTHREADTYPE_EMULATION); - Genode::Affinity::Space space = cpu_session->affinity_space(); + Genode::Cpu_connection * cpu = cpu_connection(RTTHREADTYPE_EMULATION); + Genode::Affinity::Space space = cpu->affinity_space(); Genode::Affinity::Location location(space.location_of_index(cpu_id)); if (create_emt_vcpu(thread, stack_size, start_routine, arg, - cpu_session, location, cpu_id, rtthread->szName, + cpu, location, cpu_id, rtthread->szName, prio_class(rtthread->enmType))) return 0; /* @@ -124,10 +124,24 @@ static int create_thread(pthread_t *thread, const pthread_attr_t *attr, * and 'rtTimerLRThread' (timerlr-generic.cpp) */ bool const rtthread_timer = rtthread->enmType == RTTHREADTYPE_TIMER; - return Libc::pthread_create(thread, start_routine, arg, - stack_size, rtthread->szName, - rtthread_timer ? nullptr : cpu_connection(rtthread->enmType), - Genode::Affinity::Location()); + + if (rtthread_timer) { + return Libc::pthread_create(thread, start_routine, arg, + stack_size, rtthread->szName, nullptr, + Genode::Affinity::Location()); + + } else { + using namespace Genode; + Cpu_connection *cpu = cpu_connection(rtthread->enmType); + return cpu->retry_with_upgrade(Ram_quota{8*1024}, Cap_quota{2}, + [&] () + { + return Libc::pthread_create(thread, start_routine, arg, + stack_size, rtthread->szName, cpu, + Genode::Affinity::Location()); + }); + } + } extern "C" int pthread_create(pthread_t *thread, const pthread_attr_t *attr, @@ -139,7 +153,8 @@ extern "C" int pthread_create(pthread_t *thread, const pthread_attr_t *attr, for (unsigned i = 0; i < 2; i++) { using namespace Genode; - try { return create_thread(thread, attr, start_routine, arg); } + try { + return create_thread(thread, attr, start_routine, arg); } catch (Out_of_ram) { log("Upgrading memory for creation of " "thread '", Cstring(rtthread->szName), "'");