Implement RAM accounting
This commit is contained in:
parent
bcf6714eff
commit
cf9610a958
|
@ -77,7 +77,7 @@ namespace Genode {
|
||||||
virtual int ref_account(Ram_session_capability ram_session) = 0;
|
virtual int ref_account(Ram_session_capability ram_session) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transfer quota the another ram session
|
* Transfer quota to another RAM session
|
||||||
*
|
*
|
||||||
* \param ram_session receiver of quota donation
|
* \param ram_session receiver of quota donation
|
||||||
* \param amount amount of quota to donate
|
* \param amount amount of quota to donate
|
||||||
|
|
|
@ -44,7 +44,9 @@ namespace Loader {
|
||||||
Cpu_connection cpu;
|
Cpu_connection cpu;
|
||||||
Rm_connection rm;
|
Rm_connection rm;
|
||||||
|
|
||||||
Resources(char const *label, size_t ram_quota)
|
Resources(char const *label,
|
||||||
|
Ram_session_client &ram_session_client,
|
||||||
|
size_t ram_quota)
|
||||||
: ram(label), cpu(label)
|
: ram(label), cpu(label)
|
||||||
{
|
{
|
||||||
/* deduce session costs from usable ram quota */
|
/* deduce session costs from usable ram quota */
|
||||||
|
@ -56,8 +58,8 @@ namespace Loader {
|
||||||
ram_quota -= session_donations;
|
ram_quota -= session_donations;
|
||||||
else ram_quota = 0;
|
else ram_quota = 0;
|
||||||
|
|
||||||
ram.ref_account(env()->ram_session_cap());
|
ram.ref_account(ram_session_client);
|
||||||
env()->ram_session()->transfer_quota(ram.cap(), ram_quota);
|
ram_session_client.transfer_quota(ram.cap(), ram_quota);
|
||||||
}
|
}
|
||||||
} _resources;
|
} _resources;
|
||||||
|
|
||||||
|
@ -87,6 +89,7 @@ namespace Loader {
|
||||||
Child(const char *binary_name,
|
Child(const char *binary_name,
|
||||||
const char *label,
|
const char *label,
|
||||||
Rpc_entrypoint &ep,
|
Rpc_entrypoint &ep,
|
||||||
|
Ram_session_client &ram_session_client,
|
||||||
size_t ram_quota,
|
size_t ram_quota,
|
||||||
Service_registry &parent_services,
|
Service_registry &parent_services,
|
||||||
Service &local_rom_service,
|
Service &local_rom_service,
|
||||||
|
@ -95,7 +98,7 @@ namespace Loader {
|
||||||
:
|
:
|
||||||
_label(label),
|
_label(label),
|
||||||
_ep(ep),
|
_ep(ep),
|
||||||
_resources(_label.string, ram_quota),
|
_resources(_label.string, ram_session_client, ram_quota),
|
||||||
_parent_services(parent_services),
|
_parent_services(parent_services),
|
||||||
_local_nitpicker_service(local_nitpicker_service),
|
_local_nitpicker_service(local_nitpicker_service),
|
||||||
_local_rom_service(local_rom_service),
|
_local_rom_service(local_rom_service),
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/env.h>
|
#include <base/env.h>
|
||||||
|
#include <base/heap.h>
|
||||||
#include <base/rpc_server.h>
|
#include <base/rpc_server.h>
|
||||||
#include <base/signal.h>
|
#include <base/signal.h>
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <child.h>
|
#include <child.h>
|
||||||
#include <nitpicker.h>
|
#include <nitpicker.h>
|
||||||
|
#include <ram_session_client_guard.h>
|
||||||
#include <rom.h>
|
#include <rom.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +41,7 @@ namespace Loader {
|
||||||
struct Local_rom_service : Service
|
struct Local_rom_service : Service
|
||||||
{
|
{
|
||||||
Rpc_entrypoint &_ep;
|
Rpc_entrypoint &_ep;
|
||||||
|
Allocator &_md_alloc;
|
||||||
Parent_service _parent_rom_service;
|
Parent_service _parent_rom_service;
|
||||||
Rom_module_registry &_rom_modules;
|
Rom_module_registry &_rom_modules;
|
||||||
Lock _lock;
|
Lock _lock;
|
||||||
|
@ -47,15 +50,17 @@ namespace Loader {
|
||||||
void _close(Rom_session_component *rom)
|
void _close(Rom_session_component *rom)
|
||||||
{
|
{
|
||||||
_ep.dissolve(rom);
|
_ep.dissolve(rom);
|
||||||
destroy(env()->heap(), rom);
|
destroy(&_md_alloc, rom);
|
||||||
_rom_sessions.remove(rom);
|
_rom_sessions.remove(rom);
|
||||||
}
|
}
|
||||||
|
|
||||||
Local_rom_service(Rpc_entrypoint &ep,
|
Local_rom_service(Rpc_entrypoint &ep,
|
||||||
|
Allocator &md_alloc,
|
||||||
Rom_module_registry &rom_modules)
|
Rom_module_registry &rom_modules)
|
||||||
:
|
:
|
||||||
Service("virtual_rom"),
|
Service("virtual_rom"),
|
||||||
_ep(ep),
|
_ep(ep),
|
||||||
|
_md_alloc(md_alloc),
|
||||||
_parent_rom_service(Rom_session::service_name()),
|
_parent_rom_service(Rom_session::service_name()),
|
||||||
_rom_modules(rom_modules)
|
_rom_modules(rom_modules)
|
||||||
{ }
|
{ }
|
||||||
|
@ -82,7 +87,7 @@ namespace Loader {
|
||||||
|
|
||||||
Rom_module &module = _rom_modules.lookup_and_lock(name);
|
Rom_module &module = _rom_modules.lookup_and_lock(name);
|
||||||
|
|
||||||
Rom_session_component *rom = new (env()->heap())
|
Rom_session_component *rom = new (&_md_alloc)
|
||||||
Rom_session_component(module);
|
Rom_session_component(module);
|
||||||
|
|
||||||
_rom_sessions.insert(rom);
|
_rom_sessions.insert(rom);
|
||||||
|
@ -118,14 +123,19 @@ namespace Loader {
|
||||||
struct Local_nitpicker_service : Service
|
struct Local_nitpicker_service : Service
|
||||||
{
|
{
|
||||||
Rpc_entrypoint &ep;
|
Rpc_entrypoint &ep;
|
||||||
|
Allocator &_md_alloc;
|
||||||
|
|
||||||
Signal_context_capability view_ready_sigh;
|
Signal_context_capability view_ready_sigh;
|
||||||
|
|
||||||
Nitpicker::Session_component *open_session;
|
Nitpicker::Session_component *open_session;
|
||||||
|
|
||||||
Local_nitpicker_service(Rpc_entrypoint &ep)
|
Local_nitpicker_service(Rpc_entrypoint &ep,
|
||||||
|
Allocator &md_alloc)
|
||||||
:
|
:
|
||||||
Service("virtual_nitpicker"), ep(ep), open_session(0)
|
Service("virtual_nitpicker"),
|
||||||
|
ep(ep),
|
||||||
|
_md_alloc(md_alloc),
|
||||||
|
open_session(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Local_nitpicker_service()
|
~Local_nitpicker_service()
|
||||||
|
@ -134,7 +144,7 @@ namespace Loader {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ep.dissolve(open_session);
|
ep.dissolve(open_session);
|
||||||
destroy(env()->heap(), open_session);
|
destroy(&_md_alloc, open_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::Session_capability session(const char *args)
|
Genode::Session_capability session(const char *args)
|
||||||
|
@ -142,11 +152,7 @@ namespace Loader {
|
||||||
if (open_session)
|
if (open_session)
|
||||||
throw Unavailable();
|
throw Unavailable();
|
||||||
|
|
||||||
/*
|
open_session = new (&_md_alloc)
|
||||||
* XXX replace allocation from 'env()->heap()' with
|
|
||||||
* use of session-specific allocator
|
|
||||||
*/
|
|
||||||
open_session = new (env()->heap())
|
|
||||||
Nitpicker::Session_component(ep, view_ready_sigh, args);
|
Nitpicker::Session_component(ep, view_ready_sigh, args);
|
||||||
|
|
||||||
return ep.manage(open_session);
|
return ep.manage(open_session);
|
||||||
|
@ -158,6 +164,8 @@ namespace Loader {
|
||||||
enum { STACK_SIZE = 2*4096 };
|
enum { STACK_SIZE = 2*4096 };
|
||||||
|
|
||||||
size_t _ram_quota;
|
size_t _ram_quota;
|
||||||
|
Ram_session_client_guard _ram_session_client;
|
||||||
|
Heap _md_alloc;
|
||||||
size_t _subsystem_ram_quota_limit;
|
size_t _subsystem_ram_quota_limit;
|
||||||
int _width, _height;
|
int _width, _height;
|
||||||
Rpc_entrypoint _ep;
|
Rpc_entrypoint _ep;
|
||||||
|
@ -186,19 +194,21 @@ namespace Loader {
|
||||||
Session_component(size_t quota, Ram_session &ram, Cap_session &cap)
|
Session_component(size_t quota, Ram_session &ram, Cap_session &cap)
|
||||||
:
|
:
|
||||||
_ram_quota(quota),
|
_ram_quota(quota),
|
||||||
_subsystem_ram_quota_limit(~0),
|
_ram_session_client(env()->ram_session_cap(), _ram_quota),
|
||||||
|
_md_alloc(&_ram_session_client, env()->rm_session()),
|
||||||
|
_subsystem_ram_quota_limit(0),
|
||||||
_width(-1), _height(-1),
|
_width(-1), _height(-1),
|
||||||
_ep(&cap, STACK_SIZE, "session_ep"),
|
_ep(&cap, STACK_SIZE, "session_ep"),
|
||||||
_rom_modules(ram, *env()->heap()), /* XXX remove env()->heap() */
|
_rom_modules(_ram_session_client, _md_alloc),
|
||||||
_rom_service(_ep, _rom_modules),
|
_rom_service(_ep, _md_alloc, _rom_modules),
|
||||||
_nitpicker_service(_ep),
|
_nitpicker_service(_ep, _md_alloc),
|
||||||
_child(0)
|
_child(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Session_component()
|
~Session_component()
|
||||||
{
|
{
|
||||||
if (_child)
|
if (_child)
|
||||||
destroy(env()->heap(), _child);
|
destroy(&_md_alloc, _child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -241,18 +251,14 @@ namespace Loader {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
size_t const ram_quota = (_subsystem_ram_quota_limit > 0) ?
|
||||||
* XXX account for ROM modules
|
min(_subsystem_ram_quota_limit, _ram_session_client.avail()) :
|
||||||
*/
|
_ram_session_client.avail();
|
||||||
size_t const ram_quota = _subsystem_ram_quota_limit;
|
|
||||||
|
|
||||||
/*
|
_child = new (&_md_alloc)
|
||||||
* XXX don't use 'env()->heap()'
|
|
||||||
*/
|
|
||||||
_child = new (env()->heap())
|
|
||||||
Child(binary_name.string(), label.string(), _ep,
|
Child(binary_name.string(), label.string(), _ep,
|
||||||
ram_quota, _parent_services, _rom_service,
|
_ram_session_client, ram_quota, _parent_services,
|
||||||
_nitpicker_service, _width, _height);
|
_rom_service, _nitpicker_service, _width, _height);
|
||||||
}
|
}
|
||||||
|
|
||||||
Nitpicker::View_capability view()
|
Nitpicker::View_capability view()
|
||||||
|
|
94
os/src/server/loader/ram_session_client_guard.h
Normal file
94
os/src/server/loader/ram_session_client_guard.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* \brief A guard for RAM session clients to limit memory exhaustion
|
||||||
|
* \author Christian Prochaska
|
||||||
|
* \date 2012-04-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RAM_SESSION_CLIENT_GUARD_H_
|
||||||
|
#define _RAM_SESSION_CLIENT_GUARD_H_
|
||||||
|
|
||||||
|
#include <base/lock.h>
|
||||||
|
#include <base/printf.h>
|
||||||
|
#include <dataspace/client.h>
|
||||||
|
#include <ram_session/client.h>
|
||||||
|
|
||||||
|
namespace Genode {
|
||||||
|
|
||||||
|
class Ram_session_client_guard : public Ram_session_client
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
size_t _amount; /* total amount */
|
||||||
|
size_t _consumed; /* already consumed bytes */
|
||||||
|
Lock _consumed_lock;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Ram_session_client_guard(Ram_session_capability session, size_t amount)
|
||||||
|
: Ram_session_client(session), _amount(amount), _consumed(0) { }
|
||||||
|
|
||||||
|
Ram_dataspace_capability alloc(size_t size)
|
||||||
|
{
|
||||||
|
Lock::Guard _consumed_lock_guard(_consumed_lock);
|
||||||
|
|
||||||
|
if ((_amount - _consumed) < size) {
|
||||||
|
PWRN("Quota exceeded! amount=%zu, size=%zu, consumed=%zu",
|
||||||
|
_amount, size, _consumed);
|
||||||
|
return Ram_dataspace_capability();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ram_dataspace_capability cap = Ram_session_client::alloc(size);
|
||||||
|
|
||||||
|
_consumed += size;
|
||||||
|
|
||||||
|
return cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(Ram_dataspace_capability ds)
|
||||||
|
{
|
||||||
|
Lock::Guard _consumed_lock_guard(_consumed_lock);
|
||||||
|
|
||||||
|
_consumed -= Dataspace_client(ds).size();
|
||||||
|
|
||||||
|
Ram_session_client::free(ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
int transfer_quota(Ram_session_capability ram_session, size_t amount)
|
||||||
|
{
|
||||||
|
Lock::Guard _consumed_lock_guard(_consumed_lock);
|
||||||
|
|
||||||
|
if ((_amount - _consumed) < amount) {
|
||||||
|
PWRN("Quota exceeded! amount=%zu, size=%zu, consumed=%zu",
|
||||||
|
_amount, amount, _consumed);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = Ram_session_client::transfer_quota(ram_session, amount);
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
_consumed += amount;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t quota()
|
||||||
|
{
|
||||||
|
return _amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t used()
|
||||||
|
{
|
||||||
|
Lock::Guard _consumed_lock_guard(_consumed_lock);
|
||||||
|
return _consumed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _RAM_SESSION_CLIENT_GUARD_H_ */
|
Loading…
Reference in New Issue
Block a user