mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 02:01:38 +00:00
parent
06b25a9082
commit
6f8dc9054a
@ -65,9 +65,7 @@ class Genode::Local_parent : public Expanding_parent_client
|
||||
* promote requests to non-local
|
||||
* services
|
||||
*/
|
||||
Local_parent(Parent_capability parent_cap,
|
||||
Emergency_ram_reserve &,
|
||||
Allocator &);
|
||||
Local_parent(Parent_capability parent_cap, Allocator &);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__INTERNAL__LOCAL_PARENT_H_ */
|
||||
|
@ -101,8 +101,7 @@ class Genode::Platform_env_base : public Env_deprecated
|
||||
/**
|
||||
* 'Platform_env' used by all processes except for core
|
||||
*/
|
||||
class Genode::Platform_env : public Platform_env_base,
|
||||
public Expanding_parent_client::Emergency_ram_reserve
|
||||
class Genode::Platform_env : public Platform_env_base
|
||||
{
|
||||
private:
|
||||
|
||||
@ -113,14 +112,6 @@ class Genode::Platform_env : public Platform_env_base,
|
||||
|
||||
Heap _heap;
|
||||
|
||||
/*
|
||||
* Emergency RAM reserve
|
||||
*
|
||||
* See the comment of '_fallback_sig_cap()' in 'env/env.cc'.
|
||||
*/
|
||||
constexpr static size_t _emergency_ram_size() { return 8*1024; }
|
||||
Ram_dataspace_capability _emergency_ram_ds;
|
||||
|
||||
/**
|
||||
* Attach stack area to local address space (for non-hybrid components)
|
||||
*/
|
||||
@ -139,13 +130,6 @@ class Genode::Platform_env : public Platform_env_base,
|
||||
~Platform_env() { _parent().exit(0); }
|
||||
|
||||
|
||||
/*************************************
|
||||
** Emergency_ram_reserve interface **
|
||||
*************************************/
|
||||
|
||||
void release() { ram_session()->free(_emergency_ram_ds); }
|
||||
|
||||
|
||||
/******************************
|
||||
** Env_deprecated interface **
|
||||
******************************/
|
||||
|
@ -101,10 +101,9 @@ Parent::Close_result Local_parent::close(Client::Id id)
|
||||
|
||||
|
||||
Local_parent::Local_parent(Parent_capability parent_cap,
|
||||
Emergency_ram_reserve &reserve,
|
||||
Allocator &alloc)
|
||||
:
|
||||
Expanding_parent_client(parent_cap, reserve), _alloc(alloc)
|
||||
Expanding_parent_client(parent_cap), _alloc(alloc)
|
||||
{ }
|
||||
|
||||
|
||||
@ -148,7 +147,7 @@ static Parent_capability obtain_parent_cap()
|
||||
|
||||
Local_parent &Platform_env::_parent()
|
||||
{
|
||||
static Local_parent local_parent(obtain_parent_cap(), *this, _heap);
|
||||
static Local_parent local_parent(obtain_parent_cap(), _heap);
|
||||
return local_parent;
|
||||
}
|
||||
|
||||
@ -157,8 +156,7 @@ Platform_env::Platform_env()
|
||||
:
|
||||
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()))
|
||||
_heap(Platform_env_base::ram_session(), Platform_env_base::rm_session())
|
||||
{
|
||||
_attach_stack_area();
|
||||
|
||||
|
@ -92,6 +92,12 @@ Platform_generic *Genode::platform() { return platform_specific(); }
|
||||
Thread_capability Genode::main_thread_cap() { return Thread_capability(); }
|
||||
|
||||
|
||||
/**
|
||||
* Dummy implementation for core that has no parent to ask for resources
|
||||
*/
|
||||
void Genode::init_parent_resource_requests(Genode::Env & env) {};
|
||||
|
||||
|
||||
/****************
|
||||
** Core child **
|
||||
****************/
|
||||
|
@ -28,13 +28,6 @@ namespace Genode { class Expanding_parent_client; }
|
||||
|
||||
class Genode::Expanding_parent_client : public Parent_client
|
||||
{
|
||||
public:
|
||||
|
||||
struct Emergency_ram_reserve
|
||||
{
|
||||
virtual void release() = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@ -58,29 +51,43 @@ class Genode::Expanding_parent_client : public Parent_client
|
||||
Lock _lock;
|
||||
|
||||
/**
|
||||
* Return signal context capability for the fallback signal handler
|
||||
* Signal context for the fallback signal handler
|
||||
*/
|
||||
Signal_context_capability _fallback_sig_cap();
|
||||
Signal_context _fallback_sig_ctx;
|
||||
|
||||
/**
|
||||
* Signal context capability for the fallback signal handler
|
||||
*/
|
||||
Signal_context_capability _fallback_sig_cap;
|
||||
|
||||
/**
|
||||
* Signal receiver for the fallback signal handler
|
||||
*/
|
||||
Constructible<Signal_receiver> _fallback_sig_rcv;
|
||||
|
||||
/**
|
||||
* Block for resource response arriving at the fallback signal handler
|
||||
*/
|
||||
static void _wait_for_resource_response();
|
||||
|
||||
/**
|
||||
* Emergency RAM reserve for constructing the fallback signal handler
|
||||
*
|
||||
* See the comment of '_fallback_sig_cap()' in 'env/env.cc'.
|
||||
*/
|
||||
Emergency_ram_reserve &_emergency_ram_reserve;
|
||||
void _wait_for_resource_response() {
|
||||
_fallback_sig_rcv->wait_for_signal(); }
|
||||
|
||||
public:
|
||||
|
||||
Expanding_parent_client(Parent_capability cap,
|
||||
Emergency_ram_reserve &emergency_ram_reserve)
|
||||
:
|
||||
Parent_client(cap), _emergency_ram_reserve(emergency_ram_reserve)
|
||||
{ }
|
||||
Expanding_parent_client(Parent_capability cap)
|
||||
: Parent_client(cap) { }
|
||||
|
||||
|
||||
/**
|
||||
* Downstreamed construction of the fallback signaling, used
|
||||
* when the environment is ready to construct a signal receiver
|
||||
*/
|
||||
void init_fallback_signal_handling()
|
||||
{
|
||||
if (!_fallback_sig_cap.valid()) {
|
||||
_fallback_sig_rcv.construct();
|
||||
_fallback_sig_cap = _fallback_sig_rcv->manage(&_fallback_sig_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
@ -168,7 +175,7 @@ class Genode::Expanding_parent_client : public Parent_client
|
||||
* Install fallback signal handler not yet installed.
|
||||
*/
|
||||
if (_state == UNDEFINED) {
|
||||
Parent_client::resource_avail_sigh(_fallback_sig_cap());
|
||||
Parent_client::resource_avail_sigh(_fallback_sig_cap);
|
||||
_state = BLOCKING_DEFAULT;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ namespace Genode {
|
||||
void init_signal_thread(Env &);
|
||||
void init_root_proxy(Env &);
|
||||
void init_log();
|
||||
void init_parent_resource_requests(Env &);
|
||||
void exec_static_constructors();
|
||||
|
||||
void destroy_signal_thread();
|
||||
|
@ -42,8 +42,7 @@ namespace Genode {
|
||||
}
|
||||
|
||||
|
||||
class Genode::Platform_env : public Platform_env_base,
|
||||
public Expanding_parent_client::Emergency_ram_reserve
|
||||
class Genode::Platform_env : public Platform_env_base
|
||||
{
|
||||
private:
|
||||
|
||||
@ -81,14 +80,6 @@ class Genode::Platform_env : public Platform_env_base,
|
||||
*/
|
||||
Attached_stack_area _stack_area { _parent_client, _resources.pd };
|
||||
|
||||
/*
|
||||
* Emergency RAM reserve
|
||||
*
|
||||
* See the comment of '_fallback_sig_cap()' in 'env/env.cc'.
|
||||
*/
|
||||
constexpr static size_t _emergency_ram_size() { return 16*1024; }
|
||||
Ram_dataspace_capability _emergency_ram_ds;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -96,10 +87,9 @@ class Genode::Platform_env : public Platform_env_base,
|
||||
*/
|
||||
Platform_env()
|
||||
:
|
||||
_parent_client(Genode::parent_cap(), *this),
|
||||
_parent_client(Genode::parent_cap()),
|
||||
_resources(_parent_client),
|
||||
_heap(&_resources.pd, &_resources.rm, Heap::UNLIMITED),
|
||||
_emergency_ram_ds(_resources.pd.alloc(_emergency_ram_size()))
|
||||
_heap(&_resources.pd, &_resources.rm, Heap::UNLIMITED)
|
||||
{
|
||||
env_stack_area_ram_allocator = &_resources.pd;
|
||||
env_stack_area_region_map = &_stack_area;
|
||||
@ -112,18 +102,6 @@ class Genode::Platform_env : public Platform_env_base,
|
||||
void reinit_main_thread(Capability<Region_map> &) override;
|
||||
|
||||
|
||||
/*************************************
|
||||
** Emergency_ram_reserve interface **
|
||||
*************************************/
|
||||
|
||||
void release()
|
||||
{
|
||||
log("used before freeing emergency=", _resources.pd.used_ram());
|
||||
_resources.pd.free(_emergency_ram_ds);
|
||||
log("used after freeing emergency=", _resources.pd.used_ram());
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
** Env_deprecated interface **
|
||||
******************************/
|
||||
|
@ -274,6 +274,12 @@ namespace {
|
||||
Genode::call_global_static_constructors();
|
||||
Genode::init_signal_transmitter(env);
|
||||
|
||||
/*
|
||||
* Now, as signaling is available, initialize the asynchronous
|
||||
* parent resource mechanism
|
||||
*/
|
||||
init_parent_resource_requests(env);
|
||||
|
||||
Component::construct(env);
|
||||
}
|
||||
};
|
||||
|
@ -34,47 +34,12 @@ namespace Genode {
|
||||
}
|
||||
|
||||
|
||||
static Genode::Signal_receiver *resource_sig_rec()
|
||||
void Genode::init_parent_resource_requests(Genode::Env & env)
|
||||
{
|
||||
static Genode::Signal_receiver sig_rec;
|
||||
return &sig_rec;
|
||||
}
|
||||
|
||||
|
||||
Genode::Signal_context_capability
|
||||
Genode::Expanding_parent_client::_fallback_sig_cap()
|
||||
{
|
||||
static Signal_context _sig_ctx;
|
||||
static Signal_context_capability _sig_cap;
|
||||
|
||||
/* create signal-context capability only once */
|
||||
if (!_sig_cap.valid()) {
|
||||
|
||||
/*
|
||||
* Because the 'manage' function consumes meta data of the signal
|
||||
* session, calling it may result in an 'Out_of_ram' or 'Out_of_caps' error.
|
||||
* The 'manage' function handles this error by upgrading the session quota
|
||||
* accordingly. However, this upgrade, in turn, may result in the
|
||||
* depletion of the process' RAM quota. In this case, the process would
|
||||
* issue a resource request to the parent. But in order to do so, the
|
||||
* fallback signal handler has to be constructed. To solve this
|
||||
* hen-and-egg problem, we allocate a so-called emergency RAM reserve
|
||||
* immediately at the startup of the process as part of the
|
||||
* 'Platform_env'. When initializing the fallback signal handler, these
|
||||
* resources get released in order to ensure an eventual upgrade of the
|
||||
* signal session to succeed.
|
||||
*
|
||||
* The corner case is tested by 'os/src/test/resource_request'.
|
||||
*/
|
||||
_emergency_ram_reserve.release();
|
||||
_sig_cap = resource_sig_rec()->manage(&_sig_ctx);
|
||||
}
|
||||
|
||||
return _sig_cap;
|
||||
}
|
||||
|
||||
|
||||
void Genode::Expanding_parent_client::_wait_for_resource_response()
|
||||
{
|
||||
resource_sig_rec()->wait_for_signal();
|
||||
/**
|
||||
* Catch up asynchronous resource request and notification
|
||||
* mechanism construction of the expanding parent environment
|
||||
*/
|
||||
using Parent = Expanding_parent_client;
|
||||
static_cast<Parent*>(&env.parent())->init_fallback_signal_handling();
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ void Genode::Platform_env::reinit(Native_capability::Raw raw)
|
||||
* Re-initialize 'Platform_env' members
|
||||
*/
|
||||
Expanding_parent_client * const p = &_parent_client;
|
||||
construct_at<Expanding_parent_client>(p, parent_cap(), *this);
|
||||
construct_at<Expanding_parent_client>(p, parent_cap());
|
||||
construct_at<Resources>(&_resources, _parent_client);
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user