rump: Stabilize rump libs and fs server

* Perform sanity check before calculating memory available to rump kernel
* Distinguish between 'Hard_context' and 'Hard_context_thread', so no dead
  threads (that will not be started) are created
* Install signal-handler for memory-resource requests. This way the fs server
  will not block forever when the quota is execeeded and a resource requests
  fails, leaving the rump kernels to perform necessary actions

Fixes #1127
This commit is contained in:
Sebastian Sumpf 2014-04-23 15:17:54 +02:00 committed by Christian Helmuth
parent 4dd2db7634
commit b1a6db090f
5 changed files with 55 additions and 27 deletions

View File

@ -88,11 +88,11 @@ namespace Allocator {
/* lookup phys. address */
_ds_phys[_index] = Genode::Dataspace_client(_ds_cap[_index]).phys_addr();
} catch (Genode::Ram_session::Quota_exceeded) {
PERR("Backend allocator exhausted");
PWRN("Backend allocator exhausted");
_quota_exceeded = true;
return false;
} catch (Genode::Rm_session::Attach_failed) {
PERR("Backend VM region exhausted");
PWRN("Backend VM region exhausted");
_quota_exceeded = true;
return false;
}
@ -116,7 +116,7 @@ namespace Allocator {
}
/**
* Allocate
* Allocate
*/
bool alloc(size_t size, void **out_addr)
{
@ -126,10 +126,8 @@ namespace Allocator {
return done;
done = _alloc_block();
if (!done) {
PERR("Backend allocator exhausted\n");
if (!done)
return false;
}
return _range.alloc(size, out_addr);
}

View File

@ -33,14 +33,33 @@ namespace Timer {
class Connection;
};
class Hard_context : public Genode::Thread<sizeof(Genode::addr_t) * 2048>
class Hard_context
{
private:
func _func;
void *_arg;
int _cookie;
lwp *_lwp;
int _cookie;
lwp *_lwp = 0;
public:
Hard_context(int cookie)
: _cookie(cookie){ }
void set_lwp(lwp *l) { _lwp = l; }
lwp *get_lwp() { return _lwp; }
static Timer::Connection *timer();
};
class Hard_context_thread : public Hard_context,
public Genode::Thread<sizeof(Genode::addr_t) * 2048>
{
private:
func _func;
void *_arg;
protected:
@ -52,14 +71,10 @@ class Hard_context : public Genode::Thread<sizeof(Genode::addr_t) * 2048>
public:
Hard_context(char const *name, func f, void *arg, int cookie, bool run = true)
: Thread(name),
_func(f), _arg(arg), _cookie(cookie), _lwp(0) { if (run) start(); }
void set_lwp(lwp *l) { _lwp = l; }
lwp *get_lwp() { return _lwp; }
static Timer::Connection *timer();
Hard_context_thread(char const *name, func f, void *arg, int cookie, bool run = true)
: Hard_context(cookie), Thread(name),
_func(f), _arg(arg) { if (run) start(); }
};
#endif /* _INCLUDE__HARD_CONTEXT_H_ */

View File

@ -61,7 +61,7 @@ int rumpuser_init(int version, const struct rumpuser_hyperup *hyp)
** Threads **
*************/
static Hard_context _main_thread("main thread", 0, 0, 0, false);
static Hard_context _main_thread(0);
static Hard_context *myself()
{
@ -108,7 +108,7 @@ int rumpuser_thread_create(func f, void *arg, const char *name,
if (mustjoin)
*cookie = (void *)++count;
new (Genode::env()->heap()) Hard_context(name, f, arg, mustjoin ? count : 0);
new (Genode::env()->heap()) Hard_context_thread(name, f, arg, mustjoin ? count : 0);
return 0;
}
@ -123,6 +123,8 @@ void rumpuser_seterrno(int e) { errno = e; }
int rumpuser_getparam(const char *name, void *buf, size_t buflen)
{
enum { RESERVE_MEM = 2U * 1024 * 1024 };
/* support one cpu */
PDBG("%s", name);
if (!Genode::strcmp(name, "_RUMPUSER_NCPU")) {
@ -139,11 +141,18 @@ int rumpuser_getparam(const char *name, void *buf, size_t buflen)
if (!Genode::strcmp(name, "RUMP_MEMLIMIT")) {
/* leave 2 MB for the Genode */
size_t rump_ram = Genode::env()->ram_session()->avail() - (2 * 1024 * 1024);
size_t rump_ram = Genode::env()->ram_session()->avail();
if (rump_ram <= RESERVE_MEM) {
PERR("Insufficient quota need left: %zu < %u bytes", rump_ram, RESERVE_MEM);
return -1;
}
rump_ram -= RESERVE_MEM;
/* convert to string */
Genode::snprintf((char *)buf, buflen, "%zu", rump_ram);
PINF("Asserting rump kernel %zu KB of RAM", rump_ram / 1024);
PERR("Asserting rump kernel %zu KB of RAM", rump_ram / 1024);
return 0;
}

View File

@ -39,7 +39,7 @@ struct Packet : Genode::List<Packet>::Element
};
class Backend : public Hard_context
class Backend : public Hard_context_thread
{
private:
@ -211,7 +211,7 @@ class Backend : public Hard_context
public:
Backend()
: Hard_context("block_io", 0, 0, 0, false),
: Hard_context_thread("block_io", 0, 0, 0, false),
_alloc(Genode::env()->heap()),
_session(&_alloc),
_alloc_sem(COUNT),

View File

@ -426,7 +426,8 @@ class File_system::Root : public Root_component<Session_component>
struct File_system::Main
{
Server::Entrypoint &ep;
Server::Entrypoint &ep;
Server::Signal_rpc_member<Main> resource_dispatcher;
/*
* Initialize root interface
@ -436,12 +437,17 @@ struct File_system::Main
Root fs_root = { ep, sliced_heap };
/* return immediately from resource requests */
void resource_handler(unsigned) { }
Main(Server::Entrypoint &ep)
:
ep(ep)
ep(ep),
resource_dispatcher(ep, *this, &Main::resource_handler)
{
File_system::init(ep);
env()->parent()->announce(ep.manage(fs_root));
env()->parent()->resource_avail_sigh(resource_dispatcher);
}
};