From bb00aebc9ec449feb8060c59baa42ac739c44c0f Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Thu, 8 Aug 2013 20:18:41 +0200 Subject: [PATCH] hw & signal: consider initial SLAB blocks By now Signal_session_component has allocated initial SLAB blocks in constructor, wich crashed with the root components assumptions about the RAM quota needs of session creation. Thus, if the background allocator was already exhausted from component allocation the session was created with broken initial SLAB blocks. fix #574 --- base-hw/src/base/signal/signal.cc | 24 ++++++++++--------- base-hw/src/core/include/signal_root.h | 17 +++++++++++++ .../core/include/signal_session_component.h | 17 ++++++++++--- base-hw/src/core/signal_session_component.cc | 16 ++++--------- base/include/signal_session/connection.h | 2 +- 5 files changed, 49 insertions(+), 27 deletions(-) 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()) { } };