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
This commit is contained in:
Martin Stein 2013-08-08 20:18:41 +02:00 committed by Norman Feske
parent 9b28395f0d
commit bb00aebc9e
5 changed files with 49 additions and 27 deletions

View File

@ -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;
}

View File

@ -16,6 +16,7 @@
/* Genode includes */
#include <root/component.h>
#include <kernel/syscalls.h>
/* core includes */
#include <signal_session_component.h>
@ -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);
}

View File

@ -27,9 +27,20 @@ namespace Genode
*/
class Signal_session_component : public Rpc_object<Signal_session>
{
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:

View File

@ -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)
{ }

View File

@ -23,7 +23,7 @@ namespace Genode {
{
Signal_connection()
:
Connection<Signal_session>(session("ram_quota=8K")),
Connection<Signal_session>(session("ram_quota=12K")),
Signal_session_client(cap())
{ }
};