diff --git a/base-hw/src/base/signal/signal.cc b/base-hw/src/base/signal/signal.cc index 8b8a611ee3..a04b27102b 100644 --- a/base-hw/src/base/signal/signal.cc +++ b/base-hw/src/base/signal/signal.cc @@ -92,15 +92,16 @@ Signal_receiver::Signal_receiver() while (1) { try { _cap = s->alloc_receiver(); - break; + return; } catch (Signal_session::Out_of_metadata) { /* upgrade session quota and try again, but only once */ if (session_upgraded) { - PDBG("Failed to alloc signal receiver"); - break; + PERR("failed to alloc signal receiver"); + _cap = Signal_receiver_capability(); + return; } - PINF("upgrading quota donation for Signal session"); + PINF("upgrading quota donation for SIGNAL session"); env()->parent()->upgrade(s->cap(), "ram_quota=4K"); session_upgraded = 1; } @@ -149,20 +150,21 @@ Signal_context_capability Signal_receiver::manage(Signal_context * const c) while (1) { try { c->_cap = s->alloc_context(_cap, (unsigned)c); - break; + c->_receiver = this; + _contexts.insert(&c->_receiver_le); + return c->_cap; } catch (Signal_session::Out_of_metadata) { /* upgrade session quota and try again, but only once */ - PINF("upgrading quota donation for Signal session"); - if (session_upgraded) return Signal_context_capability(); + if (session_upgraded) { + PERR("failed to alloc signal context"); + return Signal_context_capability(); + } + PINF("upgrading quota donation for SIGNAL session"); env()->parent()->upgrade(s->cap(), "ram_quota=4K"); session_upgraded = 1; } } - /* assign the context to us */ - c->_receiver = this; - _contexts.insert(&c->_receiver_le); - return c->_cap; } diff --git a/base-hw/src/core/include/signal_root.h b/base-hw/src/core/include/signal_root.h index b8426a58e3..3bfa4f36ac 100644 --- a/base-hw/src/core/include/signal_root.h +++ b/base-hw/src/core/include/signal_root.h @@ -16,6 +16,7 @@ /* Genode includes */ #include +#include /* core includes */ #include @@ -75,6 +76,22 @@ namespace Genode { size_t ram_quota = Arg_string::find_arg(args, "ram_quota").long_value(0); + + /* + * FIXME + * We check these assertions because space for initial SLAB + * blocks can be scaled pragmatically only via + * RECEIVERS_SLAB_BLOCK_SIZE and CONTEXTS_SLAB_BLOCK_SIZE + * (array size can't come from a function) + */ + if (Signal_session_component::RECEIVERS_SB_SIZE < + 32 * Kernel::signal_receiver_size() || + Signal_session_component::CONTEXTS_SB_SIZE < + 32 * Kernel::signal_context_size()) + { + PERR("Undersized SLAB blocks"); + throw Root::Exception(); + } return new (md_alloc()) Signal_session_component(md_alloc(), ram_quota); } diff --git a/base-hw/src/core/include/signal_session_component.h b/base-hw/src/core/include/signal_session_component.h index e11129d445..84c2c8030e 100644 --- a/base-hw/src/core/include/signal_session_component.h +++ b/base-hw/src/core/include/signal_session_component.h @@ -27,9 +27,20 @@ namespace Genode */ class Signal_session_component : public Rpc_object { - Allocator_guard _md_alloc; /* Metadata allocator */ - Slab _receivers_slab; /* SLAB to allocate receiver kernel-objects */ - Slab _contexts_slab; /* SLAB to allocate context kernel-objects */ + public: + + enum { + RECEIVERS_SB_SIZE = 4096, + CONTEXTS_SB_SIZE = 4096, + }; + + private: + + Allocator_guard _md_alloc; + Slab _receivers_slab; + Slab _contexts_slab; + char _initial_receivers_sb [RECEIVERS_SB_SIZE]; + char _initial_contexts_sb [CONTEXTS_SB_SIZE]; public: diff --git a/base-hw/src/core/signal_session_component.cc b/base-hw/src/core/signal_session_component.cc index 90bbf539e2..370f0cb2ac 100644 --- a/base-hw/src/core/signal_session_component.cc +++ b/base-hw/src/core/signal_session_component.cc @@ -20,22 +20,14 @@ using namespace Genode; -enum { - RECEIVER_SLAB_CHUNK_SIZE = 32, - CONTEXT_SLAB_CHUNK_SIZE = 32, -}; - Signal_session_component::Signal_session_component(Allocator * const md, size_t const ram_quota) : _md_alloc(md, ram_quota), - _receivers_slab(Kernel::signal_receiver_size(), - RECEIVER_SLAB_CHUNK_SIZE * Kernel::signal_receiver_size(), - 0, &_md_alloc), - - _contexts_slab(Kernel::signal_context_size(), - CONTEXT_SLAB_CHUNK_SIZE * Kernel::signal_context_size(), - 0, &_md_alloc) + _receivers_slab(Kernel::signal_receiver_size(), RECEIVERS_SB_SIZE, + (Slab_block *)&_initial_receivers_sb, &_md_alloc), + _contexts_slab(Kernel::signal_context_size(), CONTEXTS_SB_SIZE, + (Slab_block *)&_initial_contexts_sb, &_md_alloc) { } diff --git a/base/include/signal_session/connection.h b/base/include/signal_session/connection.h index a669c56859..db0971b001 100644 --- a/base/include/signal_session/connection.h +++ b/base/include/signal_session/connection.h @@ -23,7 +23,7 @@ namespace Genode { { Signal_connection() : - Connection(session("ram_quota=8K")), + Connection(session("ram_quota=12K")), Signal_session_client(cap()) { } };