Integrate core's RAM service into the PD service

Fixes #2407
This commit is contained in:
Norman Feske 2017-05-11 20:03:28 +02:00 committed by Christian Helmuth
parent 5a3a1c704b
commit 0167d5af50
93 changed files with 871 additions and 1545 deletions

View File

@ -29,7 +29,7 @@ SRC_CC += stack_area.cc \
platform_pd.cc \
platform_services.cc \
platform_thread.cc \
ram_session_component.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
region_map_component.cc \
region_map_support.cc \
@ -50,7 +50,7 @@ LIBS += base-fiasco-common syscall-fiasco cxx
include $(GEN_CORE_DIR)/version.inc
vpath main.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cap_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)

View File

@ -27,7 +27,7 @@ SRC_CC += stack_area.cc \
platform_pd.cc \
platform_services.cc \
platform_thread.cc \
ram_session_component.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
ram_dataspace_factory.cc \
region_map_component.cc \
@ -58,7 +58,7 @@ vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath main.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath region_map_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)

View File

@ -35,7 +35,7 @@ SRC_CC += platform.cc
SRC_CC += platform_pd.cc
SRC_CC += platform_thread.cc
SRC_CC += stack_area.cc
SRC_CC += ram_session_component.cc
SRC_CC += pd_session_component.cc
SRC_CC += ram_dataspace_support.cc
SRC_CC += region_map_component.cc
SRC_CC += rom_session_component.cc

View File

@ -19,6 +19,6 @@ using namespace Genode;
void Pd_session_component::session_quota_upgraded()
{
_pd.upgrade_slab(_sliced_heap);
_pd->upgrade_slab(_sliced_heap);
}

View File

@ -8,7 +8,7 @@ SRC_CC = main.cc \
platform.cc \
platform_thread.cc \
platform_services.cc \
ram_session_component.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
rom_session_component.cc \
cpu_session_component.cc \
@ -48,7 +48,7 @@ LD_SCRIPT_STATIC = $(BASE_DIR)/src/ld/genode.ld \
include $(GEN_CORE_DIR)/version.inc
vpath main.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_support.cc $(GEN_CORE_DIR)
vpath cpu_thread_component.cc $(GEN_CORE_DIR)

View File

@ -19,6 +19,7 @@
#include <linux_native_cpu/client.h>
/* base-internal includes */
#include <base/internal/expanding_pd_session_client.h>
#include <base/internal/local_capability.h>
#include <base/internal/region_map_mmap.h>
#include <base/internal/stack_area.h>
@ -26,13 +27,13 @@
namespace Genode { struct Local_pd_session; }
struct Genode::Local_pd_session : Pd_session_client
struct Genode::Local_pd_session : Expanding_pd_session_client
{
Region_map_mmap _address_space { false };
Region_map_mmap _stack_area { true, stack_area_virtual_size() };
Region_map_mmap _linker_area { true, Pd_session::LINKER_AREA_SIZE };
Local_pd_session(Pd_session_capability pd) : Pd_session_client(pd) { }
Local_pd_session(Pd_session_capability pd) : Expanding_pd_session_client(pd) { }
Capability<Region_map> address_space()
{

View File

@ -21,7 +21,7 @@
/* base-internal includes */
#include <base/internal/expanding_cpu_session_client.h>
#include <base/internal/expanding_region_map_client.h>
#include <base/internal/expanding_ram_session_client.h>
#include <base/internal/expanding_pd_session_client.h>
#include <base/internal/expanding_parent_client.h>
#include <base/internal/region_map_mmap.h>
#include <base/internal/local_rm_session.h>
@ -42,8 +42,6 @@ class Genode::Platform_env_base : public Env_deprecated
{
private:
Ram_session_capability _ram_session_cap;
Expanding_ram_session_client _ram_session_client;
Cpu_session_capability _cpu_session_cap;
Expanding_cpu_session_client _cpu_session_client;
Region_map_mmap _region_map_mmap;
@ -64,12 +62,9 @@ class Genode::Platform_env_base : public Env_deprecated
/**
* Constructor
*/
Platform_env_base(Ram_session_capability ram_cap,
Cpu_session_capability cpu_cap,
Platform_env_base(Cpu_session_capability cpu_cap,
Pd_session_capability pd_cap)
:
_ram_session_cap(ram_cap),
_ram_session_client(_ram_session_cap, Parent::Env::ram()),
_cpu_session_cap(cpu_cap),
_cpu_session_client(cpu_cap, Parent::Env::cpu()),
_region_map_mmap(false),
@ -77,13 +72,21 @@ class Genode::Platform_env_base : public Env_deprecated
_local_pd_session(_pd_session_cap)
{ }
/**
* Constructor used by 'Core_env'
*/
Platform_env_base()
:
Platform_env_base(Cpu_session_capability(), Pd_session_capability())
{ }
/******************************
** Env_deprecated interface **
******************************/
Ram_session *ram_session() override { return &_ram_session_client; }
Ram_session_capability ram_session_cap() override { return _ram_session_cap; }
Ram_session *ram_session() override { return &_local_pd_session; }
Ram_session_capability ram_session_cap() override { return _pd_session_cap; }
Region_map *rm_session() override { return &_region_map_mmap; }
Cpu_session *cpu_session() override { return &_cpu_session_client; }
Cpu_session_capability cpu_session_cap() override { return _cpu_session_cap; }

View File

@ -155,8 +155,7 @@ Local_parent &Platform_env::_parent()
Platform_env::Platform_env()
:
Platform_env_base(static_cap_cast<Ram_session>(_parent().session_cap(Parent::Env::ram())),
static_cap_cast<Cpu_session>(_parent().session_cap(Parent::Env::cpu())),
Platform_env_base(static_cap_cast<Cpu_session>(_parent().session_cap(Parent::Env::cpu())),
static_cap_cast<Pd_session> (_parent().session_cap(Parent::Env::pd()))),
_heap(Platform_env_base::ram_session(), Platform_env_base::rm_session()),
_emergency_ram_ds(ram_session()->alloc(_emergency_ram_size()))

View File

@ -12,7 +12,7 @@
*/
#include <base/component.h>
#include <ram_session/connection.h>
#include <pd_session/connection.h>
#include <timer_session/connection.h>
using namespace Genode;
@ -22,17 +22,16 @@ static void test_linux_rmmap_bug(Env &env)
enum { QUOTA = 1*1024*1024, CHUNK = 0x1000, ROUNDS = 0x10 };
log("line: ", __LINE__);
Ram_connection ram(env);
Pd_connection pd(env);
#if 1 /* transfer quota */
log("line: ", __LINE__);
ram.ref_account(env.ram_session_cap());
env.ram().transfer_quota(ram.cap(), QUOTA);
#endif
pd.ref_account(env.pd_session_cap());
env.pd().transfer_quota(pd.cap(), Ram_quota{QUOTA});
env.pd().transfer_quota(pd.cap(), Cap_quota{30});
log("line: ", __LINE__);
for (unsigned i = 0; i < ROUNDS; ++i) {
Ram_dataspace_capability ds(ram.alloc(CHUNK));
Ram_dataspace_capability ds(pd.alloc(CHUNK));
log(i + 1, " of ", (unsigned)ROUNDS, " pages allocated");
}

View File

@ -32,7 +32,7 @@ SRC_CC += stack_area.cc \
platform_pd.cc \
platform_services.cc \
platform_thread.cc \
ram_session_component.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
region_map_component.cc \
region_map_support.cc \
@ -51,7 +51,7 @@ INC_DIR = $(REP_DIR)/src/core/include \
include $(GEN_CORE_DIR)/version.inc
vpath main.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_support.cc $(GEN_CORE_DIR)

View File

@ -21,10 +21,10 @@ bool Pd_session_component::assign_pci(addr_t pci_config_memory, uint16_t bdf)
{
uint8_t res = Nova::NOVA_PD_OOM;
do {
res = Nova::assign_pci(_pd.pd_sel(), pci_config_memory, bdf);
res = Nova::assign_pci(_pd->pd_sel(), pci_config_memory, bdf);
} while (res == Nova::NOVA_PD_OOM &&
Nova::NOVA_OK == Pager_object::handle_oom(Pager_object::SRC_CORE_PD,
_pd.pd_sel(),
_pd->pd_sel(),
"core", "ep",
Pager_object::Policy::UPGRADE_CORE_TO_DST));

View File

@ -32,7 +32,7 @@ SRC_CC += stack_area.cc \
platform_pd.cc \
platform_services.cc \
platform_thread.cc \
ram_session_component.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
region_map_component.cc \
region_map_support.cc \
@ -49,7 +49,7 @@ INC_DIR += $(REP_DIR)/src/core/include $(GEN_CORE_DIR)/include \
include $(GEN_CORE_DIR)/version.inc
vpath main.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_support.cc $(GEN_CORE_DIR)

View File

@ -30,7 +30,7 @@ SRC_CC = stack_area.cc \
platform_pd.cc \
platform_services.cc \
platform_thread.cc \
ram_session_component.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
region_map_component.cc \
region_map_support.cc \
@ -47,7 +47,7 @@ INC_DIR += $(REP_DIR)/src/core/include $(GEN_CORE_DIR)/include \
include $(GEN_CORE_DIR)/version.inc
vpath main.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_support.cc $(GEN_CORE_DIR)

View File

@ -2,7 +2,7 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC += \
main.cc \
ram_session_component.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
rom_session_component.cc \
cpu_session_component.cc \
@ -46,7 +46,7 @@ INC_DIR += $(REP_DIR)/src/core/include $(GEN_CORE_DIR)/include \
include $(GEN_CORE_DIR)/version.inc
vpath main.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_support.cc $(GEN_CORE_DIR)

View File

@ -202,6 +202,8 @@ class Genode::Platform : public Platform_generic
{
return 1UL << Core_cspace::NUM_CORE_SEL_LOG2;
}
bool core_needs_platform_pd() const override { return false; }
};
#endif /* _CORE__INCLUDE__PLATFORM_H_ */

View File

@ -14,8 +14,8 @@
#ifndef _INCLUDE__BASE__ATTACHED_RAM_DATASPACE_H_
#define _INCLUDE__BASE__ATTACHED_RAM_DATASPACE_H_
#include <ram_session/ram_session.h>
#include <util/touch.h>
#include <base/ram_allocator.h>
#include <base/env.h>
namespace Genode { class Attached_ram_dataspace; }
@ -35,7 +35,7 @@ class Genode::Attached_ram_dataspace
private:
size_t _size;
Ram_session *_ram;
Ram_allocator *_ram;
Region_map *_rm;
Ram_dataspace_capability _ds;
void *_local_addr = nullptr;
@ -93,7 +93,7 @@ class Genode::Attached_ram_dataspace
* \throw Region_map::Region_conflict
* \throw Region_map::Invalid_dataspace
*/
Attached_ram_dataspace(Ram_session &ram, Region_map &rm,
Attached_ram_dataspace(Ram_allocator &ram, Region_map &rm,
size_t size, Cache_attribute cached = CACHED)
:
_size(size), _ram(&ram), _rm(&rm), _cached(cached)
@ -105,10 +105,10 @@ class Genode::Attached_ram_dataspace
* Constructor
*
* \noapi
* \deprecated Use the constructor with the 'Ram_session &' and
* \deprecated Use the constructor with the 'Ram_allocator &' and
* 'Region_map &' arguments instead.
*/
Attached_ram_dataspace(Ram_session *ram, size_t size,
Attached_ram_dataspace(Ram_allocator *ram, size_t size,
Cache_attribute cached = CACHED) __attribute__((deprecated))
:
_size(size), _ram(ram), _rm(env_deprecated()->rm_session()), _cached(cached)
@ -154,14 +154,14 @@ class Genode::Attached_ram_dataspace
*
* The content of the original dataspace is not retained.
*/
void realloc(Ram_session *ram_session, size_t new_size)
void realloc(Ram_allocator *ram_allocator, size_t new_size)
{
if (new_size < _size) return;
_detach_and_free_dataspace();
_size = new_size;
_ram = ram_session;
_ram = ram_allocator;
_alloc_and_attach();
}

View File

@ -21,12 +21,12 @@
#include <base/local_connection.h>
#include <base/quota_guard.h>
#include <util/arg_string.h>
#include <ram_session/connection.h>
#include <region_map/client.h>
#include <pd_session/connection.h>
#include <cpu_session/connection.h>
#include <log_session/connection.h>
#include <rom_session/connection.h>
#include <ram_session/capability.h>
#include <parent/capability.h>
namespace Genode {
@ -138,21 +138,11 @@ struct Genode::Child_policy
* Reference PD session
*
* The PD session returned by this method is used for session cap-quota
* transfers.
* and RAM-quota transfers.
*/
virtual Pd_session &ref_pd() = 0;
virtual Pd_session_capability ref_pd_cap() const = 0;
/**
* Reference RAM session
*
* The RAM session returned by this method is used for session-quota
* transfers.
*/
virtual Ram_session &ref_ram() = 0;
virtual Ram_session_capability ref_ram_cap() const = 0;
/**
* Respond to the release of resources by the child
*
@ -166,14 +156,6 @@ struct Genode::Child_policy
*/
virtual void resource_request(Parent::Resource_args const &) { }
/**
* Initialize the child's RAM session
*
* The function must define the child's reference account and transfer
* the child's initial RAM quota.
*/
virtual void init(Ram_session &, Capability<Ram_session>) = 0;
/**
* Initialize the child's CPU session
*
@ -185,8 +167,10 @@ struct Genode::Child_policy
/**
* Initialize the child's PD session
*
* The function may install a region-map fault handler for the child's
* address space ('Pd_session::address_space');.
* The function must define the child's reference account and transfer
* the child's initial RAM and capability quotas. It may also install a
* region-map fault handler for the child's address space
* ('Pd_session::address_space');.
*/
virtual void init(Pd_session &, Capability<Pd_session>) { }
@ -207,7 +191,7 @@ struct Genode::Child_policy
/**
* Granularity of allocating the backing store for session meta data
*
* Session meta data is allocated from 'ref_ram'. The first batch of
* Session meta data is allocated from 'ref_pd'. The first batch of
* session-state objects is allocated at child-construction time.
*/
virtual size_t session_alloc_batch_size() const { return 16; }
@ -332,7 +316,7 @@ class Genode::Child : protected Rpc_object<Parent>,
Id_space<Client> _id_space;
/* allocator used for dynamically created session state objects */
Sliced_heap _session_md_alloc { _policy.ref_ram(), _local_rm };
Sliced_heap _session_md_alloc { _policy.ref_pd(), _local_rm };
Session_state::Factory::Batch_size const
_session_batch_size { _policy.session_alloc_batch_size() };
@ -593,7 +577,6 @@ class Genode::Child : protected Rpc_object<Parent>,
: Capability<SESSION>(); }
};
Env_connection<Ram_connection> _ram { *this, Env::ram(), _policy.name() };
Env_connection<Pd_connection> _pd { *this, Env::pd(), _policy.name() };
Env_connection<Cpu_connection> _cpu { *this, Env::cpu(), _policy.name() };
Env_connection<Log_connection> _log { *this, Env::log(), _policy.name() };
@ -688,16 +671,15 @@ class Genode::Child : protected Rpc_object<Parent>,
*/
static Ram_quota env_ram_quota()
{
return { Cpu_connection::RAM_QUOTA + Ram_connection::RAM_QUOTA +
Pd_connection::RAM_QUOTA + Log_connection::RAM_QUOTA +
2*Rom_connection::RAM_QUOTA };
return { Cpu_connection::RAM_QUOTA + Pd_connection::RAM_QUOTA +
Log_connection::RAM_QUOTA + 2*Rom_connection::RAM_QUOTA };
}
static Cap_quota env_cap_quota()
{
return { Cpu_connection::CAP_QUOTA + Ram_connection::CAP_QUOTA +
Pd_connection::CAP_QUOTA + Log_connection::CAP_QUOTA +
2*Rom_connection::CAP_QUOTA + 1 /* parent cap */ };
return { Cpu_connection::CAP_QUOTA + Pd_connection::CAP_QUOTA +
Log_connection::CAP_QUOTA + 2*Rom_connection::CAP_QUOTA +
1 /* parent cap */ };
}
template <typename FN>
@ -722,13 +704,13 @@ class Genode::Child : protected Rpc_object<Parent>,
return _effective_quota(quota, env_cap_quota());
}
Ram_session_capability ram_session_cap() const { return _ram.cap(); }
Ram_session_capability ram_session_cap() const { return _pd.cap(); }
Pd_session_capability pd_session_cap() const { return _pd.cap(); }
Parent_capability parent_cap() const { return cap(); }
Ram_session &ram() { return _ram.session(); }
Ram_session const &ram() const { return _ram.session(); }
Ram_session &ram() { return _pd.session(); }
Ram_session const &ram() const { return _pd.session(); }
Cpu_session &cpu() { return _cpu.session(); }
Pd_session &pd() { return _pd .session(); }
Pd_session const &pd() const { return _pd .session(); }

View File

@ -15,7 +15,6 @@
#define _INCLUDE__BASE__SERVICE_H_
#include <util/list.h>
#include <ram_session/client.h>
#include <pd_session/client.h>
#include <base/env.h>
#include <base/session_state.h>
@ -411,8 +410,7 @@ class Genode::Child_service : public Async_service
{
private:
Ram_session_client _ram;
Pd_session_client _pd;
Pd_session_client _pd;
public:
@ -423,11 +421,10 @@ class Genode::Child_service : public Async_service
Id_space<Parent::Server> &server_id_space,
Session_state::Factory &factory,
Wakeup &wakeup,
Ram_session_capability ram,
Pd_session_capability ram,
Pd_session_capability pd)
:
Async_service(name, server_id_space, factory, wakeup),
_ram(ram), _pd(pd)
Async_service(name, server_id_space, factory, wakeup), _pd(pd)
{ }
/**
@ -435,13 +432,13 @@ class Genode::Child_service : public Async_service
*/
void transfer(Ram_session_capability to, Ram_quota amount) override
{
if (to.valid()) _ram.transfer_quota(to, amount);
if (to.valid()) _pd.transfer_quota(to, amount);
}
/**
* Ram_transfer::Account interface
*/
Ram_session_capability cap(Ram_quota) const override { return _ram; }
Pd_session_capability cap(Ram_quota) const override { return _pd; }
/**
* Cap_transfer::Account interface

View File

@ -21,7 +21,7 @@
#include <parent/parent.h>
#include <region_map/region_map.h>
#include <rm_session/rm_session.h> /* deprecated, kept for API compatibility only */
#include <ram_session/ram_session.h>
#include <ram_session/capability.h>
#include <cpu_session/cpu_session.h>
#include <cpu_session/capability.h>
#include <pd_session/capability.h>

View File

@ -66,18 +66,18 @@ class Genode::Parent
*/
struct Env
{
static Client::Id ram() { return { 1 }; }
static Client::Id pd() { return { 1 }; }
static Client::Id cpu() { return { 2 }; }
static Client::Id pd() { return { 3 }; }
static Client::Id log() { return { 4 }; }
static Client::Id binary() { return { 5 }; }
static Client::Id linker() { return { 6 }; }
static Client::Id log() { return { 3 }; }
static Client::Id binary() { return { 4 }; }
static Client::Id linker() { return { 5 }; }
static Client::Id last() { return { 5 }; }
/**
* True if session ID refers to an environment session
*/
static bool session_id(Client::Id id) {
return id.value >= 1 && id.value <= 6; }
return id.value >= 1 && id.value <= last().value; }
};
/**

View File

@ -15,7 +15,7 @@
#define _INCLUDE__PD_SESSION__CLIENT_H_
#include <pd_session/capability.h>
#include <base/rpc_client.h>
#include <dataspace/client.h>
namespace Genode { struct Pd_session_client; }
@ -71,6 +71,25 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
Cap_quota cap_quota() const { return call<Rpc_cap_quota>(); }
Cap_quota used_caps() const { return call<Rpc_used_caps>(); }
Ram_dataspace_capability alloc(size_t size,
Cache_attribute cached = CACHED) override
{
return call<Rpc_alloc>(size, cached);
}
void free(Ram_dataspace_capability ds) override { call<Rpc_free>(ds); }
size_t dataspace_size(Ram_dataspace_capability ds) const override
{
return ds.valid() ? Dataspace_client(ds).size() : 0;
}
void transfer_quota(Pd_session_capability ram_session, Ram_quota amount) override {
call<Rpc_transfer_ram_quota>(ram_session, amount); }
Ram_quota ram_quota() const override { return call<Rpc_ram_quota>(); }
Ram_quota used_ram() const override { return call<Rpc_used_ram>(); }
Capability<Native_pd> native_pd() override { return call<Rpc_native_pd>(); }
};

View File

@ -22,7 +22,7 @@ namespace Genode { struct Pd_connection; }
struct Genode::Pd_connection : Connection<Pd_session>, Pd_session_client
{
enum { RAM_QUOTA = 20*1024*sizeof(long) };
enum { RAM_QUOTA = 24*1024*sizeof(long)};
/**
* Constructor

View File

@ -3,8 +3,6 @@
* \author Christian Helmuth
* \author Norman Feske
* \date 2006-06-27
*
* A pd session represents the protection domain of a program.
*/
/*
@ -21,9 +19,9 @@
#include <thread/capability.h>
#include <session/session.h>
#include <region_map/region_map.h>
#include <base/ram_allocator.h>
namespace Genode {
struct Pd_session;
struct Pd_session_client;
struct Parent;
@ -31,7 +29,7 @@ namespace Genode {
}
struct Genode::Pd_session : Session
struct Genode::Pd_session : Session, Ram_allocator
{
static const char *service_name() { return "PD"; }
@ -40,8 +38,11 @@ struct Genode::Pd_session : Session
* allocation, a capability for the 'Native_pd' RPC interface, its
* session capability, and the RPC capabilities for the 3 contained
* region maps.
*
* Furthermore, we account for the dataspace capabilities allocated during
* the component bootstrapping.
*/
enum { CAP_QUOTA = 6 };
enum { CAP_QUOTA = 6 + 7 };
typedef Pd_session_client Client;
@ -195,8 +196,8 @@ struct Genode::Pd_session : Session
/**
* Transfer capability quota to another PD session
*
* \param pd_session receiver of quota donation
* \param amount amount of quota to donate
* \param to receiver of quota donation
* \param amount amount of quota to donate
*
* \throw Out_of_caps
* \throw Invalid_session
@ -205,8 +206,7 @@ struct Genode::Pd_session : Session
* Quota can only be transfered if the specified PD session is either the
* reference account for this session or vice versa.
*/
virtual void transfer_quota(Capability<Pd_session> pd_session,
Cap_quota amount) = 0;
virtual void transfer_quota(Capability<Pd_session> to, Cap_quota amount) = 0;
/**
* Return current capability-quota limit
@ -224,6 +224,46 @@ struct Genode::Pd_session : Session
}
/***********************************
** RAM allocation and accounting **
***********************************/
/*
* Note that the 'Pd_session' inherits the 'Ram_allocator' interface,
* which comprises the actual allocation and deallocation operations.
*/
/**
* Transfer quota to another RAM session
*
* \param to receiver of quota donation
* \param amount amount of quota to donate
*
* \throw Out_of_ram
* \throw Invalid_session
* \throw Undefined_ref_account
*
* Quota can only be transfered if the specified PD session is either the
* reference account for this session or vice versa.
*/
virtual void transfer_quota(Capability<Pd_session> to, Ram_quota amount) = 0;
/**
* Return current quota limit
*/
virtual Ram_quota ram_quota() const = 0;
/**
* Return used quota
*/
virtual Ram_quota used_ram() const = 0;
/**
* Return amount of available quota
*/
Ram_quota avail_ram() const { return { ram_quota().value - used_ram().value }; }
/*****************************************
** Access to kernel-specific interface **
*****************************************/
@ -273,6 +313,16 @@ struct Genode::Pd_session : Session
GENODE_RPC(Rpc_cap_quota, Cap_quota, cap_quota);
GENODE_RPC(Rpc_used_caps, Cap_quota, used_caps);
GENODE_RPC_THROW(Rpc_alloc, Ram_dataspace_capability, alloc,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps, Undefined_ref_account),
size_t, Cache_attribute);
GENODE_RPC(Rpc_free, void, free, Ram_dataspace_capability);
GENODE_RPC_THROW(Rpc_transfer_ram_quota, void, transfer_quota,
GENODE_TYPE_LIST(Out_of_ram, Invalid_session, Undefined_ref_account),
Capability<Pd_session>, Ram_quota);
GENODE_RPC(Rpc_ram_quota, Ram_quota, ram_quota);
GENODE_RPC(Rpc_used_ram, Ram_quota, used_ram);
GENODE_RPC(Rpc_native_pd, Capability<Native_pd>, native_pd);
GENODE_RPC_INTERFACE(Rpc_assign_parent, Rpc_assign_pci,
@ -281,6 +331,8 @@ struct Genode::Pd_session : Session
Rpc_alloc_rpc_cap, Rpc_free_rpc_cap, Rpc_address_space,
Rpc_stack_area, Rpc_linker_area, Rpc_ref_account,
Rpc_transfer_cap_quota, Rpc_cap_quota, Rpc_used_caps,
Rpc_alloc, Rpc_free,
Rpc_transfer_ram_quota, Rpc_ram_quota, Rpc_used_ram,
Rpc_native_pd);
};

View File

@ -22,8 +22,8 @@ namespace Genode {
* We cannot include 'ram_session/ram_session.h' because this file relies
* on the the 'Ram_session_capability' type.
*/
class Ram_session;
typedef Capability<Ram_session> Ram_session_capability;
class Pd_session;
typedef Capability<Pd_session> Ram_session_capability;
}
#endif /* _INCLUDE__RAM_SESSION__CAPABILITY_H_ */

View File

@ -1,53 +0,0 @@
/*
* \brief Client-side RAM session interface
* \author Norman Feske
* \date 2006-05-31
*/
/*
* Copyright (C) 2006-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__RAM_SESSION__CLIENT_H_
#define _INCLUDE__RAM_SESSION__CLIENT_H_
#include <ram_session/capability.h>
#include <ram_session/ram_session.h>
#include <dataspace/client.h>
namespace Genode { struct Ram_session_client; }
struct Genode::Ram_session_client : Rpc_client<Ram_session>
{
explicit Ram_session_client(Ram_session_capability session)
: Rpc_client<Ram_session>(session) { }
Ram_dataspace_capability alloc(size_t size,
Cache_attribute cached = CACHED) override
{
return call<Rpc_alloc>(size, cached);
}
void free(Ram_dataspace_capability ds) override { call<Rpc_free>(ds); }
size_t dataspace_size(Ram_dataspace_capability ds) const override
{
return ds.valid() ? Dataspace_client(ds).size() : 0;
}
void ref_account(Ram_session_capability ram_session) override {
call<Rpc_ref_account>(ram_session); }
void transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override {
call<Rpc_transfer_ram_quota>(ram_session, amount); }
Ram_quota ram_quota() const override { return call<Rpc_ram_quota>(); }
Ram_quota used_ram() const override { return call<Rpc_used_ram>(); }
};
#endif /* _INCLUDE__RAM_SESSION__CLIENT_H_ */

View File

@ -1,67 +0,0 @@
/*
* \brief Connection to RAM service
* \author Norman Feske
* \date 2008-08-22
*/
/*
* Copyright (C) 2008-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__RAM_SESSION__CONNECTION_H_
#define _INCLUDE__RAM_SESSION__CONNECTION_H_
#include <ram_session/client.h>
#include <base/connection.h>
namespace Genode { struct Ram_connection; }
struct Genode::Ram_connection : Connection<Ram_session>, Ram_session_client
{
enum { RAM_QUOTA = 4096*sizeof(long) };
/**
* Issue session request
*
* \noapi
*/
Capability<Ram_session> _session(Parent &parent, char const *label,
addr_t phys_start, size_t phys_size)
{
return session(parent,
"ram_quota=%u, cap_quota=%u, phys_start=0x%lx, phys_size=0x%lx, "
"label=\"%s\"", RAM_QUOTA, CAP_QUOTA, phys_start, phys_size, label);
}
/**
* Constructor
*
* \param label session label
*/
Ram_connection(Env &env, const char *label = "", unsigned long phys_start = 0UL,
unsigned long phys_size = 0UL)
:
Connection<Ram_session>(env, _session(env.parent(), label, phys_start, phys_size)),
Ram_session_client(cap())
{ }
/**
* Constructor
*
* \noapi
* \deprecated Use the constructor with 'Env &' as first
* argument instead
*/
Ram_connection(const char *label = "", unsigned long phys_start = 0UL,
unsigned long phys_size = 0UL) __attribute__((deprecated))
:
Connection<Ram_session>(_session(*env_deprecated()->parent(), label, phys_start, phys_size)),
Ram_session_client(cap())
{ }
};
#endif /* _INCLUDE__RAM_SESSION__CONNECTION_H_ */

View File

@ -2,6 +2,8 @@
* \brief RAM session interface
* \author Norman Feske
* \date 2006-05-11
*
* \deprecated The RAM session interface is integrated in the PD session now.
*/
/*
@ -14,103 +16,8 @@
#ifndef _INCLUDE__RAM_SESSION__RAM_SESSION_H_
#define _INCLUDE__RAM_SESSION__RAM_SESSION_H_
#include <base/stdint.h>
#include <base/ram_allocator.h>
#include <dataspace/capability.h>
#include <ram_session/capability.h>
#include <session/session.h>
#include <pd_session/pd_session.h>
namespace Genode {
struct Ram_session_client;
struct Ram_session;
}
/**
* RAM session interface
*/
struct Genode::Ram_session : Session, Ram_allocator
{
static const char *service_name() { return "RAM"; }
enum { CAP_QUOTA = 8 };
typedef Ram_session_client Client;
/*********************
** Exception types **
*********************/
class Invalid_session : public Exception { };
class Undefined_ref_account : public Exception { };
/**
* Destructor
*/
virtual ~Ram_session() { }
/**
* Define reference account for the RAM session
*
* \param ram_session reference account
*
* \throw Invalid_session
*
* Each RAM session requires another RAM session as reference
* account to transfer quota to and from. The reference account can
* be defined only once.
*/
virtual void ref_account(Ram_session_capability ram_session) = 0;
/**
* Transfer quota to another RAM session
*
* \param ram_session receiver of quota donation
* \param amount amount of quota to donate
*
* \throw Out_of_ram
* \throw Invalid_session
* \throw Undefined_ref_account
*
* Quota can only be transfered if the specified RAM session is
* either the reference account for this session or vice versa.
*/
virtual void transfer_quota(Ram_session_capability ram_session, Ram_quota amount) = 0;
/**
* Return current quota limit
*/
virtual Ram_quota ram_quota() const = 0;
/**
* Return used quota
*/
virtual Ram_quota used_ram() const = 0;
/**
* Return amount of available quota
*/
Ram_quota avail_ram() const { return { ram_quota().value - used_ram().value }; }
/*********************
** RPC declaration **
*********************/
GENODE_RPC_THROW(Rpc_alloc, Ram_dataspace_capability, alloc,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps, Undefined_ref_account),
size_t, Cache_attribute);
GENODE_RPC(Rpc_free, void, free, Ram_dataspace_capability);
GENODE_RPC(Rpc_ref_account, void, ref_account, Capability<Ram_session>);
GENODE_RPC_THROW(Rpc_transfer_ram_quota, void, transfer_quota,
GENODE_TYPE_LIST(Out_of_ram, Invalid_session, Undefined_ref_account),
Capability<Ram_session>, Ram_quota);
GENODE_RPC(Rpc_ram_quota, Ram_quota, ram_quota);
GENODE_RPC(Rpc_used_ram, Ram_quota, used_ram);
GENODE_RPC_INTERFACE(Rpc_alloc, Rpc_free, Rpc_ref_account,
Rpc_transfer_ram_quota, Rpc_ram_quota, Rpc_used_ram);
};
namespace Genode { typedef Pd_session Ram_session; }
#endif /* _INCLUDE__RAM_SESSION__RAM_SESSION_H_ */

View File

@ -185,8 +185,14 @@ class Genode::Root_component : public Rpc_object<Typed_root<SESSION_TYPE> >,
SESSION_TYPE *s = 0;
try { s = _create_session(adjusted_args, affinity); }
catch (Out_of_ram) { throw Insufficient_ram_quota(); }
catch (Out_of_caps) { throw Insufficient_cap_quota(); }
catch (Out_of_ram) { throw Insufficient_ram_quota(); }
catch (Out_of_caps) { throw Insufficient_cap_quota(); }
catch (Service_denied) { throw; }
catch (Insufficient_cap_quota) { throw; }
catch (Insufficient_ram_quota) { throw; }
catch (...) {
warning("unexpected exception during ",
SESSION_TYPE::service_name(), "-session creation"); }
/*
* Consider that the session-object constructor may already have

View File

@ -24,11 +24,12 @@
/* core includes */
#include <platform.h>
#include <core_region_map.h>
#include <ram_session_component.h>
#include <synced_ram_session.h>
#include <pd_session_component.h>
#include <synced_ram_allocator.h>
#include <assertion.h>
namespace Genode {
class Core_env;
extern Core_env *core_env();
}
@ -47,10 +48,10 @@ class Genode::Core_env : public Env_deprecated
bool _init_stack_area() { init_stack_area(); return true; }
bool _stack_area_initialized = _init_stack_area();
Rpc_entrypoint _entrypoint;
Core_region_map _region_map;
Ram_session_component _ram_session;
Synced_ram_session _synced_ram_session { _ram_session };
Rpc_entrypoint _entrypoint;
Core_region_map _region_map;
Pd_session_component _pd_session;
Synced_ram_allocator _synced_ram_allocator { _pd_session };
public:
@ -58,22 +59,26 @@ class Genode::Core_env : public Env_deprecated
:
_entrypoint(nullptr, ENTRYPOINT_STACK_SIZE, "entrypoint"),
_region_map(_entrypoint),
_ram_session(_entrypoint,
Session::Resources {
Ram_quota { platform()->ram_alloc()->avail() },
Cap_quota { platform()->max_caps() } },
Session::Label("core"),
Session::Diag{false},
*platform()->ram_alloc(),
_region_map,
Ram_dataspace_factory::any_phys_range())
_pd_session(_entrypoint,
Session::Resources {
Ram_quota { platform()->ram_alloc()->avail() },
Cap_quota { platform()->max_caps() } },
Session::Label("core"),
Session::Diag{false},
*platform()->ram_alloc(),
Ram_dataspace_factory::any_phys_range(),
_region_map,
*((Pager_entrypoint *)nullptr),
"" /* args to native PD */)
{
_ram_session.init_ram_account();
_pd_session.init_cap_and_ram_accounts();
}
~Core_env() { parent()->exit(0); }
Rpc_entrypoint *entrypoint() { return &_entrypoint; }
Rpc_entrypoint *entrypoint() { return &_entrypoint; }
Ram_allocator &ram_allocator() { return _synced_ram_allocator; }
Region_map &local_rm() { return _region_map; }
/******************************
@ -81,18 +86,17 @@ class Genode::Core_env : public Env_deprecated
******************************/
Parent *parent() override { return nullptr; }
Ram_session *ram_session() override { return &_synced_ram_session; }
Ram_session_capability ram_session_cap() override { return _ram_session.cap(); }
Ram_session *ram_session() override { return &_pd_session; }
Ram_session_capability ram_session_cap() override { return _pd_session.cap(); }
Region_map *rm_session() override { return &_region_map; }
Pd_session *pd_session() override { return nullptr; }
Pd_session *pd_session() override { return &_pd_session; }
Allocator *heap() override { ASSERT_NEVER_CALLED; }
Cpu_session *cpu_session() override { ASSERT_NEVER_CALLED; }
Cpu_session_capability cpu_session_cap() override { ASSERT_NEVER_CALLED; }
Pd_session_capability pd_session_cap() override { ASSERT_NEVER_CALLED; }
Pd_session_capability pd_session_cap() override { return _pd_session.cap(); }
void reinit(Capability<Parent>::Raw) override { }
void reinit_main_thread(Capability<Region_map> &) override { }
};
#endif /* _CORE__INCLUDE__CORE_ENV_H_ */

View File

@ -31,20 +31,31 @@ class Genode::Pd_root : public Genode::Root_component<Genode::Pd_session_compone
Rpc_entrypoint &_ep;
Pager_entrypoint &_pager_ep;
Ram_allocator &_ram_alloc;
Range_allocator &_phys_alloc;
Region_map &_local_rm;
static Ram_dataspace_factory::Phys_range _phys_range_from_args(char const *args)
{
addr_t const start = Arg_string::find_arg(args, "phys_start").ulong_value(0);
addr_t const size = Arg_string::find_arg(args, "phys_size").ulong_value(0);
addr_t const end = start + size - 1;
return (start <= end) ? Ram_dataspace_factory::Phys_range { start, end }
: Ram_dataspace_factory::any_phys_range();
}
protected:
Pd_session_component *_create_session(const char *args)
{
Pd_session_component *result = new (md_alloc())
return new (md_alloc())
Pd_session_component(_ep,
session_resources_from_args(args),
session_label_from_args(args),
session_diag_from_args(args),
_ram_alloc, _local_rm, _pager_ep, args);
return result;
_phys_alloc,
_phys_range_from_args(args),
_local_rm, _pager_ep, args);
}
void _upgrade_session(Pd_session_component *pd, const char *args)
@ -58,20 +69,15 @@ class Genode::Pd_root : public Genode::Root_component<Genode::Pd_session_compone
/**
* Constructor
*
* \param ep entry point for managing pd session objects,
* threads, and signal contexts
* \param ram_alloc allocator used for session-local allocations
* \param md_alloc meta-data allocator to be used by root component
*/
Pd_root(Rpc_entrypoint &ep,
Pager_entrypoint &pager_ep,
Ram_allocator &ram_alloc,
Range_allocator &phys_alloc,
Region_map &local_rm,
Allocator &md_alloc)
:
Root_component<Pd_session_component>(&ep, &md_alloc),
_ep(ep), _pager_ep(pager_ep), _ram_alloc(ram_alloc), _local_rm(local_rm)
_ep(ep), _pager_ep(pager_ep), _phys_alloc(phys_alloc), _local_rm(local_rm)
{ }
};

View File

@ -32,6 +32,7 @@
#include <platform_pd.h>
#include <signal_broker.h>
#include <rpc_cap_factory.h>
#include <ram_dataspace_factory.h>
#include <native_pd_component.h>
#include <region_map_component.h>
#include <platform_generic.h>
@ -44,30 +45,37 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
{
private:
Constrained_ram_allocator _constrained_md_ram_alloc;
Sliced_heap _sliced_heap;
Platform_pd _pd { &_sliced_heap, _label.string() };
Capability<Parent> _parent;
Rpc_entrypoint &_ep;
Pager_entrypoint &_pager_ep;
Signal_broker _signal_broker { _sliced_heap, _ep, _ep };
Rpc_cap_factory _rpc_cap_factory { _sliced_heap };
Native_pd_component _native_pd;
Rpc_entrypoint &_ep;
Constrained_ram_allocator _constrained_md_ram_alloc;
Sliced_heap _sliced_heap;
Constructible<Platform_pd> _pd { &_sliced_heap, _label.string() };
Capability<Parent> _parent;
Signal_broker _signal_broker;
Ram_dataspace_factory _ram_ds_factory;
Rpc_cap_factory _rpc_cap_factory;
Native_pd_component _native_pd;
Region_map_component _address_space;
Region_map_component _stack_area;
Region_map_component _linker_area;
Constructible<Account<Cap_quota> > _cap_account;
Constructible<Account<Ram_quota> > _ram_account;
friend class Native_pd_component;
enum Cap_type { RPC_CAP, SIG_SOURCE_CAP, SIG_CONTEXT_CAP, IGN_CAP };
/*****************************************
** Utilities for capability accounting **
*****************************************/
enum Cap_type { RPC_CAP, DS_CAP, SIG_SOURCE_CAP, SIG_CONTEXT_CAP, IGN_CAP };
char const *_name(Cap_type type)
{
switch (type) {
case RPC_CAP: return "RPC";
case DS_CAP: return "dataspace";
case SIG_SOURCE_CAP: return "signal-source";
case SIG_CONTEXT_CAP: return "signal-context";
default: return "";
@ -98,43 +106,49 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
public:
typedef Ram_dataspace_factory::Phys_range Phys_range;
/**
* Constructor
*
* \param ep entrypoint holding signal-receiver component
* objects, signal contexts, thread objects
* \param ram_alloc backing store for dynamically allocated
* session meta data
*/
Pd_session_component(Rpc_entrypoint &ep,
Resources resources,
Label const &label,
Diag diag,
Ram_allocator &ram_alloc,
Range_allocator &phys_alloc,
Phys_range phys_range,
Region_map &local_rm,
Pager_entrypoint &pager_ep,
char const *args)
:
Session_object(ep, resources, label, diag),
_constrained_md_ram_alloc(ram_alloc, *this, *this),
_ep(ep),
_constrained_md_ram_alloc(*this, *this, *this),
_sliced_heap(_constrained_md_ram_alloc, local_rm),
_ep(ep), _pager_ep(pager_ep),
_signal_broker(_sliced_heap, ep, ep),
_ram_ds_factory(ep, phys_alloc, phys_range, local_rm, _sliced_heap),
_rpc_cap_factory(_sliced_heap),
_native_pd(*this, args),
_address_space(ep, _sliced_heap, pager_ep,
platform()->vm_start(), platform()->vm_size()),
_stack_area (_ep, _sliced_heap, pager_ep, 0, stack_area_virtual_size()),
_linker_area(_ep, _sliced_heap, pager_ep, 0, LINKER_AREA_SIZE)
{ }
_stack_area (ep, _sliced_heap, pager_ep, 0, stack_area_virtual_size()),
_linker_area(ep, _sliced_heap, pager_ep, 0, LINKER_AREA_SIZE)
{
if (platform()->core_needs_platform_pd() || label != "core")
_pd.construct(&_sliced_heap, _label.string());
}
/**
* Initialize cap account without providing a reference account
* Initialize cap and RAM accounts without providing a reference account
*
* This method is solely used to set up the initial PD session within
* core. The cap accounts of regular PD session are initialized via
* 'ref_account'.
* This method is solely used to set up the initial PD within core. The
* accounts of regular PD sessions are initialized via 'ref_account'.
*/
void init_cap_account() { _cap_account.construct(*this, _label); }
void init_cap_and_ram_accounts()
{
_cap_account.construct(*this, _label);
_ram_account.construct(*this, _label);
}
/**
* Session_object interface
@ -152,7 +166,7 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
*/
bool bind_thread(Platform_thread &thread)
{
return _pd.bind_thread(&thread);
return _pd->bind_thread(&thread);
}
Region_map_component &address_space_region_map()
@ -160,19 +174,19 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
return _address_space;
}
/**************************
** PD session interface **
**************************/
void assign_parent(Capability<Parent> parent) override
{
_parent = parent;
_pd.assign_parent(parent);
_pd->assign_parent(parent);
}
bool assign_pci(addr_t, uint16_t) override;
/****************
** Signalling **
****************/
Signal_source_capability alloc_signal_source() override
{
_consume_cap(SIG_SOURCE_CAP);
@ -185,8 +199,10 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
void free_signal_source(Signal_source_capability sig_rec_cap) override
{
_signal_broker.free_signal_source(sig_rec_cap);
_released_cap(SIG_SOURCE_CAP);
if (sig_rec_cap.valid()) {
_signal_broker.free_signal_source(sig_rec_cap);
_released_cap(SIG_SOURCE_CAP);
}
}
Signal_context_capability
@ -194,6 +210,7 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
{
Cap_quota_guard::Reservation cap_costs(*this, Cap_quota{1});
try {
/* may throw 'Out_of_ram' or 'Invalid_signal_source' */
Signal_context_capability cap =
_signal_broker.alloc_context(sig_rec_cap, imprint);
@ -201,8 +218,6 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
diag("consumed signal-context cap (", _cap_account, ")");
return cap;
}
catch (Genode::Allocator::Out_of_memory) {
throw Out_of_ram(); }
catch (Signal_broker::Invalid_signal_source) {
throw Pd_session::Invalid_signal_source(); }
}
@ -216,14 +231,19 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
void submit(Signal_context_capability cap, unsigned n) override {
_signal_broker.submit(cap, n); }
/*
* \throw Out_of_caps by '_consume_cap'
* \throw Out_of_ram by '_rpc_cap_factory.alloc'
*/
/*******************************
** RPC capability allocation **
*******************************/
Native_capability alloc_rpc_cap(Native_capability ep) override
{
/* may throw 'Out_of_caps' */
_consume_cap(RPC_CAP);
return _rpc_cap_factory.alloc(ep);
/* may throw 'Out_of_ram' */
try { return _rpc_cap_factory.alloc(ep); }
catch (...) { _released_cap_silent(); throw; }
}
void free_rpc_cap(Native_capability cap) override
@ -232,63 +252,29 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
_released_cap(RPC_CAP);
}
Capability<Region_map> address_space() {
/******************************
** Address-space management **
******************************/
Capability<Region_map> address_space() override {
return _address_space.cap(); }
Capability<Region_map> stack_area() {
Capability<Region_map> stack_area() override {
return _stack_area.cap(); }
Capability<Region_map> linker_area() {
Capability<Region_map> linker_area() override {
return _linker_area.cap(); }
void ref_account(Capability<Pd_session> pd_cap) override
{
/* the reference account can be defined only once */
if (_cap_account.constructed())
return;
if (this->cap() == pd_cap)
return;
/***********************************************
** Capability and RAM trading and accounting **
***********************************************/
_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
void ref_account(Capability<Pd_session>) override;
if (!pd || !pd->_cap_account.constructed()) {
error("invalid PD session specified as ref account");
throw Invalid_session();
}
_cap_account.construct(*this, _label, *pd->_cap_account);
});
}
void transfer_quota(Capability<Pd_session> pd_cap, Cap_quota amount) override
{
/* the reference account can be defined only once */
if (!_cap_account.constructed())
throw Undefined_ref_account();
if (this->cap() == pd_cap)
return;
_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
if (!pd || !pd->_cap_account.constructed())
throw Invalid_session();
try {
_cap_account->transfer_quota(*pd->_cap_account, amount);
diag("transferred ", amount, " caps "
"to '", pd->_cap_account->label(), "' (", _cap_account, ")");
}
catch (Account<Cap_quota>::Unrelated_account) {
warning("attempt to transfer cap quota to unrelated PD session");
throw Invalid_session(); }
catch (Account<Cap_quota>::Limit_exceeded) {
warning("cap limit (", *_cap_account, ") exceeded "
"during transfer_quota(", amount, ")");
throw Out_of_caps(); }
});
}
void transfer_quota(Capability<Pd_session>, Cap_quota) override;
void transfer_quota(Capability<Pd_session>, Ram_quota) override;
Cap_quota cap_quota() const
{
@ -300,6 +286,32 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
return _cap_account.constructed() ? _cap_account->used() : Cap_quota { 0 };
}
Ram_quota ram_quota() const override
{
return _ram_account.constructed() ? _ram_account->limit() : Ram_quota { 0 };
}
Ram_quota used_ram() const override
{
return _ram_account.constructed() ? _ram_account->used() : Ram_quota { 0 };
}
/***********************************
** RAM allocation and accounting **
***********************************/
Ram_dataspace_capability alloc(size_t, Cache_attribute) override;
void free(Ram_dataspace_capability) override;
size_t dataspace_size(Ram_dataspace_capability) const override;
/*******************************************
** Platform-specific interface extension **
*******************************************/
Capability<Native_pd> native_pd() { return _native_pd.cap(); }
};

View File

@ -104,6 +104,11 @@ namespace Genode {
* Return system-wide maximum number of capabilities
*/
virtual size_t max_caps() const = 0;
/**
* Return true if the core component relies on a 'Platform_pd' object
*/
virtual bool core_needs_platform_pd() const { return true; }
};

View File

@ -1,74 +0,0 @@
/*
* \brief RAM root interface
* \author Norman Feske
* \date 2006-05-30
*/
/*
* Copyright (C) 2006-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__INCLUDE__RAM_ROOT_H_
#define _CORE__INCLUDE__RAM_ROOT_H_
#include <root/component.h>
#include "ram_session_component.h"
namespace Genode {
class Ram_root : public Root_component<Ram_session_component>
{
private:
Rpc_entrypoint &_ep;
Range_allocator &_phys_alloc;
Region_map &_local_rm;
static Ram_session_component::Phys_range phys_range_from_args(char const *args)
{
addr_t const start = Arg_string::find_arg(args, "phys_start").ulong_value(0);
addr_t const size = Arg_string::find_arg(args, "phys_size").ulong_value(0);
addr_t const end = start + size - 1;
return (start <= end) ? Ram_dataspace_factory::Phys_range { start, end }
: Ram_dataspace_factory::any_phys_range();
}
protected:
Ram_session_component *_create_session(const char *args)
{
return new (md_alloc())
Ram_session_component(_ep,
session_resources_from_args(args),
session_label_from_args(args),
session_diag_from_args(args),
_phys_alloc, _local_rm,
phys_range_from_args(args));
}
void _upgrade_session(Ram_session_component *ram, const char *args)
{
ram->Ram_quota_guard::upgrade(ram_quota_from_args(args));
ram->Cap_quota_guard::upgrade(cap_quota_from_args(args));
ram->session_quota_upgraded();
}
public:
Ram_root(Rpc_entrypoint &ep,
Range_allocator &phys_alloc,
Region_map &local_rm,
Allocator &md_alloc)
:
Root_component<Ram_session_component>(&ep, &md_alloc),
_ep(ep), _phys_alloc(phys_alloc), _local_rm(local_rm)
{ }
};
}
#endif /* _CORE__INCLUDE__RAM_ROOT_H_ */

View File

@ -1,94 +0,0 @@
/*
* \brief Core-specific instance of the RAM session interface
* \author Norman Feske
* \date 2006-06-19
*/
/*
* Copyright (C) 2006-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__INCLUDE__RAM_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__RAM_SESSION_COMPONENT_H_
/* Genode includes */
#include <base/heap.h>
#include <base/session_object.h>
/* core includes */
#include <ram_dataspace_factory.h>
#include <account.h>
namespace Genode { class Ram_session_component; }
class Genode::Ram_session_component : public Session_object<Ram_session>
{
private:
Rpc_entrypoint &_ep;
Constrained_ram_allocator _constrained_md_ram_alloc;
Sliced_heap _sliced_heap;
Constructible<Account<Ram_quota> > _ram_account;
Ram_dataspace_factory _ram_ds_factory;
public:
typedef Ram_dataspace_factory::Phys_range Phys_range;
Ram_session_component(Rpc_entrypoint &ep,
Resources resources,
Session_label const &label,
Diag diag,
Range_allocator &phys_alloc,
Region_map &local_rm,
Phys_range phys_range);
/**
* Initialize RAM account without providing a reference account
*
* This method is solely used to set up the initial RAM session within
* core. The RAM accounts of regular RAM session are initialized via
* 'ref_account'.
*/
void init_ram_account() { _ram_account.construct(*this, _label); }
/*****************************
** Ram_allocator interface **
*****************************/
Ram_dataspace_capability alloc(size_t, Cache_attribute) override;
void free(Ram_dataspace_capability) override;
size_t dataspace_size(Ram_dataspace_capability) const override;
/***************************
** RAM Session interface **
***************************/
void ref_account(Ram_session_capability) override;
void transfer_quota(Ram_session_capability, Ram_quota) override;
Ram_quota ram_quota() const override
{
return _ram_account.constructed() ? _ram_account->limit() : Ram_quota { 0 };
}
Ram_quota used_ram() const override
{
return _ram_account.constructed() ? _ram_account->used() : Ram_quota { 0 };
}
};
#endif /* _CORE__INCLUDE__RAM_SESSION_COMPONENT_H_ */

View File

@ -0,0 +1,55 @@
/*
* \brief Synchronized wrapper for the 'Ram_allocator' interface
* \author Norman Feske
* \date 2017-05-11
*/
/*
* Copyright (C) 2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__INCLUDE__SYNCED_RAM_ALLOCATOR_H_
#define _CORE__INCLUDE__SYNCED_RAM_ALLOCATOR_H_
/* Genode includes */
#include <base/ram_allocator.h>
#include <base/lock.h>
namespace Genode { class Synced_ram_allocator; }
class Genode::Synced_ram_allocator : public Ram_allocator
{
private:
Lock mutable _lock;
Ram_allocator &_alloc;
public:
Synced_ram_allocator(Ram_allocator &alloc) : _alloc(alloc) { }
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override
{
Lock::Guard lock_guard(_lock);
return _alloc.alloc(size, cached);
}
void free(Ram_dataspace_capability ds) override
{
Lock::Guard lock_guard(_lock);
_alloc.free(ds);
}
size_t dataspace_size(Ram_dataspace_capability ds) const override
{
Lock::Guard lock_guard(_lock);
return _alloc.dataspace_size(ds);
}
};
#endif /* _CORE__INCLUDE__SYNCED_RAM_ALLOCATOR_H_ */

View File

@ -1,78 +0,0 @@
/*
* \brief Synchronized wrapper for the 'Ram_session' interface
* \author Norman Feske
* \date 2017-05-11
*/
/*
* Copyright (C) 2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__INCLUDE__SYNCED_RAM_SESSION_H_
#define _CORE__INCLUDE__SYNCED_RAM_SESSION_H_
/* Genode includes */
#include <ram_session/ram_session.h>
#include <base/lock.h>
namespace Genode { class Synced_ram_session; }
class Genode::Synced_ram_session : public Ram_session
{
private:
Lock mutable _lock;
Ram_session &_ram_session;
public:
Synced_ram_session(Ram_session &ram_session) : _ram_session(ram_session) { }
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override
{
Lock::Guard lock_guard(_lock);
return _ram_session.alloc(size, cached);
}
void free(Ram_dataspace_capability ds) override
{
Lock::Guard lock_guard(_lock);
_ram_session.free(ds);
}
size_t dataspace_size(Ram_dataspace_capability ds) const override
{
Lock::Guard lock_guard(_lock);
return _ram_session.dataspace_size(ds);
}
void ref_account(Ram_session_capability session) override
{
Lock::Guard lock_guard(_lock);
_ram_session.ref_account(session);
}
void transfer_quota(Ram_session_capability session, Ram_quota amount) override
{
Lock::Guard lock_guard(_lock);
_ram_session.transfer_quota(session, amount);
}
Ram_quota ram_quota() const override
{
Lock::Guard lock_guard(_lock);
return _ram_session.ram_quota();
}
Ram_quota used_ram() const override
{
Lock::Guard lock_guard(_lock);
return _ram_session.used_ram();
}
};
#endif /* _CORE__INCLUDE__SYNCED_RAM_SESSION_H_ */

View File

@ -30,7 +30,6 @@
#include <core_env.h>
#include <core_service.h>
#include <signal_transmitter.h>
#include <ram_root.h>
#include <rom_root.h>
#include <rm_root.h>
#include <cpu_root.h>
@ -112,9 +111,6 @@ class Core_child : public Child_policy
Capability<Pd_session> _core_pd_cap;
Pd_session &_core_pd;
Capability<Ram_session> _core_ram_cap;
Ram_session &_core_ram;
Capability<Cpu_session> _core_cpu_cap;
Cpu_session &_core_cpu;
@ -128,20 +124,18 @@ class Core_child : public Child_policy
/**
* Constructor
*/
Core_child(Registry<Service> &services,
Core_child(Registry<Service> &services, Region_map &local_rm,
Pd_session &core_pd, Capability<Pd_session> core_pd_cap,
Ram_session &core_ram, Capability<Ram_session> core_ram_cap,
Cpu_session &core_cpu, Capability<Cpu_session> core_cpu_cap,
Cap_quota cap_quota, Ram_quota ram_quota)
:
_entrypoint(nullptr, STACK_SIZE, "init_child", false),
_services(services),
_core_pd_cap (core_pd_cap), _core_pd (core_pd),
_core_ram_cap(core_ram_cap), _core_ram(core_ram),
_core_cpu_cap(core_cpu_cap), _core_cpu(core_cpu),
_cap_quota(Child::effective_quota(cap_quota)),
_ram_quota(Child::effective_quota(ram_quota)),
_child(*env_deprecated()->rm_session(), _entrypoint, *this)
_child(local_rm, _entrypoint, *this)
{
_entrypoint.activate();
}
@ -171,12 +165,7 @@ class Core_child : public Child_policy
{
session.ref_account(_core_pd_cap);
_core_pd.transfer_quota(cap, _cap_quota);
}
void init(Ram_session &session, Capability<Ram_session> cap) override
{
session.ref_account(_core_ram_cap);
_core_ram.transfer_quota(cap, _ram_quota);
_core_pd.transfer_quota(cap, _ram_quota);
}
void init(Cpu_session &session, Capability<Cpu_session> cap) override
@ -188,8 +177,8 @@ class Core_child : public Child_policy
Pd_session &ref_pd() { return _core_pd; }
Pd_session_capability ref_pd_cap() const { return _core_pd_cap; }
Ram_session &ref_ram() { return _core_ram; }
Ram_session_capability ref_ram_cap() const { return _core_ram_cap; }
Ram_session &ref_ram() { return _core_pd; }
Ram_session_capability ref_ram_cap() const { return _core_pd_cap; }
size_t session_alloc_batch_size() const override { return 128; }
};
@ -244,16 +233,14 @@ int main()
static Trace::Policy_registry trace_policies;
/*
* Initialize root interfaces for our services
*/
Rpc_entrypoint *e = core_env()->entrypoint();
static Rpc_entrypoint &ep = *core_env()->entrypoint();
static Ram_allocator &core_ram_alloc = core_env()->ram_allocator();
static Region_map &local_rm = core_env()->local_rm();
Pd_session &core_pd = *core_env()->pd_session();
Capability<Pd_session> core_pd_cap = core_env()->pd_session_cap();
static Registry<Service> services;
static Ram_allocator &core_ram_alloc = *core_env()->ram_session();
static Region_map &local_rm = *core_env()->rm_session();
/*
* Allocate session meta data on distinct dataspaces to enable independent
* destruction (to enable quota trading) of session component objects.
@ -267,21 +254,19 @@ int main()
static Pager_entrypoint pager_ep(rpc_cap_factory);
static Ram_root ram_root (*e, *platform()->ram_alloc(), local_rm, sliced_heap);
static Rom_root rom_root (e, e, platform()->rom_fs(), &sliced_heap);
static Rm_root rm_root (e, &sliced_heap, pager_ep);
static Cpu_root cpu_root (e, e, &pager_ep, &sliced_heap,
Trace::sources());
static Pd_root pd_root (*e, pager_ep, core_ram_alloc, local_rm, sliced_heap);
static Log_root log_root (e, &sliced_heap);
static Io_mem_root io_mem_root (e, e, platform()->io_mem_alloc(),
platform()->ram_alloc(), &sliced_heap);
static Irq_root irq_root (core_env()->pd_session(),
platform()->irq_alloc(), &sliced_heap);
static Trace::Root trace_root (e, &sliced_heap, Trace::sources(), trace_policies);
static Rom_root rom_root (&ep, &ep, platform()->rom_fs(), &sliced_heap);
static Rm_root rm_root (&ep, &sliced_heap, pager_ep);
static Cpu_root cpu_root (&ep, &ep, &pager_ep, &sliced_heap,
Trace::sources());
static Pd_root pd_root (ep, pager_ep, *platform()->ram_alloc(), local_rm, sliced_heap);
static Log_root log_root (&ep, &sliced_heap);
static Io_mem_root io_mem_root (&ep, &ep, platform()->io_mem_alloc(),
platform()->ram_alloc(), &sliced_heap);
static Irq_root irq_root (core_env()->pd_session(),
platform()->irq_alloc(), &sliced_heap);
static Trace::Root trace_root (&ep, &sliced_heap, Trace::sources(), trace_policies);
static Core_service<Rom_session_component> rom_service (services, rom_root);
static Core_service<Ram_session_component> ram_service (services, ram_root);
static Core_service<Rm_session_component> rm_service (services, rm_root);
static Core_service<Cpu_session_component> cpu_service (services, cpu_root);
static Core_service<Pd_session_component> pd_service (services, pd_root);
@ -291,54 +276,39 @@ int main()
static Core_service<Trace::Session_component> trace_service (services, trace_root);
/* make platform-specific services known to service pool */
platform_add_local_services(e, &sliced_heap, &services);
platform_add_local_services(&ep, &sliced_heap, &services);
/* calculate number of capabilities to be assigned to init */
size_t const preservered_cap_quota = 1000;
size_t const avail_ram_quota = core_pd.avail_ram().value;
size_t const avail_cap_quota = core_pd.avail_caps().value;
if (platform()->max_caps() < preservered_cap_quota) {
error("platform cap limit lower than preservation for core");
size_t const preserved_ram_quota = 224*1024;
size_t const preserved_cap_quota = 1000;
if (avail_ram_quota < preserved_ram_quota) {
error("core preservation exceeds platform RAM limit");
return -1;
}
size_t const avail_cap_quota = platform()->max_caps() - preservered_cap_quota;
if (avail_cap_quota < preserved_cap_quota) {
error("core preservation exceeds platform cap quota limit");
return -1;
}
/* PD session representing core */
static Pd_session_component
core_pd(*e,
Session::Resources { Ram_quota { 16*1024 },
Cap_quota { avail_cap_quota } },
Session::Label("core"), Session::Diag{false},
core_ram_alloc, local_rm, pager_ep, "");
core_pd.init_cap_account();
Ram_quota const init_ram_quota { avail_ram_quota - preserved_ram_quota };
Cap_quota const init_cap_quota { avail_cap_quota - preserved_cap_quota };
/* CPU session representing core */
static Cpu_session_component
core_cpu(e, e, &pager_ep, &sliced_heap, Trace::sources(),
core_cpu(&ep, &ep, &pager_ep, &sliced_heap, Trace::sources(),
"label=\"core\"", Affinity(), Cpu_session::QUOTA_LIMIT);
Cpu_session_capability core_cpu_cap = core_env()->entrypoint()->manage(&core_cpu);
Cpu_session_capability core_cpu_cap = ep.manage(&core_cpu);
/* calculate RAM to be assigned to init */
size_t const platform_ram_limit = platform()->ram_alloc()->avail();
size_t const preserved_ram_quota = 224*1024;
if (platform_ram_limit < preserved_ram_quota) {
error("platform RAM limit lower than preservation for core");
return -1;
}
size_t const avail_ram_quota = platform_ram_limit - preserved_ram_quota;
log("", avail_ram_quota / (1024*1024), " MiB RAM and ", avail_cap_quota, " caps "
log("", init_ram_quota.value / (1024*1024), " MiB RAM and ", init_cap_quota, " caps "
"assigned to init");
static Reconstructible<Core_child>
init(services,
core_pd, core_pd.cap(),
*env_deprecated()->ram_session(), env_deprecated()->ram_session_cap(),
core_cpu, core_cpu_cap,
core_pd.cap_quota(), Ram_quota{avail_ram_quota});
init(services, local_rm, core_pd, core_pd_cap, core_cpu, core_cpu_cap,
init_cap_quota, init_ram_quota);
platform()->wait_for_exit();

View File

@ -1,5 +1,5 @@
/*
* \brief Core implementation of the RAM session interface
* \brief Core implementation of the PD session interface
* \author Norman Feske
* \date 2006-05-19
*/
@ -15,13 +15,13 @@
#include <base/log.h>
/* core includes */
#include <ram_session_component.h>
#include <pd_session_component.h>
using namespace Genode;
Ram_dataspace_capability
Ram_session_component::alloc(size_t ds_size, Cache_attribute cached)
Pd_session_component::alloc(size_t ds_size, Cache_attribute cached)
{
/* zero-sized dataspaces are not allowed */
if (!ds_size) return Ram_dataspace_capability();
@ -72,7 +72,7 @@ Ram_session_component::alloc(size_t ds_size, Cache_attribute cached)
}
void Ram_session_component::free(Ram_dataspace_capability ds_cap)
void Pd_session_component::free(Ram_dataspace_capability ds_cap)
{
if (this->cap() == ds_cap)
return;
@ -87,11 +87,11 @@ void Ram_session_component::free(Ram_dataspace_capability ds_cap)
_ram_account->replenish(Ram_quota{size});
/* capability of the dataspace RPC object */
Cap_quota_guard::replenish(Cap_quota{1});
_released_cap(DS_CAP);
}
size_t Ram_session_component::dataspace_size(Ram_dataspace_capability ds_cap) const
size_t Pd_session_component::dataspace_size(Ram_dataspace_capability ds_cap) const
{
if (this->cap() == ds_cap)
return 0;
@ -100,46 +100,76 @@ size_t Ram_session_component::dataspace_size(Ram_dataspace_capability ds_cap) co
}
void Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
void Pd_session_component::ref_account(Capability<Pd_session> pd_cap)
{
/* the reference account can be defined only once */
if (_ram_account.constructed())
if (_cap_account.constructed())
return;
if (this->cap() == ram_session_cap)
if (this->cap() == pd_cap)
return;
_ep.apply(ram_session_cap, [&] (Ram_session_component *ram) {
_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
if (!ram || !ram->_ram_account.constructed()) {
error("invalid RAM session specified as ref account");
if (!pd || !pd->_ram_account.constructed()) {
error("invalid PD session specified as ref account");
throw Invalid_session();
}
_ram_account.construct(*this, _label, *ram->_ram_account);
_cap_account.construct(*this, _label, *pd->_cap_account);
_ram_account.construct(*this, _label, *pd->_ram_account);
});
}
void Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap,
Ram_quota amount)
void Pd_session_component::transfer_quota(Capability<Pd_session> pd_cap,
Cap_quota amount)
{
/* the reference account can be defined only once */
if (!_ram_account.constructed())
if (!_cap_account.constructed())
throw Undefined_ref_account();
if (this->cap() == ram_session_cap)
if (this->cap() == pd_cap)
return;
_ep.apply(ram_session_cap, [&] (Ram_session_component *ram) {
_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
if (!ram || !ram->_ram_account.constructed())
if (!pd || !pd->_cap_account.constructed())
throw Invalid_session();
try {
_ram_account->transfer_quota(*ram->_ram_account, amount); }
_cap_account->transfer_quota(*pd->_cap_account, amount);
diag("transferred ", amount, " caps "
"to '", pd->_cap_account->label(), "' (", _cap_account, ")");
}
catch (Account<Cap_quota>::Unrelated_account) {
warning("attempt to transfer cap quota to unrelated PD session");
throw Invalid_session(); }
catch (Account<Cap_quota>::Limit_exceeded) {
warning("cap limit (", *_cap_account, ") exceeded "
"during transfer_quota(", amount, ")");
throw Out_of_caps(); }
});
}
void Pd_session_component::transfer_quota(Capability<Pd_session> pd_cap,
Ram_quota amount)
{
if (!_ram_account.constructed())
throw Undefined_ref_account();
if (this->cap() == pd_cap)
return;
_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
if (!pd || !pd->_ram_account.constructed())
throw Invalid_session();
try {
_ram_account->transfer_quota(*pd->_ram_account, amount); }
catch (Account<Ram_quota>::Unrelated_account) {
warning("attempt to transfer RAM quota to unrelated RAM session");
warning("attempt to transfer RAM quota to unrelated PD session");
throw Invalid_session(); }
catch (Account<Ram_quota>::Limit_exceeded) {
warning("RAM limit (", *_ram_account, ") exceeded "
@ -148,18 +178,3 @@ void Ram_session_component::transfer_quota(Ram_session_capability ram_session_ca
});
}
Ram_session_component::Ram_session_component(Rpc_entrypoint &ep,
Resources resources,
Label const &label,
Diag diag,
Range_allocator &phys_alloc,
Region_map &local_rm,
Phys_range phys_range)
:
Session_object(ep, resources, label, diag),
_ep(ep),
_constrained_md_ram_alloc(*this, *this, *this),
_sliced_heap(_constrained_md_ram_alloc, local_rm),
_ram_ds_factory(ep, phys_alloc, phys_range, local_rm, _sliced_heap)
{ }

View File

@ -97,6 +97,16 @@ class Genode::Expanding_parent_client : public Parent_client
Upgrade_result upgrade(Client::Id id, Upgrade_args const &args) override
{
/*
* Upgrades from our PD to our own PD session are futile. The only
* thing we can do when our PD is drained is requesting further
* resources from our parent.
*/
if (id == Env::pd()) {
resource_request(Resource_args(args.string()));
return UPGRADE_DONE;
}
/*
* If the upgrade fails, attempt to issue a resource request twice.
*

View File

@ -1,5 +1,5 @@
/*
* \brief RAM-session client that upgrades its session quota on demand
* \brief PD-session client that issues resource requests on demand
* \author Norman Feske
* \date 2013-09-25
*/
@ -11,20 +11,17 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__BASE__INTERNAL__EXPANDING_RAM_SESSION_CLIENT_H_
#define _INCLUDE__BASE__INTERNAL__EXPANDING_RAM_SESSION_CLIENT_H_
#ifndef _INCLUDE__BASE__INTERNAL__EXPANDING_PD_SESSION_CLIENT_H_
#define _INCLUDE__BASE__INTERNAL__EXPANDING_PD_SESSION_CLIENT_H_
/* Genode includes */
#include <util/retry.h>
#include <ram_session/connection.h>
#include <pd_session/client.h>
/* base-internal includes */
#include <base/internal/upgradeable_client.h>
namespace Genode { class Expanding_ram_session_client; }
namespace Genode { class Expanding_pd_session_client; }
struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_session_client>
struct Genode::Expanding_pd_session_client : Pd_session_client
{
void _request_ram_from_parent(size_t amount)
{
@ -38,10 +35,7 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_ses
parent.resource_request(String<128>("cap_quota=", amount).string());
}
Expanding_ram_session_client(Ram_session_capability cap, Parent::Client::Id id)
:
Upgradeable_client<Genode::Ram_session_client>(cap, id)
{ }
Expanding_pd_session_client(Pd_session_capability cap) : Pd_session_client(cap) { }
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached = UNCACHED) override
{
@ -54,13 +48,10 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_ses
return retry<Out_of_ram>(
[&] () {
return retry<Out_of_caps>(
[&] () { return Ram_session_client::alloc(size, cached); },
[&] () { return Pd_session_client::alloc(size, cached); },
[&] () {
try { upgrade_caps(UPGRADE_CAPS); }
catch (Out_of_caps) {
warning("cap quota exhausted, issuing resource request to parent");
_request_caps_from_parent(UPGRADE_CAPS);
}
warning("cap quota exhausted, issuing resource request to parent");
_request_caps_from_parent(UPGRADE_CAPS);
},
NUM_ATTEMPTS);
},
@ -81,7 +72,7 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_ses
NUM_ATTEMPTS);
}
void transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override
void transfer_quota(Pd_session_capability pd_session, Ram_quota amount) override
{
/*
* Should the transfer fail because we don't have enough quota, request
@ -89,10 +80,10 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_ses
*/
enum { NUM_ATTEMPTS = 2 };
retry<Out_of_ram>(
[&] () { Ram_session_client::transfer_quota(ram_session, amount); },
[&] () { Pd_session_client::transfer_quota(pd_session, amount); },
[&] () { _request_ram_from_parent(amount.value); },
NUM_ATTEMPTS);
}
};
#endif /* _INCLUDE__BASE__INTERNAL__EXPANDING_RAM_SESSION_CLIENT_H_ */
#endif /* _INCLUDE__BASE__INTERNAL__EXPANDING_PD_SESSION_CLIENT_H_ */

View File

@ -19,7 +19,7 @@
namespace Genode {
class Region_map;
class Ram_session;
class Ram_allocator;
class Env;
class Local_session_id_space;

View File

@ -30,15 +30,19 @@
#include <base/internal/parent_cap.h>
#include <base/internal/attached_stack_area.h>
#include <base/internal/expanding_cpu_session_client.h>
#include <base/internal/expanding_pd_session_client.h>
#include <base/internal/expanding_region_map_client.h>
#include <base/internal/expanding_ram_session_client.h>
#include <base/internal/expanding_parent_client.h>
namespace Genode { class Platform_env; }
namespace Genode {
class Platform_env_base : public Env_deprecated { };
class Platform_env;
}
class Genode::Platform_env : public Env_deprecated,
class Genode::Platform_env : public Platform_env_base,
public Expanding_parent_client::Emergency_ram_reserve
{
private:
@ -53,19 +57,16 @@ class Genode::Platform_env : public Env_deprecated,
return static_cap_cast<T>(parent.session_cap(id));
}
Expanding_ram_session_client ram;
Expanding_pd_session_client pd;
Expanding_cpu_session_client cpu;
Pd_session_client pd;
Expanding_region_map_client rm;
Resources(Parent &parent)
:
ram(request<Ram_session>(parent, Parent::Env::ram()),
Parent::Env::ram()),
pd (request<Pd_session> (parent, Parent::Env::pd())),
cpu(request<Cpu_session>(parent, Parent::Env::cpu()),
Parent::Env::cpu()),
pd (request<Pd_session> (parent, Parent::Env::pd())),
rm (pd, pd.address_space(), Parent::Env::pd())
rm(pd, pd.address_space(), Parent::Env::pd())
{ }
};
@ -97,10 +98,10 @@ class Genode::Platform_env : public Env_deprecated,
:
_parent_client(Genode::parent_cap(), *this),
_resources(_parent_client),
_heap(&_resources.ram, &_resources.rm, Heap::UNLIMITED),
_emergency_ram_ds(_resources.ram.alloc(_emergency_ram_size()))
_heap(&_resources.pd, &_resources.rm, Heap::UNLIMITED),
_emergency_ram_ds(_resources.pd.alloc(_emergency_ram_size()))
{
env_stack_area_ram_allocator = &_resources.ram;
env_stack_area_ram_allocator = &_resources.pd;
env_stack_area_region_map = &_stack_area;
}
@ -117,9 +118,9 @@ class Genode::Platform_env : public Env_deprecated,
void release()
{
log("used before freeing emergency=", _resources.ram.used_ram());
_resources.ram.free(_emergency_ram_ds);
log("used after freeing emergency=", _resources.ram.used_ram());
log("used before freeing emergency=", _resources.pd.used_ram());
_resources.pd.free(_emergency_ram_ds);
log("used after freeing emergency=", _resources.pd.used_ram());
}
@ -128,8 +129,8 @@ class Genode::Platform_env : public Env_deprecated,
******************************/
Parent *parent() override { return &_parent_client; }
Ram_session *ram_session() override { return &_resources.ram; }
Ram_session_capability ram_session_cap() override { return _resources.ram; }
Ram_session *ram_session() override { return &_resources.pd; }
Ram_session_capability ram_session_cap() override { return _resources.pd; }
Cpu_session *cpu_session() override { return &_resources.cpu; }
Cpu_session_capability cpu_session_cap() override { return _resources.cpu; }
Region_map *rm_session() override { return &_resources.rm; }

View File

@ -211,8 +211,8 @@ Session_capability Child::session(Parent::Client::Id id,
session.closed_callback = this;
try {
Ram_transfer::Remote_account ref_ram_account { _policy.ref_ram(), _policy.ref_ram_cap() };
Cap_transfer::Remote_account ref_cap_account { _policy.ref_pd(), _policy.ref_pd_cap() };
Ram_transfer::Remote_account ref_ram_account { _policy.ref_pd(), _policy.ref_pd_cap() };
Cap_transfer::Remote_account ref_cap_account { _policy.ref_pd(), _policy.ref_pd_cap() };
Ram_transfer::Remote_account ram_account { ram(), ram_session_cap() };
Cap_transfer::Remote_account cap_account { pd(), pd_session_cap() };
@ -350,10 +350,10 @@ Parent::Upgrade_result Child::upgrade(Client::Id id, Parent::Upgrade_args const
Arg_string::find_arg(args.string(), "cap_quota").ulong_value(0) };
try {
Ram_transfer::Remote_account ref_ram_account { _policy.ref_ram(), _policy.ref_ram_cap() };
Cap_transfer::Remote_account ref_cap_account { _policy.ref_pd(), _policy.ref_pd_cap() };
Ram_transfer::Remote_account ref_ram_account { _policy.ref_pd(), _policy.ref_pd_cap() };
Cap_transfer::Remote_account ref_cap_account { _policy.ref_pd(), _policy.ref_pd_cap() };
Ram_transfer::Remote_account ram_account { ram(), ram_session_cap() };
Ram_transfer::Remote_account ram_account { ram(), pd_session_cap() };
Cap_transfer::Remote_account cap_account { pd(), pd_session_cap() };
/* transfer quota from client to ourself */
@ -399,9 +399,9 @@ Parent::Upgrade_result Child::upgrade(Client::Id id, Parent::Upgrade_args const
void Child::_revert_quota_and_destroy(Session_state &session)
{
Ram_transfer::Remote_account ref_ram_account(_policy.ref_ram(), _policy.ref_ram_cap());
Ram_transfer::Remote_account ref_ram_account(_policy.ref_pd(), _policy.ref_pd_cap());
Ram_transfer::Account &service_ram_account = session.service();
Ram_transfer::Remote_account child_ram_account(ram(), ram_session_cap());
Ram_transfer::Remote_account child_ram_account(ram(), pd_session_cap());
Cap_transfer::Remote_account ref_cap_account(_policy.ref_pd(), _policy.ref_pd_cap());
Cap_transfer::Account &service_cap_account = session.service();
@ -675,8 +675,8 @@ namespace {
void Child::_try_construct_env_dependent_members()
{
/* check if the environment sessions are complete */
if (!_ram.cap().valid() || !_pd .cap().valid() ||
!_cpu.cap().valid() || !_log.cap().valid() || !_binary.cap().valid())
if (!_pd.cap().valid() || !_cpu.cap().valid() || !_log.cap().valid()
|| !_binary.cap().valid())
return;
/*
@ -696,15 +696,12 @@ void Child::_try_construct_env_dependent_members()
if (session.phase == Session_state::AVAILABLE)
session.phase = Session_state::CAP_HANDED_OUT; });
/* call 'Child_policy::init' methods for the environment sessions */
_policy.init(_ram.session(), _ram.cap());
_policy.init(_cpu.session(), _cpu.cap());
_policy.init(_pd.session(), _pd.cap());
try {
_initial_thread.construct(_cpu.session(), _pd.cap(), "initial");
_process.construct(_binary.session().dataspace(), _linker_dataspace(),
_pd.cap(), _pd.session(), _ram.session(),
_pd.cap(), _pd.session(), _pd.session(),
*_initial_thread, _local_rm,
Child_address_space(_pd.session(), _policy).region_map(),
cap());
@ -728,12 +725,15 @@ void Child::_discard_env_session(Id_space<Parent::Client>::Id id)
}
void Child::initiate_env_ram_session() { _ram.initiate(); }
void Child::initiate_env_ram_session()
{
_pd.initiate();
_policy.init(_pd.session(), _pd.cap());
}
void Child::initiate_env_sessions()
{
_pd .initiate();
_cpu .initiate();
_log .initiate();
_binary.initiate();
@ -793,7 +793,6 @@ Child::~Child()
/*
* Remove statically created env sessions from the child's ID space.
*/
_discard_env_session(Env::ram());
_discard_env_session(Env::cpu());
_discard_env_session(Env::pd());
_discard_env_session(Env::log());

View File

@ -69,7 +69,7 @@ void Genode::Platform_env::reinit(Native_capability::Raw raw)
* no problem because they are used by the 'Heap' destructor only, which is
* never called for heap instance of 'Platform_env'.
*/
_heap.reassign_resources(&_resources.ram, &_resources.rm);
_heap.reassign_resources(&_resources.pd, &_resources.rm);
}

View File

@ -30,9 +30,8 @@ Id_space<Parent::Client> &Genode::env_session_id_space()
/* pre-allocate env session IDs */
static Parent::Client dummy;
static Id_space<Parent::Client>::Element
ram { dummy, id_space, Parent::Env::ram() },
cpu { dummy, id_space, Parent::Env::cpu() },
pd { dummy, id_space, Parent::Env::pd() },
cpu { dummy, id_space, Parent::Env::cpu() },
log { dummy, id_space, Parent::Env::log() },
binary { dummy, id_space, Parent::Env::binary() },
linker { dummy, id_space, Parent::Env::linker() };

View File

@ -13,7 +13,7 @@
*/
/* Genode includes */
#include <ram_session/connection.h>
#include <pd_session/connection.h>
#include <base/log.h>
#include <base/component.h>
@ -24,16 +24,16 @@ void Component::construct(Genode::Env &env)
log("--- dataspace ownership test ---");
static Ram_connection ram_1 { env };
static Ram_connection ram_2 { env };
static Pd_connection pd_1 { env };
static Pd_connection pd_2 { env };
log("allocate dataspace from one RAM session");
ram_1.ref_account(env.ram_session_cap());
env.ram().transfer_quota(ram_1.cap(), Ram_quota{8*1024});
Ram_dataspace_capability ds = ram_1.alloc(sizeof(unsigned));
pd_1.ref_account(env.pd_session_cap());
env.pd().transfer_quota(pd_1.cap(), Ram_quota{8*1024});
Ram_dataspace_capability ds = pd_1.alloc(sizeof(unsigned));
log("attempt to free dataspace from foreign RAM session");
ram_2.free(ds);
pd_2.free(ds);
log("try to attach dataspace to see if it still exists");
env.rm().attach(ds);
@ -41,9 +41,9 @@ void Component::construct(Genode::Env &env)
log("attach operation succeeded");
log("free dataspace from legitimate RAM session");
Ram_quota const quota_before_free { ram_1.avail_ram() };
ram_1.free(ds);
Ram_quota const quota_after_free { ram_1.avail_ram() };
Ram_quota const quota_before_free { pd_1.avail_ram() };
pd_1.free(ds);
Ram_quota const quota_after_free { pd_1.avail_ram() };
if (quota_after_free.value > quota_before_free.value)
log("test succeeded");

View File

@ -101,19 +101,11 @@ class Test_child_policy : public Child_policy
Pd_session &ref_pd() override { return _env.pd(); }
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
Ram_session &ref_ram() override { return _env.ram(); }
Ram_session_capability ref_ram_cap() const override { return _env.ram_session_cap(); }
void init(Ram_session &session, Ram_session_capability cap) override
{
enum { CHILD_QUOTA = 1*1024*1024 };
session.ref_account(_env.ram_session_cap());
_env.ram().transfer_quota(cap, Ram_quota{CHILD_QUOTA});
}
void init(Pd_session &session, Pd_session_capability cap) override
{
session.ref_account(_env.pd_session_cap());
_env.pd().transfer_quota(cap, Ram_quota{1*1024*1024});
_env.pd().transfer_quota(cap, Cap_quota{20});
Region_map_client address_space(session.address_space());

View File

@ -56,9 +56,6 @@ class Launchpad_child : public Genode::Child_policy,
Genode::Allocator &_alloc;
Genode::Ram_session_capability _ref_ram_cap;
Genode::Ram_session_client _ref_ram { _ref_ram_cap };
Genode::Cap_quota const _cap_quota;
Genode::Ram_quota const _ram_quota;
@ -106,7 +103,6 @@ class Launchpad_child : public Genode::Child_policy,
:
_name(label), _elf_name(elf_name),
_env(env), _alloc(alloc),
_ref_ram_cap(env.ram_session_cap()),
_cap_quota(Genode::Child::effective_quota(cap_quota)),
_ram_quota(Genode::Child::effective_quota(ram_quota)),
_parent_services(parent_services),
@ -139,21 +135,12 @@ class Launchpad_child : public Genode::Child_policy,
Genode::Pd_session &ref_pd() override { return _env.pd(); }
Genode::Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
Genode::Ram_session &ref_ram() override { return _ref_ram; }
Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
void init(Genode::Pd_session &session,
Genode::Pd_session_capability cap) override
{
session.ref_account(_env.pd_session_cap());
_env.pd().transfer_quota(cap, _cap_quota);
}
void init(Genode::Ram_session &session,
Genode::Ram_session_capability cap) override
{
session.ref_account(_ref_ram_cap);
_ref_ram.transfer_quota(cap, _ram_quota);
_env.pd().transfer_quota(cap, _ram_quota);
}
Genode::Id_space<Genode::Parent::Server> &server_id_space() override {

View File

@ -58,8 +58,7 @@ class Report_rom_slave : public Genode::Noncopyable
const char *config)
:
Genode::Slave::Policy(_name(), _name(), *this, ep, rm,
ref_pd, ref_pd_cap, _caps(),
ref_ram, ref_ram_cap, _quota())
ref_pd, ref_pd_cap, _caps(), _quota())
{
if (config)
configure(config);

View File

@ -197,10 +197,9 @@ class Launcher::Fading_dialog : private Input_event_handler
_nitpicker_connection(env, "menu"),
_nitpicker_session(env, _nitpicker_connection, env.ep(), _fader_slave_ep, *this),
_nit_fader_slave(_fader_slave_ep, env.rm(), env.pd(), env.pd_session_cap(),
env.ram(), env.ram_session_cap(), _nitpicker_service),
_nitpicker_service),
_nit_fader_connection(env.rm(), _nit_fader_slave.policy(), Slave::Args("label=menu")),
_menu_view_slave(env.rm(), env.pd(), env.pd_session_cap(),
env.ram(), env.ram_session_cap(),
_nit_fader_connection,
_dialog_rom, _hover_report, initial_position)
{

View File

@ -83,16 +83,13 @@ class Launcher::Menu_view_slave
Genode::Region_map &rm,
Genode::Pd_session &ref_pd,
Genode::Pd_session_capability ref_pd_cap,
Genode::Ram_session &ref_ram,
Genode::Ram_session_capability ref_ram_cap,
Capability<Nitpicker::Session> nitpicker_session,
Capability<Rom_session> dialog_rom_session,
Capability<Report::Session> hover_report_session,
Position position)
:
Genode::Slave::Policy(_name(), _name(), *this, ep, rm,
ref_pd, ref_pd_cap, _caps(),
ref_ram, ref_ram_cap, _quota()),
ref_pd, ref_pd_cap, _caps(), _quota()),
_nitpicker(rm, nitpicker_session),
_dialog_rom(dialog_rom_session),
_hover_report(hover_report_session),
@ -134,15 +131,13 @@ class Launcher::Menu_view_slave
Menu_view_slave(Genode::Region_map &rm,
Genode::Pd_session &ref_pd,
Genode::Pd_session_capability ref_pd_cap,
Genode::Ram_session &ref_ram,
Genode::Ram_session_capability ref_ram_cap,
Capability<Nitpicker::Session> nitpicker_session,
Capability<Rom_session> dialog_rom_session,
Capability<Report::Session> hover_report_session,
Position initial_position)
:
_ep(&ref_pd, _ep_stack_size, "nit_fader"),
_policy(_ep, rm, ref_pd, ref_pd_cap, ref_ram, ref_ram_cap,
_policy(_ep, rm, ref_pd, ref_pd_cap,
nitpicker_session, dialog_rom_session,
hover_report_session, initial_position),
_child(rm, _ep, _policy)

View File

@ -51,17 +51,14 @@ class Launcher::Nit_fader_slave
public:
Policy(Rpc_entrypoint &ep,
Region_map &rm,
Pd_session &ref_pd,
Pd_session_capability ref_pd_cap,
Ram_session &ref_ram,
Ram_session_capability ref_ram_cap,
Genode::Service &nitpicker_service)
Policy(Rpc_entrypoint &ep,
Region_map &rm,
Pd_session &ref_pd,
Pd_session_capability ref_pd_cap,
Genode::Service &nitpicker_service)
:
Genode::Slave::Policy(_name(), _name(), *this, ep, rm,
ref_pd, ref_pd_cap, _caps(),
ref_ram, ref_ram_cap, _quota()),
ref_pd, ref_pd_cap, _caps(), _quota()),
_nitpicker_service(nitpicker_service)
{
visible(false);
@ -101,11 +98,9 @@ class Launcher::Nit_fader_slave
Genode::Region_map &rm,
Pd_session &ref_pd,
Pd_session_capability ref_pd_cap,
Ram_session &ref_ram,
Ram_session_capability ref_ram_cap,
Genode::Service &nitpicker_service)
:
_policy(ep, rm, ref_pd, ref_pd_cap, ref_ram, ref_ram_cap, nitpicker_service),
_policy(ep, rm, ref_pd, ref_pd_cap, nitpicker_service),
_child(rm, ep, _policy)
{
visible(false);

View File

@ -16,7 +16,6 @@
/* Genode includes */
#include <util/string.h>
#include <ram_session/client.h>
#include <base/attached_dataspace.h>
#include <os/reporter.h>
#include <nitpicker_session/connection.h>
@ -31,8 +30,6 @@
namespace Wm { class Main;
using Genode::size_t;
using Genode::Allocator;
using Genode::Ram_session_client;
using Genode::Ram_session_capability;
using Genode::Arg_string;
using Genode::Object_pool;
using Genode::Attached_dataspace;

View File

@ -44,7 +44,6 @@ class Avplay_slave : public QObject
private Genode::Static_parent_services<Genode::Cpu_session,
Genode::Log_session,
Genode::Pd_session,
Genode::Ram_session,
Genode::Rom_session,
Timer::Session,
Audio_out::Session>,
@ -113,15 +112,13 @@ class Avplay_slave : public QObject
Genode::Region_map &rm,
Genode::Pd_session &ref_pd,
Genode::Pd_session_capability ref_pd_cap,
Genode::Ram_session &ref_ram,
Genode::Ram_session_capability ref_ram_cap,
Input_service &input_service,
Framebuffer_service_factory &framebuffer_service_factory,
char const *mediafile)
:
Genode::Slave::Policy(_name(), _name(), *this, entrypoint,
rm, ref_pd, ref_pd_cap, _caps(),
ref_ram, ref_ram_cap, _ram_quota()),
_ram_quota()),
_input_service(input_service),
_framebuffer_service_factory(framebuffer_service_factory),
_mediafile(mediafile),
@ -163,15 +160,13 @@ class Avplay_slave : public QObject
Avplay_slave(Genode::Region_map &rm,
Genode::Pd_session &ref_pd,
Genode::Pd_session_capability ref_pd_cap,
Genode::Ram_session &ref_ram,
Genode::Ram_session_capability ref_ram_cap,
Input_service &input_service,
Framebuffer_service_factory &framebuffer_service_factory,
char const *mediafile)
:
_ep(&ref_pd, _ep_stack_size, "avplay_ep"),
_policy(_ep, rm, ref_pd, ref_pd_cap, ref_ram, ref_ram_cap,
input_service, framebuffer_service_factory, mediafile),
_policy(_ep, rm, ref_pd, ref_pd_cap, input_service,
framebuffer_service_factory, mediafile),
_child(rm, _ep, _policy)
{ }

View File

@ -33,7 +33,6 @@ class Filter_framebuffer_slave
private Genode::Static_parent_services<Genode::Cpu_session,
Genode::Log_session,
Genode::Pd_session,
Genode::Ram_session,
Genode::Rom_session,
Timer::Session>,
public Genode::Slave::Policy
@ -48,8 +47,6 @@ class Filter_framebuffer_slave
Genode::Region_map &rm,
Genode::Pd_session &ref_pd,
Genode::Pd_session_capability ref_pd_cap,
Genode::Ram_session &ref_ram,
Genode::Ram_session_capability ref_ram_cap,
Name const &name,
size_t caps,
size_t ram_quota,
@ -58,7 +55,6 @@ class Filter_framebuffer_slave
Genode::Slave::Policy(name, name, *this, entrypoint, rm,
ref_pd, ref_pd_cap,
Genode::Cap_quota{caps},
ref_ram, ref_ram_cap,
Genode::Ram_quota{ram_quota}),
_framebuffer_service_factory(framebuffer_service_factory)
{ }
@ -86,16 +82,14 @@ class Filter_framebuffer_slave
Filter_framebuffer_slave(Genode::Region_map &rm,
Genode::Pd_session &ref_pd,
Genode::Pd_session_capability ref_pd_cap,
Genode::Ram_session &ref_ram,
Genode::Ram_session_capability ref_ram_cap,
Genode::Slave::Policy::Name const &name,
size_t caps,
size_t ram_quota,
Framebuffer_service_factory &framebuffer_service_factory)
:
_ep(&ref_pd, _ep_stack_size, "filter_framebuffer_ep"),
_policy(_ep, rm, ref_pd, ref_pd_cap, ref_ram, ref_ram_cap, name,
caps, ram_quota, framebuffer_service_factory),
_policy(_ep, rm, ref_pd, ref_pd_cap, name, caps, ram_quota,
framebuffer_service_factory),
_child(rm, _ep, _policy)
{ }

View File

@ -76,8 +76,6 @@ Main_window::Main_window(Genode::Env &env)
framebuffer_filter->slave = new Filter_framebuffer_slave(_env.rm(),
_env.pd(),
_env.pd_session_cap(),
_env.ram(),
_env.ram_session_cap(),
framebuffer_filter->name,
framebuffer_filter->caps,
framebuffer_filter->ram_quota,
@ -90,7 +88,6 @@ Main_window::Main_window(Genode::Env &env)
Avplay_slave *avplay_slave = new Avplay_slave(_env.rm(),
_env.pd(), _env.pd_session_cap(),
_env.ram(), _env.ram_session_cap(),
_input_service,
*framebuffer_service_factory,
_mediafile_name.buf);

View File

@ -287,19 +287,11 @@ class Cli_monitor::Child_base : public Genode::Child_policy
Genode::Pd_session_capability ref_pd_cap() const override { return _ref_pd_cap; }
Genode::Pd_session &ref_pd() override { return _ref_pd; }
Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
Genode::Ram_session &ref_ram() override { return _ref_ram; }
void init(Genode::Pd_session &session, Genode::Pd_session_capability cap) override
{
session.ref_account(_ref_pd_cap);
_ref_pd.transfer_quota(cap, _cap_quota);
}
void init(Genode::Ram_session &session, Genode::Ram_session_capability cap) override
{
session.ref_account(_ref_ram_cap);
_ref_ram.transfer_quota(cap, Genode::Ram_quota{_ram_quota});
_ref_pd.transfer_quota(cap, Genode::Ram_quota{_ram_quota});
}
Genode::Service &resolve_session_request(Genode::Service::Name const &name,

View File

@ -15,7 +15,7 @@
#define _INCLUDE__CLI_MONITOR__RAM_H_
/* Genode includes */
#include <ram_session/connection.h>
#include <pd_session/client.h>
namespace Cli_monitor { class Ram; }
@ -26,8 +26,8 @@ class Cli_monitor::Ram
typedef Genode::size_t size_t;
Genode::Ram_session &_ram;
Genode::Ram_session_capability _ram_cap;
Genode::Pd_session &_pd;
Genode::Pd_session_capability _pd_cap;
Genode::Lock mutable _lock;
Genode::Signal_context_capability _yield_sigh;
@ -37,11 +37,11 @@ class Cli_monitor::Ram
void _validate_preservation()
{
if (_ram.avail_ram().value < _preserve)
if (_pd.avail_ram().value < _preserve)
Genode::Signal_transmitter(_yield_sigh).submit();
/* verify to answer outstanding resource requests too */
if (_ram.avail_ram().value > _preserve)
if (_pd.avail_ram().value > _preserve)
Genode::Signal_transmitter(_resource_avail_sigh).submit();
}
@ -54,13 +54,13 @@ class Cli_monitor::Ram
: quota(quota), used(used), avail(avail), preserve(preserve) { }
};
Ram(Genode::Ram_session &ram,
Genode::Ram_session_capability ram_cap,
Ram(Genode::Pd_session &pd,
Genode::Pd_session_capability pd_cap,
size_t preserve,
Genode::Signal_context_capability yield_sigh,
Genode::Signal_context_capability resource_avail_sigh)
:
_ram(ram), _ram_cap(ram_cap),
_pd(pd), _pd_cap(pd_cap),
_yield_sigh(yield_sigh),
_resource_avail_sigh(resource_avail_sigh),
_preserve(preserve)
@ -86,8 +86,8 @@ class Cli_monitor::Ram
{
Genode::Lock::Guard guard(_lock);
return Status(_ram.ram_quota().value, _ram.used_ram().value,
_ram.avail_ram().value, _preserve);
return Status(_pd.ram_quota().value, _pd.used_ram().value,
_pd.avail_ram().value, _preserve);
}
void validate_preservation()
@ -111,7 +111,7 @@ class Cli_monitor::Ram
Lock::Guard guard(_lock);
try { Ram_session_client(from).transfer_quota(_ram_cap, Ram_quota{amount}); }
try { Pd_session_client(from).transfer_quota(_pd_cap, Ram_quota{amount}); }
catch (...) { throw Transfer_quota_failed(); }
Signal_transmitter(_resource_avail_sigh).submit();
@ -124,16 +124,16 @@ class Cli_monitor::Ram
{
Genode::Lock::Guard guard(_lock);
if (_ram.avail_ram().value < (_preserve + amount)) {
if (_pd.avail_ram().value < (_preserve + amount)) {
Genode::Signal_transmitter(_yield_sigh).submit();
throw Transfer_quota_failed();
}
try { _ram.transfer_quota(to, Genode::Ram_quota{amount}); }
try { _pd.transfer_quota(to, Genode::Ram_quota{amount}); }
catch (...) { throw Transfer_quota_failed(); }
}
size_t avail() const { return _ram.avail_ram().value; }
size_t avail() const { return _pd.avail_ram().value; }
};
#endif /* _INCLUDE__CLI_MONITOR__RAM_H_ */

View File

@ -14,19 +14,17 @@
#ifndef _INCLUDE__OS__RAM_SESSION_GUARD_H_
#define _INCLUDE__OS__RAM_SESSION_GUARD_H_
#include <dataspace/client.h>
#include <ram_session/ram_session.h>
#include <ram_session/capability.h>
#include <base/ram_allocator.h>
#include <pd_session/capability.h>
namespace Genode { struct Ram_session_guard; }
class Genode::Ram_session_guard : public Genode::Ram_session
class Genode::Ram_session_guard : public Genode::Ram_allocator
{
private:
Ram_session &_session;
Ram_session_capability _session_cap;
Ram_allocator &_ram_alloc;
size_t _quota;
size_t _used = 0;
@ -34,9 +32,8 @@ class Genode::Ram_session_guard : public Genode::Ram_session
public:
Ram_session_guard(Ram_session &session, Ram_session_capability cap,
size_t quota)
: _session(session), _session_cap(cap), _quota(quota) { }
Ram_session_guard(Ram_allocator &ram_alloc, size_t quota)
: _ram_alloc(ram_alloc), _quota(quota) { }
/**
* Extend allocation limit
@ -71,26 +68,10 @@ class Genode::Ram_session_guard : public Genode::Ram_session
return true;
}
/**
* Revert transfer quota
*/
int revert_transfer_quota(Ram_session &ram_session,
size_t amount)
{
if (amount > _used)
return -4;
try {
ram_session.transfer_quota(_session_cap, Ram_quota{amount});
_used -= amount;
return 0;
} catch (...) { return -1; }
}
/***************************
** Ram_session interface **
***************************/
/*****************************
** Ram_allocator interface **
*****************************/
Ram_dataspace_capability alloc(size_t size,
Cache_attribute cached = CACHED) override
@ -98,7 +79,7 @@ class Genode::Ram_session_guard : public Genode::Ram_session
if (_used + size <= _used || _used + size > _quota)
throw Out_of_ram();
Ram_dataspace_capability cap = _session.alloc(size, cached);
Ram_dataspace_capability cap = _ram_alloc.alloc(size, cached);
if (cap.valid())
_used += size;
@ -109,30 +90,14 @@ class Genode::Ram_session_guard : public Genode::Ram_session
void free(Ram_dataspace_capability ds) override
{
size_t size = Dataspace_client(ds).size();
_session.free(ds);
_ram_alloc.free(ds);
_used -= size;
}
size_t dataspace_size(Ram_dataspace_capability ds) const override
{
return _session.dataspace_size(ds);
return _ram_alloc.dataspace_size(ds);
}
void ref_account(Ram_session_capability ram_session) override {
_session.ref_account(ram_session); }
void transfer_quota(Ram_session_capability ram_session,
Ram_quota amount) override
{
if (_used + amount.value <= _used || _used + amount.value > _quota)
throw Out_of_ram();
_session.transfer_quota(ram_session, amount);
_used += amount.value;
}
Ram_quota ram_quota() const override { return Ram_quota{_quota}; }
Ram_quota used_ram() const override { return Ram_quota{_used}; }
};
#endif /* _INCLUDE__OS__RAM_SESSION_GUARD_H_ */

View File

@ -56,8 +56,6 @@ class Genode::Slave::Policy : public Child_policy
Binary_name const _binary_name;
Pd_session &_ref_pd;
Pd_session_capability _ref_pd_cap;
Ram_session &_ref_ram;
Ram_session_capability _ref_ram_cap;
Genode::Parent_service _binary_service;
Cap_quota const _cap_quota;
Ram_quota const _ram_quota;
@ -89,18 +87,15 @@ class Genode::Slave::Policy : public Child_policy
Pd_session &ref_pd,
Pd_session_capability ref_pd_cap,
Cap_quota cap_quota,
Ram_session &ref_ram,
Ram_session_capability ref_ram_cap,
Ram_quota ram_quota)
:
_label(label), _binary_name(binary_name),
_ref_pd(ref_pd), _ref_pd_cap(ref_pd_cap),
_ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap),
_binary_service(Rom_session::service_name()),
_cap_quota(cap_quota), _ram_quota(ram_quota),
_parent_services(parent_services), _ep(ep),
_config_policy(rm, "config", _ep, &_ref_ram),
_session_requester(ep, _ref_ram, rm)
_config_policy(rm, "config", _ep, &_ref_pd),
_session_requester(ep, _ref_pd, rm)
{
configure("<config/>");
}
@ -137,19 +132,11 @@ class Genode::Slave::Policy : public Child_policy
Pd_session &ref_pd() override { return _ref_pd; }
Pd_session_capability ref_pd_cap() const override { return _ref_pd_cap; }
Ram_session &ref_ram() override { return _ref_ram; }
Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
void init(Pd_session &session, Pd_session_capability cap) override
{
session.ref_account(_ref_pd_cap);
_ref_pd.transfer_quota(cap, _cap_quota);
}
void init(Ram_session &session, Ram_session_capability cap) override
{
session.ref_account(_ref_ram_cap);
_ref_ram.transfer_quota(cap, _ram_quota);
_ref_pd.transfer_quota(cap, _ram_quota);
}
Service &resolve_session_request(Service::Name const &service_name,
@ -262,15 +249,15 @@ class Genode::Slave::Connection_base
*/
void transfer(Ram_session_capability to, Ram_quota amount) override
{
if (to.valid()) _policy.ref_ram().transfer_quota(to, amount);
if (to.valid()) _policy.ref_pd().transfer_quota(to, amount);
}
/**
* Service ('Ram_transfer::Account') interface
*/
Ram_session_capability cap(Ram_quota) const override
Pd_session_capability cap(Ram_quota) const override
{
return _policy.ref_ram_cap();
return _policy.ref_pd_cap();
}
/**

View File

@ -53,4 +53,4 @@ build_boot_image "core ld.lib.so init timer report_rom test-resource_request"
append qemu_args "-nographic -m 128"
run_genode_until {child "test-resource_request" exited with exit value 0.*\n} 30
run_genode_until {child "test-resource_request" exited with exit value 0.*\n} 60

View File

@ -22,8 +22,7 @@ namespace Platform { class Device_pd_policy; }
class Platform::Device_pd_policy
:
private Genode::Static_parent_services<Genode::Ram_session,
Genode::Pd_session,
private Genode::Static_parent_services<Genode::Pd_session,
Genode::Cpu_session,
Genode::Log_session,
Genode::Rom_session>,
@ -36,14 +35,11 @@ class Platform::Device_pd_policy
Genode::Pd_session &pd_ref,
Genode::Pd_session_capability pd_ref_cap,
Genode::Cap_quota cap_quota,
Genode::Ram_session &ram_ref,
Genode::Ram_session_capability ram_ref_cap,
Genode::Ram_quota ram_quota,
Genode::Session_label const &label)
:
Genode::Slave::Policy(label, "device_pd", *this, slave_ep, local_rm,
pd_ref, pd_ref_cap, cap_quota,
ram_ref, ram_ref_cap, ram_quota)
pd_ref, pd_ref_cap, cap_quota, ram_quota)
{ }
};

View File

@ -18,7 +18,7 @@
#include <base/rpc_server.h>
#include <base/tslab.h>
#include <base/attached_rom_dataspace.h>
#include <ram_session/connection.h>
#include <ram_session/capability.h>
#include <root/component.h>
#include <util/mmio.h>
@ -302,9 +302,9 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
Genode::Session_label const &label)
try :
_reservation(ref_ram, RAM_QUOTA),
_policy(ep, local_rm,
ref_pd, ref_pd_cap, Genode::Cap_quota{CAP_QUOTA},
ref_ram, ref_ram_cap, Genode::Ram_quota{RAM_QUOTA},
_policy(ep, local_rm, ref_pd, ref_pd_cap,
Genode::Cap_quota{CAP_QUOTA},
Genode::Ram_quota{RAM_QUOTA},
label),
_child(local_rm, ep, _policy),
_connection(_policy, Genode::Slave::Args())
@ -597,8 +597,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
:
_env(env), _device_pd_ep(device_pd_ep),
_config(config),
_env_ram(env.ram(), env.ram_session_cap(),
Genode::Arg_string::find_arg(args, "ram_quota").long_value(0)),
_env_ram(env.ram(), Genode::ram_quota_from_args(args).value),
_env_ram_cap(env.ram_session_cap()),
_env_pd(env.pd()),
_env_pd_cap(env.pd_session_cap()),
@ -1149,7 +1148,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
Session_component *_create_session(const char *args)
{
try {
return new (md_alloc())
return new (md_alloc())
Session_component(_env, _config, _device_pd_ep, _buses, _heap, args);
}
catch (Genode::Session_policy::No_policy_defined) {

View File

@ -200,7 +200,7 @@ void Init::Child::apply_ram_upgrade()
_check_ram_constraints(_ram_limit_accessor.ram_limit());
ref_ram().transfer_quota(_child.ram_session_cap(), Ram_quota{transfer});
ref_pd().transfer_quota(_child.pd_session_cap(), Ram_quota{transfer});
/* wake up child that blocks on a resource request */
if (_requested_resources.constructed()) {
@ -239,7 +239,7 @@ void Init::Child::apply_ram_downgrade()
size_t const transfer = min(avail - preserved, decrease);
try {
_child.ram().transfer_quota(ref_ram_cap(), Ram_quota{transfer});
_child.pd().transfer_quota(ref_pd_cap(), Ram_quota{transfer});
_resources.assigned_ram_quota =
Ram_quota { _resources.assigned_ram_quota.value - transfer };
break;
@ -335,26 +335,22 @@ void Init::Child::init(Pd_session &session, Pd_session_capability cap)
{
session.ref_account(_env.pd_session_cap());
Cap_quota const quota { _resources.effective_cap_quota().value };
try { _env.pd().transfer_quota(cap, quota); }
catch (Out_of_caps) {
error(name(), ": unable to initialize cap quota of PD"); }
}
void Init::Child::init(Ram_session &session, Ram_session_capability cap)
{
session.ref_account(_env.ram_session_cap());
size_t const initial_session_costs =
session_alloc_batch_size()*_child.session_factory().session_costs();
size_t const transfer_ram = _resources.effective_ram_quota().value > initial_session_costs
Ram_quota const ram_quota { _resources.effective_ram_quota().value > initial_session_costs
? _resources.effective_ram_quota().value - initial_session_costs
: 0;
if (transfer_ram)
_env.ram().transfer_quota(cap, Ram_quota{transfer_ram});
: 0 };
Cap_quota const cap_quota { _resources.effective_cap_quota().value };
try { _env.pd().transfer_quota(cap, cap_quota); }
catch (Out_of_caps) {
error(name(), ": unable to initialize cap quota of PD"); }
try { _env.ram().transfer_quota(cap, ram_quota); }
catch (Out_of_ram) {
error(name(), ": unable to initialize RAM quota of PD"); }
}

View File

@ -244,7 +244,7 @@ class Init::Child : Child_policy, Routed_service::Wakeup
Child &_child;
Dynamic_rom_session _session { _child._env.ep().rpc_ep(),
_child.ref_ram(), _child._env.rm(),
_child.ref_pd(), _child._env.rm(),
*this };
Service::Single_session_factory _factory { _session };
@ -512,11 +512,7 @@ class Init::Child : Child_policy, Routed_service::Wakeup
Pd_session &ref_pd() override { return _env.pd(); }
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
Ram_session &ref_ram() override { return _env.ram(); }
Ram_session_capability ref_ram_cap() const override { return _env.ram_session_cap(); }
void init(Pd_session &, Pd_session_capability) override;
void init(Ram_session &, Ram_session_capability) override;
void init(Cpu_session &, Cpu_session_capability) override;
Id_space<Parent::Server> &server_id_space() override {

View File

@ -19,7 +19,6 @@
#include <base/child.h>
#include <util/arg_string.h>
#include <init/child_policy.h>
#include <ram_session/connection.h>
#include <cpu_session/connection.h>
#include <pd_session/connection.h>
#include <region_map/client.h>
@ -100,19 +99,11 @@ class Loader::Child : public Child_policy
Pd_session &ref_pd() override { return _env.pd(); }
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
Ram_session &ref_ram() override { return _env.ram(); }
Ram_session_capability ref_ram_cap() const override { return _env.ram_session_cap(); }
void init(Pd_session &pd, Pd_session_capability pd_cap) override
{
pd.ref_account(ref_pd_cap());
ref_pd().transfer_quota(pd_cap, _cap_quota);
}
void init(Ram_session &ram, Ram_session_capability ram_cap) override
{
ram.ref_account(ref_ram_cap());
ref_ram().transfer_quota(ram_cap, _ram_quota);
ref_pd().transfer_quota(pd_cap, _ram_quota);
}
Service &resolve_session_request(Service::Name const &name,

View File

@ -158,10 +158,10 @@ class Loader::Session_component : public Rpc_object<Session>
struct Local_nitpicker_factory : Local_service<Nitpicker::Session_component>::Factory
{
Entrypoint &_ep;
Env &_env;
Region_map &_rm;
Ram_session &_ram;
Entrypoint &_ep;
Env &_env;
Region_map &_rm;
Ram_allocator &_ram;
Area _max_size;
Nitpicker::View_capability _parent_view;
@ -170,7 +170,8 @@ class Loader::Session_component : public Rpc_object<Session>
Constructible<Nitpicker::Session_component> session;
Local_nitpicker_factory(Entrypoint &ep, Env &env, Region_map &rm, Ram_session &ram)
Local_nitpicker_factory(Entrypoint &ep, Env &env,
Region_map &rm, Ram_allocator &ram)
: _ep(ep), _env(env), _rm(rm), _ram(ram) { }
void constrain_geometry(Area size) { _max_size = size; }

View File

@ -152,7 +152,7 @@ class Nitpicker::Session_component : public Rpc_object<Session>
Session_component(Entrypoint &ep,
Env &env,
Region_map &rm,
Ram_session &ram,
Ram_allocator &ram,
Area max_size,
Nitpicker::View_capability parent_view,
Signal_context_capability view_ready_sigh,

View File

@ -15,37 +15,38 @@
#define _RAM_SESSION_CLIENT_GUARD_H_
#include <base/lock.h>
#include <base/printf.h>
#include <base/log.h>
#include <base/ram_allocator.h>
#include <pd_session/client.h>
#include <dataspace/client.h>
#include <ram_session/client.h>
namespace Genode {
class Ram_session_client_guard : public Ram_session_client
class Ram_session_client_guard : public Ram_allocator
{
private:
size_t const _amount; /* total amount */
size_t _consumed; /* already consumed bytes */
Lock mutable _consumed_lock;
Pd_session_client _pd;
size_t const _amount; /* total amount */
size_t _consumed; /* already consumed bytes */
Lock mutable _consumed_lock;
public:
Ram_session_client_guard(Ram_session_capability session, Ram_quota amount)
: Ram_session_client(session), _amount(amount.value), _consumed(0) { }
Ram_session_client_guard(Pd_session_capability session, Ram_quota amount)
: _pd(session), _amount(amount.value), _consumed(0) { }
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override
{
Lock::Guard _consumed_lock_guard(_consumed_lock);
if ((_amount - _consumed) < size) {
PWRN("Quota exceeded! amount=%lu, size=%lu, consumed=%lu",
_amount, size, _consumed);
warning("quota exceeded! amount=", _amount, ", "
"size=", size, ", consumed=", _consumed);
return Ram_dataspace_capability();
}
Ram_dataspace_capability cap =
Ram_session_client::alloc(size, cached);
Ram_dataspace_capability cap = _pd.alloc(size, cached);
_consumed += size;
@ -58,38 +59,14 @@ namespace Genode {
_consumed -= Dataspace_client(ds).size();
Ram_session_client::free(ds);
_pd.free(ds);
}
size_t dataspace_size(Ram_dataspace_capability ds) const override
{
return Ram_session_client::dataspace_size(ds);
}
void transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override
{
Lock::Guard _consumed_lock_guard(_consumed_lock);
if ((_amount - _consumed) < amount.value) {
warning("Quota exceeded! amount=", _amount, ", "
"size=", amount.value, ", "
"consumed=", _consumed);
throw Out_of_ram();
}
Ram_session_client::transfer_quota(ram_session, amount);
_consumed += amount.value;
}
Ram_quota ram_quota() const override
{
return { _amount };
}
Ram_quota used_ram() const override
{
Lock::Guard _consumed_lock_guard(_consumed_lock);
return { _consumed };
return _pd.dataspace_size(ds);
}
};
}

View File

@ -31,7 +31,7 @@ namespace Genode {
Name const _name;
Ram_session &_ram;
Ram_allocator &_ram;
Attached_ram_dataspace _fg;
Attached_ram_dataspace _bg;
@ -48,9 +48,9 @@ namespace Genode {
enum Origin { PARENT_PROVIDED, SESSION_LOCAL };
Rom_module(Env &env, Xml_node config, Name const &name,
Ram_session &ram_session, Origin origin)
Ram_allocator &ram_allocator, Origin origin)
:
_name(name), _ram(ram_session),
_name(name), _ram(ram_allocator),
_fg(_ram, env.rm(), 0), _bg(_ram, env.rm(), 0),
_bg_has_pending_data(false),
_lock(Lock::LOCKED)
@ -158,7 +158,7 @@ namespace Genode {
Env &_env;
Xml_node const _config;
Lock _lock;
Ram_session &_ram_session;
Ram_allocator &_ram_allocator;
Allocator &_md_alloc;
List<Rom_module> _list;
@ -172,14 +172,15 @@ namespace Genode {
/**
* Constructor
*
* \param ram_session RAM session used as backing store for
* module data
* \param md_alloc backing store for ROM module meta data
* \param ram_allocator RAM allocator used as backing store for
* module data
* \param md_alloc backing store for ROM module meta data
*/
Rom_module_registry(Env &env, Xml_node config, Ram_session &ram_session,
Rom_module_registry(Env &env, Xml_node config,
Ram_allocator &ram_allocator,
Allocator &md_alloc)
:
_env(env), _config(config), _ram_session(ram_session),
_env(env), _config(config), _ram_allocator(ram_allocator),
_md_alloc(md_alloc)
{ }
@ -226,7 +227,7 @@ namespace Genode {
Lock::Guard guard(_lock);
Rom_module *module = new (&_md_alloc)
Rom_module(_env, _config, name, _ram_session,
Rom_module(_env, _config, name, _ram_allocator,
Rom_module::SESSION_LOCAL);
Rom_module_lock_guard module_guard(*module);
@ -247,7 +248,7 @@ namespace Genode {
Lock::Guard guard(_lock);
Rom_module *module = new (&_md_alloc)
Rom_module(_env, _config, name, _ram_session,
Rom_module(_env, _config, name, _ram_allocator,
Rom_module::PARENT_PROVIDED);
Rom_module_lock_guard module_guard(*module);

View File

@ -56,7 +56,7 @@ class Net::Stream_allocator
Stream_allocator(Genode::Ram_session &ram,
Genode::Region_map &rm,
Genode::size_t amount)
: _ram(ram, Genode::Ram_session_capability(), amount),
: _ram(ram, amount),
_heap(ram, rm),
_range_alloc(&_heap) {}

View File

@ -344,7 +344,7 @@ class Vfs_server::Session_component : public File_system::Session_rpc_object,
bool writable)
:
Session_rpc_object(env.ram().alloc(tx_buf_size), env.rm(), env.ep().rpc_ep()),
_ram(env.ram(), env.ram_session_cap(), ram_quota),
_ram(env.ram(), ram_quota),
_alloc(_ram, env.rm()),
_process_packet_handler(env.ep(), *this, &Session_component::_process_packets),
_vfs(vfs),

View File

@ -75,20 +75,12 @@ class Bomb_child : public Child_policy
{
pd.ref_account(_env.pd_session_cap());
_env.pd().transfer_quota(pd_cap, _cap_quota);
_env.pd().transfer_quota(pd_cap, _ram_quota);
}
void init(Ram_session &ram, Ram_session_capability ram_cap) override
{
ram.ref_account(_env.ram_session_cap());
_env.ram().transfer_quota(ram_cap, _ram_quota);
}
Pd_session &ref_pd() override { return _env.pd(); }
Pd_session &ref_pd() override { return _env.pd(); }
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
Ram_session &ref_ram() override { return _env.ram(); }
Ram_session_capability ref_ram_cap() const override { return _env.ram_session_cap(); }
Service &resolve_session_request(Service::Name const &service_name,
Session_state::Args const &args) override
{

View File

@ -36,8 +36,8 @@ struct Test::Policy
Policy(Env &env, Name const &name)
:
Slave::Policy(name, name, *this, env.ep().rpc_ep(), env.rm(),
env.pd(), env.pd_session_cap(), Cap_quota{100},
env.ram(), env.ram_session_cap(), Ram_quota{1024*1024})
env.pd(), env.pd_session_cap(),
Cap_quota{100}, Ram_quota{1024*1024})
{ }
};

View File

@ -70,12 +70,11 @@ class Test_child : public Genode::Child_policy
private:
Env &_env;
Cap_quota const _cap_quota { 30 };
Cap_quota const _cap_quota { 50 };
Ram_quota const _ram_quota { 1024*1024 };
Binary_name const _binary_name;
Signal_context_capability _sigh;
Parent_service _cpu_service { _env, Cpu_session::service_name() };
Parent_service _ram_service { _env, Ram_session::service_name() };
Parent_service _pd_service { _env, Pd_session::service_name() };
Parent_service _log_service { _env, Log_session::service_name() };
Parent_service _rom_service { _env, Rom_session::service_name() };
@ -105,15 +104,6 @@ class Test_child : public Genode::Child_policy
Pd_session &ref_pd() override { return _env.pd(); }
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
Ram_session &ref_ram() override { return _env.ram(); }
Ram_session_capability ref_ram_cap() const override { return _env.ram_session_cap(); }
void init(Ram_session &ram, Ram_session_capability ram_cap) override
{
ram.ref_account(ref_ram_cap());
ref_ram().transfer_quota(ram_cap, _ram_quota);
}
void init(Cpu_session &cpu, Cpu_session_capability) override
{
/* register default exception handler */
@ -124,6 +114,7 @@ class Test_child : public Genode::Child_policy
{
pd.ref_account(ref_pd_cap());
ref_pd().transfer_quota(pd_cap, _cap_quota);
ref_pd().transfer_quota(pd_cap, _ram_quota);
/* register handler for unresolvable page faults */
Region_map_client address_space(pd.address_space());
@ -134,7 +125,6 @@ class Test_child : public Genode::Child_policy
Session_state::Args const &args) override
{
if (service == Cpu_session::service_name()) return _cpu_service;
if (service == Ram_session::service_name()) return _ram_service;
if (service == Pd_session::service_name()) return _pd_service;
if (service == Log_session::service_name()) return _log_service;
if (service == Rom_session::service_name()) return _rom_service;
@ -202,7 +192,7 @@ struct Faulting_loader_grand_child_test
" <default-route>\n"
" <any-service> <parent/> <any-child/> </any-service>\n"
" </default-route>\n"
" <start name=\"test-segfault\">\n"
" <start name=\"test-segfault\" caps=\"50\">\n"
" <resource name=\"RAM\" quantum=\"10M\"/>\n"
" </start>\n"
"</config>";

View File

@ -17,7 +17,7 @@
#include <base/component.h>
#include <base/log.h>
#include <base/attached_rom_dataspace.h>
#include <ram_session/connection.h>
#include <pd_session/connection.h>
#include <os/reporter.h>
namespace Test {
@ -26,9 +26,9 @@ namespace Test {
}
static void print_quota_stats(Genode::Ram_session &ram)
static void print_quota_stats(Genode::Pd_session &pd)
{
Genode::log("quota: avail=", ram.avail_ram().value, " used=", ram.used_ram().value);
Genode::log("quota: avail=", pd.avail_ram().value, " used=", pd.used_ram().value);
}
@ -152,25 +152,17 @@ void Component::construct(Genode::Env &env)
print_quota_stats(env.ram());
/*
* Out of memory while upgrading session quotas.
*
* This test provokes the signal session to consume more resources than
* donated via the initial session creation. Once drained, we need to
* successively upgrade the session. At one point, we will run out of our
* initial quota. Now, before we can issue another upgrade, we first need
* to request additional resources.
*
* Note that the construction of the signal receiver will consume a part
* of the quota we preserved as 'KEEP_QUOTA'.
* Drain PD session by allocating a lot of signal-context capabilities.
* This step will ultimately trigger resource requests to the parent.
*/
log("\n-- draining signal session --");
log("\n-- draining PD session --");
{
struct Dummy_signal_handler : Signal_handler<Dummy_signal_handler>
{
Dummy_signal_handler(Entrypoint &ep)
: Signal_handler<Dummy_signal_handler>(ep, *this, nullptr) { }
};
enum { NUM_SIGH = 2000U };
enum { NUM_SIGH = 1000U };
static Constructible<Dummy_signal_handler> dummy_handlers[NUM_SIGH];
for (unsigned i = 0; i < NUM_SIGH; i++)
@ -190,8 +182,8 @@ void Component::construct(Genode::Env &env)
* resource request to the parent.
*/
log("\n-- out-of-memory during session request --");
static Ram_connection ram(env);
ram.ref_account(env.ram_session_cap());
static Pd_connection pd(env);
pd.ref_account(env.pd_session_cap());
print_quota_stats(env.ram());
size_t const used_quota_after_session_request = env.ram().used_ram().value;
@ -200,7 +192,7 @@ void Component::construct(Genode::Env &env)
* requests, too.
*/
log("\n-- out-of-memory during transfer-quota --");
env.ram().transfer_quota(ram.cap(), Ram_quota{512*1024});
env.ram().transfer_quota(pd.cap(), Ram_quota{512*1024});
print_quota_stats(env.ram());
size_t const used_quota_after_transfer = env.ram().used_ram().value;

View File

@ -296,8 +296,8 @@ class Test::Parent
:
Slave::Policy(Label("child"), "test-resource_yield",
*this, env.ep().rpc_ep(), env.rm(),
env.pd(), env.pd_session_cap(), Cap_quota{SLAVE_CAPS},
env.ram(), env.ram_session_cap(), Ram_quota{SLAVE_RAM}),
env.pd(), env.pd_session_cap(),
Cap_quota{SLAVE_CAPS}, Ram_quota{SLAVE_RAM}),
_parent(parent)
{
configure("<config child=\"yes\" />");

View File

@ -53,9 +53,6 @@ class Gdb_monitor::App_child : public Child_policy
Pd_session_capability _ref_pd_cap { _env.pd_session_cap() };
Pd_session &_ref_pd { _env.pd() };
Ram_session_capability _ref_ram_cap { _env.ram_session_cap() };
Ram_session &_ref_ram { _env.ram() };
const char *_unique_name;
Dataspace_capability _elf_ds;
@ -164,26 +161,21 @@ class Gdb_monitor::App_child : public Child_policy
Pd_session_capability ref_pd_cap() const override { return _ref_pd_cap; }
Ram_session &ref_ram() override { return _ref_ram; }
Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
void init(Ram_session &session,
Ram_session_capability cap) override
{
session.ref_account(_ref_ram_cap);
_ref_ram.transfer_quota(cap, _ram_quota);
}
void init(Pd_session &session,
Pd_session_capability cap) override
{
session.ref_account(_ref_pd_cap);
_ref_pd.transfer_quota(cap, _cap_quota);
_entrypoint.apply(cap, [&] (Pd_session_component *pd) {
if (pd) {
_ref_pd.transfer_quota(pd->core_pd_cap(), _cap_quota);
_ref_pd.transfer_quota(pd->core_pd_cap(), _ram_quota);
}
});
}
Service &resolve_session_request(Service::Name const &service_name,
Session_state::Args const &args) override
Session_state::Args const &args) override
{
Service *service = nullptr;

View File

@ -509,12 +509,11 @@ extern "C" int fork()
_memory_model = &memory_model;
try {
child->start();
} catch (...) {
Genode::error("Could not start child process");
return -1;
}
try { child->start(); }
catch (Out_of_caps) { error("out of caps during child startup"); return -1; }
catch (Out_of_ram) { error("out of RAM during child startup"); return -1; }
catch (Service_denied) { error("service denied during child startup"); return -1; }
catch (...) { error("could not start child process"); return -1; }
return GENODE_MAIN_LWPID;
}

View File

@ -117,13 +117,27 @@ class Gdb_monitor::Pd_session_component : public Rpc_object<Pd_session>
return _linker_area.Rpc_object<Region_map>::cap(); }
void ref_account(Capability<Pd_session> pd) override {
warning("Pd_session::ref_account not implemented"); }
_pd.ref_account(pd); }
void transfer_quota(Capability<Pd_session> pd, Cap_quota amount) override {
warning("Pd_session::transfer_quota not implemented"); }
Cap_quota cap_quota() const { return _pd.cap_quota(); }
Cap_quota used_caps() const { return _pd.used_caps(); }
Cap_quota cap_quota() const override { return _pd.cap_quota(); }
Cap_quota used_caps() const override { return _pd.used_caps(); }
Ram_dataspace_capability alloc(size_t amount, Cache_attribute cached) override {
return _pd.alloc(amount, cached); }
void free(Ram_dataspace_capability ds) override { _pd.free(ds); }
size_t dataspace_size(Ram_dataspace_capability ds) const override {
return _pd.dataspace_size(ds); }
void transfer_quota(Pd_session_capability pd, Ram_quota amount) override {
_pd.transfer_quota(pd, amount); }
Ram_quota ram_quota() const override { return _pd.ram_quota(); }
Ram_quota used_ram() const override { return _pd.used_ram(); }
Capability<Native_pd> native_pd() override {
return _pd.native_pd(); }

View File

@ -1,75 +0,0 @@
/*
* \brief Implementation of the RAM session interface
* \author Christian Prochaska
* \date 2011-05-06
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/env.h>
#include <base/printf.h>
#include "ram_session_component.h"
using namespace Genode;
using namespace Gdb_monitor;
Ram_session_component::Ram_session_component(Env &env, const char *args,
Affinity const &affinity)
: _env(env),
_parent_ram_session(_env.session<Ram_session>(_id_space_element.id(), args, affinity))
{ }
Ram_session_component::~Ram_session_component()
{ }
Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size, Cache_attribute cached)
{
return _parent_ram_session.alloc(ds_size, cached);
}
void Ram_session_component::free(Ram_dataspace_capability ds_cap)
{
_parent_ram_session.free(ds_cap);
}
size_t Ram_session_component::dataspace_size(Ram_dataspace_capability ds_cap) const
{
return _parent_ram_session.dataspace_size(ds_cap);
}
void Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
{
_parent_ram_session.ref_account(ram_session_cap);
}
void Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap,
Ram_quota amount)
{
_parent_ram_session.transfer_quota(ram_session_cap, amount);
}
Ram_quota Ram_session_component::ram_quota() const
{
return _parent_ram_session.ram_quota();
}
Ram_quota Ram_session_component::used_ram() const
{
return _parent_ram_session.used_ram();
}

View File

@ -35,7 +35,6 @@ CC_OPT_linux-low += -Wno-unused-function
SRC_CC = genode-low.cc \
cpu_session_component.cc \
cpu_thread_component.cc \
ram_session_component.cc \
region_map_component.cc \
signal_handler_thread.cc \
main.cc

View File

@ -101,7 +101,7 @@ class Noux::Args
struct Noux::Args_dataspace : private Attached_ram_dataspace, Args
{
Args_dataspace(Ram_session &ram, Region_map &rm,
Args_dataspace(Ram_allocator &ram, Region_map &rm,
size_t size, Args const &from = Args())
:
Attached_ram_dataspace(ram, rm, size),

View File

@ -24,7 +24,6 @@
#include <noux_session/capability.h>
#include <args.h>
#include <environment.h>
#include <ram_session_component.h>
#include <cpu_session_component.h>
#include <pd_session_component.h>
#include <child_policy.h>
@ -90,7 +89,7 @@ struct Noux::Child_config : Attached_ram_dataspace
{
enum { CONFIG_DS_SIZE = 4096 };
Child_config(Ram_session &ram, Region_map &local_rm, Verbose const &verbose)
Child_config(Ram_allocator &ram, Region_map &local_rm, Verbose const &verbose)
:
Attached_ram_dataspace(ram, local_rm, CONFIG_DS_SIZE)
{
@ -146,9 +145,6 @@ class Noux::Child : public Rpc_object<Session>,
Pd_session &_ref_pd;
Pd_session_capability const _ref_pd_cap;
Ram_session &_ref_ram;
Ram_session_capability const _ref_ram_cap;
/**
* Registry of dataspaces owned by the Noux process
*/
@ -162,14 +158,6 @@ class Noux::Child : public Rpc_object<Session>,
Pd_service::Single_session_factory _pd_factory { _pd };
Pd_service _pd_service { _pd_factory };
/**
* Locally-provided RAM service
*/
typedef Local_service<Ram_session_component> Ram_service;
Ram_session_component _ram { _ref_ram, _heap, _ep, _ds_registry };
Ram_service::Single_session_factory _ram_factory { _ram };
Ram_service _ram_service { _ram_factory };
/**
* Locally-provided CPU service
*/
@ -181,8 +169,7 @@ class Noux::Child : public Rpc_object<Session>,
/*
* Locally-provided Noux service
*/
Session_capability const _noux_session_cap =
Session_capability(_ep.manage(this));
Capability_guard _cap_guard { _ep, *this };
typedef Local_service<Rpc_object<Session> > Noux_service;
Noux_service::Single_session_factory _noux_factory { *this };
@ -209,12 +196,12 @@ class Noux::Child : public Rpc_object<Session>,
/*
* Child configuration
*/
Child_config _config { _ref_ram, _env.rm(), _verbose };
Child_config _config { _ref_pd, _env.rm(), _verbose };
enum { PAGE_SIZE = 4096, PAGE_MASK = ~(PAGE_SIZE - 1) };
enum { SYSIO_DS_SIZE = PAGE_MASK & (sizeof(Sysio) + PAGE_SIZE - 1) };
Attached_ram_dataspace _sysio_ds { _ref_ram, _env.rm(), SYSIO_DS_SIZE };
Attached_ram_dataspace _sysio_ds { _ref_pd, _env.rm(), SYSIO_DS_SIZE };
Sysio &_sysio = *_sysio_ds.local_addr<Sysio>();
typedef Ring_buffer<enum Sysio::Signal, Sysio::SIGNAL_QUEUE_SIZE>
@ -339,8 +326,6 @@ class Noux::Child : public Rpc_object<Session>,
Allocator &heap,
Pd_session &ref_pd,
Pd_session_capability ref_pd_cap,
Ram_session &ref_ram,
Ram_session_capability ref_ram_cap,
Parent_services &parent_services,
bool forked,
Destruct_queue &destruct_queue)
@ -359,10 +344,9 @@ class Noux::Child : public Rpc_object<Session>,
_root_dir(root_dir),
_destruct_queue(destruct_queue),
_heap(heap),
_ref_pd (ref_pd), _ref_pd_cap (ref_pd_cap),
_ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap),
_args(ref_ram, _env.rm(), ARGS_DS_SIZE, args),
_sysio_env(_ref_ram, _env.rm(), sysio_env),
_ref_pd (ref_pd), _ref_pd_cap (ref_pd_cap),
_args(ref_pd, _env.rm(), ARGS_DS_SIZE, args),
_sysio_env(_ref_pd, _env.rm(), sysio_env),
_parent_services(parent_services),
_sysio_ds_info(_ds_registry, _sysio_ds.cap()),
_args_ds_info(_ds_registry, _args.cap()),
@ -370,11 +354,11 @@ class Noux::Child : public Rpc_object<Session>,
_config_ds_info(_ds_registry, _config.cap()),
_child_policy(name, forked,
_args.cap(), _sysio_env.cap(), _config.cap(),
_ep, _pd_service, _ram_service, _cpu_service,
_ep, _pd_service, _cpu_service,
_noux_service, _empty_rom_service,
_rom_service, _parent_services,
*this, parent_exit, *this, _destruct_handler,
ref_pd, ref_pd_cap, ref_ram, ref_ram_cap,
ref_pd, ref_pd_cap,
_verbose.enabled()),
_child(_env.rm(), _ep, _child_policy)
{
@ -414,8 +398,7 @@ class Noux::Child : public Rpc_object<Session>,
}
}
Ram_session_component &ram() { return _ram; }
Pd_session_component &pd() { return _pd; }
Pd_session_component &pd() { return _pd; }
Dataspace_registry &ds_registry() { return _ds_registry; }
@ -541,8 +524,7 @@ class Noux::Child : public Rpc_object<Session>,
args,
env,
_heap,
_ref_pd, _ref_pd_cap,
_ref_ram, _ref_ram_cap,
_ref_pd, _ref_pd_cap,
_parent_services,
false,
_destruct_queue);

View File

@ -30,7 +30,6 @@ namespace Noux {
typedef Registry<Parent_service> Parent_services;
typedef Local_service<Pd_session_component> Pd_service;
typedef Local_service<Ram_session_component> Ram_service;
typedef Local_service<Cpu_session_component> Cpu_service;
typedef Local_service<Rpc_object<Session> > Noux_service;
@ -48,7 +47,6 @@ class Noux::Child_policy : public Genode::Child_policy
Init::Child_policy_provide_rom_file _env_policy;
Init::Child_policy_provide_rom_file _config_policy;
Pd_service &_pd_service;
Ram_service &_ram_service;
Cpu_service &_cpu_service;
Noux_service &_noux_service;
Empty_rom_service &_empty_rom_service;
@ -60,8 +58,6 @@ class Noux::Child_policy : public Genode::Child_policy
Signal_context_capability _destruct_context_cap;
Pd_session &_ref_pd;
Pd_session_capability _ref_pd_cap;
Ram_session &_ref_ram;
Ram_session_capability _ref_ram_cap;
int _exit_value;
bool _verbose;
@ -85,7 +81,6 @@ class Noux::Child_policy : public Genode::Child_policy
Dataspace_capability config_ds,
Rpc_entrypoint &entrypoint,
Pd_service &pd_service,
Ram_service &ram_service,
Cpu_service &cpu_service,
Noux_service &noux_service,
Empty_rom_service &empty_rom_service,
@ -97,24 +92,23 @@ class Noux::Child_policy : public Genode::Child_policy
Signal_context_capability destruct_context_cap,
Pd_session &ref_pd,
Pd_session_capability ref_pd_cap,
Ram_session &ref_ram,
Ram_session_capability ref_ram_cap,
bool verbose)
:
_name(name), _forked(forked),
_args_policy( "args", args_ds, &entrypoint),
_env_policy( "env", env_ds, &entrypoint),
_config_policy("config", config_ds, &entrypoint),
_pd_service(pd_service), _ram_service(ram_service),
_cpu_service(cpu_service), _noux_service(noux_service),
_pd_service(pd_service),
_cpu_service(cpu_service),
_noux_service(noux_service),
_empty_rom_service(empty_rom_service),
_rom_service(rom_service), _parent_services(parent_services),
_rom_service(rom_service),
_parent_services(parent_services),
_family_member(family_member),
_parent_exit(parent_exit),
_file_descriptor_registry(file_descriptor_registry),
_destruct_context_cap(destruct_context_cap),
_ref_pd (ref_pd), _ref_pd_cap (ref_pd_cap),
_ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap),
_ref_pd (ref_pd), _ref_pd_cap (ref_pd_cap),
_exit_value(~0),
_verbose(verbose)
{ }
@ -130,12 +124,9 @@ class Noux::Child_policy : public Genode::Child_policy
Pd_session &ref_pd() override { return _ref_pd; }
Pd_session_capability ref_pd_cap() const override { return _ref_pd_cap; }
Ram_session &ref_ram() override { return _ref_ram; }
Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
void init(Ram_session &session, Ram_session_capability cap) override
void init(Pd_session &session, Pd_session_capability cap) override
{
session.ref_account(_ref_ram_cap);
session.ref_account(_ref_pd_cap);
}
Service &resolve_session_request(Service::Name const &service_name,
@ -162,7 +153,6 @@ class Noux::Child_policy : public Genode::Child_policy
return *service;
/* check for local services */
if (service_name == Genode::Ram_session::service_name()) return _ram_service;
if (service_name == Genode::Cpu_session::service_name()) return _cpu_service;
if (service_name == Genode::Rom_session::service_name()) return _rom_service;
if (service_name == Genode::Pd_session::service_name()) return _pd_service;

View File

@ -102,7 +102,7 @@ class Noux::Dataspace_info : public Object_pool<Dataspace_info>::Entry
* RM session)
* \return capability for the new dataspace
*/
virtual Dataspace_capability fork(Ram_session &ram,
virtual Dataspace_capability fork(Ram_allocator &ram,
Region_map &local_rm,
Allocator &alloc,
Dataspace_registry &ds_registry,
@ -186,7 +186,7 @@ struct Noux::Static_dataspace_info : Dataspace_info
_ds_registry.apply(ds_cap(), lambda);
}
Dataspace_capability fork(Ram_session &,
Dataspace_capability fork(Ram_allocator &,
Region_map &,
Allocator &,
Dataspace_registry &,

View File

@ -40,7 +40,7 @@ class Noux::Environment : private Attached_ram_dataspace
*
* \param env comma-separated list of environment variables
*/
Environment(Ram_session &ram, Region_map &local_rm, Sysio::Env const &env)
Environment(Ram_allocator &ram, Region_map &local_rm, Sysio::Env const &env)
:
Attached_ram_dataspace(ram, local_rm, sizeof(Sysio::Env)),
_env(local_addr<Sysio::Env>())

View File

@ -255,9 +255,6 @@ struct Noux::Main
} _kill_broadcaster;
Dataspace_registry _ref_ram_ds_registry { _heap };
Ram_session_component _ref_ram { _env.ram(), _heap, _env.ep().rpc_ep(), _ref_ram_ds_registry };
Noux::Child _init_child { _name_of_init_process(),
_verbose,
_user_info,
@ -274,8 +271,6 @@ struct Noux::Main
_heap,
_env.pd(),
_env.pd_session_cap(),
_ref_ram,
Ram_session_capability(),
_parent_services,
false,
_destruct_queue };

View File

@ -2,6 +2,15 @@
* \brief PD service used by Noux processes
* \author Norman Feske
* \date 2016-04-20
*
* The custom implementation of the PD session interface provides a pool of
* RAM shared by Noux and all Noux processes. The use of a shared pool
* alleviates the need to assign RAM quota to individual Noux processes.
*
* Furthermore, the custom implementation is needed to get hold of the RAM
* dataspaces allocated by each Noux process. When forking a process, the
* acquired information (in the form of 'Ram_dataspace_info' objects) is used
* to create a shadow copy of the forking address space.
*/
/*
@ -21,8 +30,65 @@
/* Noux includes */
#include <region_map_component.h>
#include <dataspace_registry.h>
namespace Noux { class Pd_session_component; }
namespace Noux {
struct Ram_dataspace_info;
struct Pd_session_component;
using namespace Genode;
}
struct Noux::Ram_dataspace_info : Dataspace_info,
List<Ram_dataspace_info>::Element
{
Ram_dataspace_info(Ram_dataspace_capability ds_cap)
: Dataspace_info(ds_cap) { }
Dataspace_capability fork(Ram_allocator &ram,
Region_map &local_rm,
Allocator &alloc,
Dataspace_registry &ds_registry,
Rpc_entrypoint &) override
{
size_t const size = Dataspace_client(ds_cap()).size();
Ram_dataspace_capability dst_ds_cap;
try {
dst_ds_cap = ram.alloc(size);
Attached_dataspace src_ds(local_rm, ds_cap());
Attached_dataspace dst_ds(local_rm, dst_ds_cap);
memcpy(dst_ds.local_addr<char>(), src_ds.local_addr<char>(), size);
ds_registry.insert(new (alloc) Ram_dataspace_info(dst_ds_cap));
return dst_ds_cap;
} catch (...) {
error("fork of RAM dataspace failed");
if (dst_ds_cap.valid())
ram.free(dst_ds_cap);
return Dataspace_capability();
}
}
void poke(Region_map &rm, addr_t dst_offset, char const *src, size_t len) override
{
if (!src) return;
if ((dst_offset >= size()) || (dst_offset + len > size())) {
error("illegal attemt to write beyond dataspace boundary");
return;
}
try {
Attached_dataspace ds(rm, ds_cap());
memcpy(ds.local_addr<char>() + dst_offset, src, len);
} catch (...) { warning("poke: failed to attach RAM dataspace"); }
}
};
class Noux::Pd_session_component : public Rpc_object<Pd_session>
@ -39,6 +105,16 @@ class Noux::Pd_session_component : public Rpc_object<Pd_session>
Region_map_component _stack_area;
Region_map_component _linker_area;
Allocator &_alloc;
Ram_allocator &_ram;
Ram_quota _used_ram_quota { 0 };
List<Ram_dataspace_info> _ds_list;
Dataspace_registry &_ds_registry;
template <typename FUNC>
auto _with_automatic_cap_upgrade(FUNC func) -> decltype(func())
{
@ -62,7 +138,8 @@ class Noux::Pd_session_component : public Rpc_object<Pd_session>
_ep(ep), _pd(env, name.string()), _ref_pd(env.pd()),
_address_space(alloc, _ep, ds_registry, _pd, _pd.address_space()),
_stack_area (alloc, _ep, ds_registry, _pd, _pd.stack_area()),
_linker_area (alloc, _ep, ds_registry, _pd, _pd.linker_area())
_linker_area (alloc, _ep, ds_registry, _pd, _pd.linker_area()),
_alloc(alloc), _ram(env.ram()), _ds_registry(ds_registry)
{
_ep.manage(this);
@ -78,6 +155,10 @@ class Noux::Pd_session_component : public Rpc_object<Pd_session>
~Pd_session_component()
{
_ep.dissolve(this);
Ram_dataspace_info *info = 0;
while ((info = _ds_list.first()))
free(static_cap_cast<Ram_dataspace>(info->ds_cap()));
}
Pd_session_capability core_pd_cap() { return _pd.cap(); }
@ -96,17 +177,16 @@ class Noux::Pd_session_component : public Rpc_object<Pd_session>
Region_map &linker_area_region_map() { return _linker_area; }
Region_map &stack_area_region_map() { return _stack_area; }
void replay(Ram_session &dst_ram,
Pd_session_component &dst_pd,
void replay(Pd_session_component &dst_pd,
Region_map &local_rm,
Allocator &alloc,
Dataspace_registry &ds_registry,
Rpc_entrypoint &ep)
{
/* replay region map into new protection domain */
_stack_area .replay(dst_ram, dst_pd.stack_area_region_map(), local_rm, alloc, ds_registry, ep);
_linker_area .replay(dst_ram, dst_pd.linker_area_region_map(), local_rm, alloc, ds_registry, ep);
_address_space.replay(dst_ram, dst_pd.address_space_region_map(), local_rm, alloc, ds_registry, ep);
_stack_area .replay(dst_pd, dst_pd.stack_area_region_map(), local_rm, alloc, ds_registry, ep);
_linker_area .replay(dst_pd, dst_pd.linker_area_region_map(), local_rm, alloc, ds_registry, ep);
_address_space.replay(dst_pd, dst_pd.address_space_region_map(), local_rm, alloc, ds_registry, ep);
Region_map &dst_address_space = dst_pd.address_space_region_map();
Region_map &dst_stack_area = dst_pd.stack_area_region_map();
@ -183,6 +263,58 @@ class Noux::Pd_session_component : public Rpc_object<Pd_session>
Cap_quota cap_quota() const { return _pd.cap_quota(); }
Cap_quota used_caps() const { return _pd.used_caps(); }
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override
{
Ram_dataspace_capability ds_cap = _ram.alloc(size, cached);
Ram_dataspace_info *ds_info = new (_alloc) Ram_dataspace_info(ds_cap);
_ds_registry.insert(ds_info);
_ds_list.insert(ds_info);
_used_ram_quota = Ram_quota { _used_ram_quota.value + size };
return ds_cap;
}
void free(Ram_dataspace_capability ds_cap) override
{
Ram_dataspace_info *ds_info;
auto lambda = [&] (Ram_dataspace_info *rdi) {
ds_info = rdi;
if (!ds_info) {
error("RAM free: dataspace lookup failed");
return;
}
size_t const ds_size = rdi->size();
_ds_registry.remove(ds_info);
ds_info->dissolve_users();
_ds_list.remove(ds_info);
_ram.free(ds_cap);
_used_ram_quota = Ram_quota { _used_ram_quota.value - ds_size };
};
_ds_registry.apply(ds_cap, lambda);
destroy(_alloc, ds_info);
}
size_t dataspace_size(Ram_dataspace_capability ds_cap) const override
{
size_t result = 0;
_ds_registry.apply(ds_cap, [&] (Ram_dataspace_info *rdi) {
if (rdi)
result = rdi->size(); });
return result;
}
void transfer_quota(Pd_session_capability, Ram_quota) override { }
Ram_quota ram_quota() const override { return _pd.ram_quota(); }
Ram_quota used_ram() const override { return Ram_quota{_used_ram_quota}; }
Capability<Native_pd> native_pd() override {
return _pd.native_pd(); }
};

View File

@ -1,197 +0,0 @@
/*
* \brief RAM service used by Noux processes
* \author Norman Feske
* \date 2012-02-22
*
* The custom implementation of the RAM session interface provides a pool of
* RAM shared by Noux and all Noux processes. The use of a shared pool
* alleviates the need to assign RAM quota to individual Noux processes.
*
* Furthermore, the custom implementation is needed to get hold of the RAM
* dataspaces allocated by each Noux process. When forking a process, the
* acquired information (in the form of 'Ram_dataspace_info' objects) is used
* to create a shadow copy of the forking address space.
*/
/*
* Copyright (C) 2012-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _NOUX__RAM_SESSION_COMPONENT_H_
#define _NOUX__RAM_SESSION_COMPONENT_H_
/* Genode includes */
#include <ram_session/client.h>
#include <base/rpc_server.h>
/* Noux includes */
#include <dataspace_registry.h>
namespace Noux {
struct Ram_dataspace_info;
struct Ram_session_component;
using namespace Genode;
}
struct Noux::Ram_dataspace_info : Dataspace_info,
List<Ram_dataspace_info>::Element
{
Ram_dataspace_info(Ram_dataspace_capability ds_cap)
: Dataspace_info(ds_cap) { }
Dataspace_capability fork(Ram_session &ram,
Region_map &local_rm,
Allocator &alloc,
Dataspace_registry &ds_registry,
Rpc_entrypoint &) override
{
size_t const size = Dataspace_client(ds_cap()).size();
Ram_dataspace_capability dst_ds_cap;
try {
dst_ds_cap = ram.alloc(size);
Attached_dataspace src_ds(local_rm, ds_cap());
Attached_dataspace dst_ds(local_rm, dst_ds_cap);
memcpy(dst_ds.local_addr<char>(), src_ds.local_addr<char>(), size);
ds_registry.insert(new (alloc) Ram_dataspace_info(dst_ds_cap));
return dst_ds_cap;
} catch (...) {
error("fork of RAM dataspace failed");
if (dst_ds_cap.valid())
ram.free(dst_ds_cap);
return Dataspace_capability();
}
}
void poke(Region_map &rm, addr_t dst_offset, char const *src, size_t len) override
{
if (!src) return;
if ((dst_offset >= size()) || (dst_offset + len > size())) {
error("illegal attemt to write beyond dataspace boundary");
return;
}
try {
Attached_dataspace ds(rm, ds_cap());
memcpy(ds.local_addr<char>() + dst_offset, src, len);
} catch (...) { warning("poke: failed to attach RAM dataspace"); }
}
};
class Noux::Ram_session_component : public Rpc_object<Ram_session>
{
private:
Ram_session &_ram;
Allocator &_alloc;
Rpc_entrypoint &_ep;
List<Ram_dataspace_info> _list;
/*
* Track the RAM resources accumulated via RAM session allocations.
*
* XXX not used yet
*/
size_t _used_ram_quota = 0;
Dataspace_registry &_registry;
public:
/**
* Constructor
*/
Ram_session_component(Ram_session &ram, Allocator &alloc,
Rpc_entrypoint &ep, Dataspace_registry &registry)
:
_ram(ram), _alloc(alloc), _ep(ep), _registry(registry)
{
_ep.manage(this);
}
/**
* Destructor
*/
~Ram_session_component()
{
_ep.dissolve(this);
Ram_dataspace_info *info = 0;
while ((info = _list.first()))
free(static_cap_cast<Ram_dataspace>(info->ds_cap()));
}
/***************************
** Ram_session interface **
***************************/
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override
{
Ram_dataspace_capability ds_cap =
_ram.alloc(size, cached);
Ram_dataspace_info *ds_info = new (_alloc) Ram_dataspace_info(ds_cap);
_used_ram_quota += ds_info->size();
_registry.insert(ds_info);
_list.insert(ds_info);
return ds_cap;
}
void free(Ram_dataspace_capability ds_cap) override
{
Ram_dataspace_info *ds_info;
auto lambda = [&] (Ram_dataspace_info *rdi) {
ds_info = rdi;
if (!ds_info) {
error("RAM free: dataspace lookup failed");
return;
}
_registry.remove(ds_info);
ds_info->dissolve_users();
_list.remove(ds_info);
_used_ram_quota -= ds_info->size();
_ram.free(ds_cap);
};
_registry.apply(ds_cap, lambda);
destroy(_alloc, ds_info);
}
size_t dataspace_size(Ram_dataspace_capability ds_cap) const override
{
size_t result = 0;
_registry.apply(ds_cap, [&] (Ram_dataspace_info *rdi) {
if (rdi)
result = rdi->size(); });
return result;
}
void ref_account(Ram_session_capability) override { }
void transfer_quota(Ram_session_capability, Ram_quota) override { }
Ram_quota ram_quota() const override { return _ram.ram_quota(); }
Ram_quota used_ram() const override { return Ram_quota{_used_ram_quota}; }
};
#endif /* _NOUX__RAM_SESSION_COMPONENT_H_ */

View File

@ -25,6 +25,9 @@
#include <util/retry.h>
#include <pd_session/capability.h>
/* Noux includes */
#include <dataspace_registry.h>
namespace Noux { class Region_map_component; }
@ -159,7 +162,7 @@ class Noux::Region_map_component : public Rpc_object<Region_map>,
* \param ep entrypoint used to serve the RPC interface
* of forked managed dataspaces
*/
void replay(Ram_session &dst_ram,
void replay(Ram_allocator &dst_ram,
Region_map &dst_rm,
Region_map &local_rm,
Allocator &alloc,
@ -325,7 +328,7 @@ class Noux::Region_map_component : public Rpc_object<Region_map>,
** Dataspace_info interface **
******************************/
Dataspace_capability fork(Ram_session &,
Dataspace_capability fork(Ram_allocator &,
Region_map &,
Allocator &,
Dataspace_registry &,

View File

@ -31,7 +31,7 @@ struct Noux::Rom_dataspace_info : Dataspace_info
~Rom_dataspace_info() { }
Dataspace_capability fork(Ram_session &,
Dataspace_capability fork(Ram_allocator &,
Region_map &,
Allocator &alloc,
Dataspace_registry &ds_registry,

View File

@ -498,8 +498,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
_args,
_sysio_env.env(),
_heap,
_ref_pd, _ref_pd_cap,
_ref_ram, _ref_ram_cap,
_ref_pd, _ref_pd_cap,
_parent_services,
true,
_destruct_queue);
@ -514,7 +513,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
/* copy our address space into the new child */
try {
_pd.replay(child->ram(), child->pd(), _env.rm(), _heap,
_pd.replay(child->pd(), _env.rm(), _heap,
child->ds_registry(), _ep);
/* start executing the main thread of the new process */