parent
06b25a9082
commit
6f8dc9054a
|
@ -65,9 +65,7 @@ class Genode::Local_parent : public Expanding_parent_client
|
||||||
* promote requests to non-local
|
* promote requests to non-local
|
||||||
* services
|
* services
|
||||||
*/
|
*/
|
||||||
Local_parent(Parent_capability parent_cap,
|
Local_parent(Parent_capability parent_cap, Allocator &);
|
||||||
Emergency_ram_reserve &,
|
|
||||||
Allocator &);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__BASE__INTERNAL__LOCAL_PARENT_H_ */
|
#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
|
* 'Platform_env' used by all processes except for core
|
||||||
*/
|
*/
|
||||||
class Genode::Platform_env : public Platform_env_base,
|
class Genode::Platform_env : public Platform_env_base
|
||||||
public Expanding_parent_client::Emergency_ram_reserve
|
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -113,14 +112,6 @@ class Genode::Platform_env : public Platform_env_base,
|
||||||
|
|
||||||
Heap _heap;
|
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)
|
* 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); }
|
~Platform_env() { _parent().exit(0); }
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
|
||||||
** Emergency_ram_reserve interface **
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
void release() { ram_session()->free(_emergency_ram_ds); }
|
|
||||||
|
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
** Env_deprecated interface **
|
** Env_deprecated interface **
|
||||||
******************************/
|
******************************/
|
||||||
|
|
|
@ -101,10 +101,9 @@ Parent::Close_result Local_parent::close(Client::Id id)
|
||||||
|
|
||||||
|
|
||||||
Local_parent::Local_parent(Parent_capability parent_cap,
|
Local_parent::Local_parent(Parent_capability parent_cap,
|
||||||
Emergency_ram_reserve &reserve,
|
|
||||||
Allocator &alloc)
|
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()
|
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;
|
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())),
|
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()))),
|
static_cap_cast<Pd_session> (_parent().session_cap(Parent::Env::pd()))),
|
||||||
_heap(Platform_env_base::ram_session(), Platform_env_base::rm_session()),
|
_heap(Platform_env_base::ram_session(), Platform_env_base::rm_session())
|
||||||
_emergency_ram_ds(ram_session()->alloc(_emergency_ram_size()))
|
|
||||||
{
|
{
|
||||||
_attach_stack_area();
|
_attach_stack_area();
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,12 @@ Platform_generic *Genode::platform() { return platform_specific(); }
|
||||||
Thread_capability Genode::main_thread_cap() { return Thread_capability(); }
|
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 **
|
** Core child **
|
||||||
****************/
|
****************/
|
||||||
|
|
|
@ -28,13 +28,6 @@ namespace Genode { class Expanding_parent_client; }
|
||||||
|
|
||||||
class Genode::Expanding_parent_client : public Parent_client
|
class Genode::Expanding_parent_client : public Parent_client
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
struct Emergency_ram_reserve
|
|
||||||
{
|
|
||||||
virtual void release() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,29 +51,43 @@ class Genode::Expanding_parent_client : public Parent_client
|
||||||
Lock _lock;
|
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
|
* Block for resource response arriving at the fallback signal handler
|
||||||
*/
|
*/
|
||||||
static void _wait_for_resource_response();
|
void _wait_for_resource_response() {
|
||||||
|
_fallback_sig_rcv->wait_for_signal(); }
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Expanding_parent_client(Parent_capability cap,
|
Expanding_parent_client(Parent_capability cap)
|
||||||
Emergency_ram_reserve &emergency_ram_reserve)
|
: Parent_client(cap) { }
|
||||||
:
|
|
||||||
Parent_client(cap), _emergency_ram_reserve(emergency_ram_reserve)
|
|
||||||
{ }
|
/**
|
||||||
|
* 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.
|
* Install fallback signal handler not yet installed.
|
||||||
*/
|
*/
|
||||||
if (_state == UNDEFINED) {
|
if (_state == UNDEFINED) {
|
||||||
Parent_client::resource_avail_sigh(_fallback_sig_cap());
|
Parent_client::resource_avail_sigh(_fallback_sig_cap);
|
||||||
_state = BLOCKING_DEFAULT;
|
_state = BLOCKING_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace Genode {
|
||||||
void init_signal_thread(Env &);
|
void init_signal_thread(Env &);
|
||||||
void init_root_proxy(Env &);
|
void init_root_proxy(Env &);
|
||||||
void init_log();
|
void init_log();
|
||||||
|
void init_parent_resource_requests(Env &);
|
||||||
void exec_static_constructors();
|
void exec_static_constructors();
|
||||||
|
|
||||||
void destroy_signal_thread();
|
void destroy_signal_thread();
|
||||||
|
|
|
@ -42,8 +42,7 @@ namespace Genode {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Genode::Platform_env : public Platform_env_base,
|
class Genode::Platform_env : public Platform_env_base
|
||||||
public Expanding_parent_client::Emergency_ram_reserve
|
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -81,14 +80,6 @@ class Genode::Platform_env : public Platform_env_base,
|
||||||
*/
|
*/
|
||||||
Attached_stack_area _stack_area { _parent_client, _resources.pd };
|
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:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,10 +87,9 @@ class Genode::Platform_env : public Platform_env_base,
|
||||||
*/
|
*/
|
||||||
Platform_env()
|
Platform_env()
|
||||||
:
|
:
|
||||||
_parent_client(Genode::parent_cap(), *this),
|
_parent_client(Genode::parent_cap()),
|
||||||
_resources(_parent_client),
|
_resources(_parent_client),
|
||||||
_heap(&_resources.pd, &_resources.rm, Heap::UNLIMITED),
|
_heap(&_resources.pd, &_resources.rm, Heap::UNLIMITED)
|
||||||
_emergency_ram_ds(_resources.pd.alloc(_emergency_ram_size()))
|
|
||||||
{
|
{
|
||||||
env_stack_area_ram_allocator = &_resources.pd;
|
env_stack_area_ram_allocator = &_resources.pd;
|
||||||
env_stack_area_region_map = &_stack_area;
|
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;
|
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 **
|
** Env_deprecated interface **
|
||||||
******************************/
|
******************************/
|
||||||
|
|
|
@ -274,6 +274,12 @@ namespace {
|
||||||
Genode::call_global_static_constructors();
|
Genode::call_global_static_constructors();
|
||||||
Genode::init_signal_transmitter(env);
|
Genode::init_signal_transmitter(env);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, as signaling is available, initialize the asynchronous
|
||||||
|
* parent resource mechanism
|
||||||
|
*/
|
||||||
|
init_parent_resource_requests(env);
|
||||||
|
|
||||||
Component::construct(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;
|
* Catch up asynchronous resource request and notification
|
||||||
}
|
* mechanism construction of the expanding parent environment
|
||||||
|
*/
|
||||||
|
using Parent = Expanding_parent_client;
|
||||||
Genode::Signal_context_capability
|
static_cast<Parent*>(&env.parent())->init_fallback_signal_handling();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ void Genode::Platform_env::reinit(Native_capability::Raw raw)
|
||||||
* Re-initialize 'Platform_env' members
|
* Re-initialize 'Platform_env' members
|
||||||
*/
|
*/
|
||||||
Expanding_parent_client * const p = &_parent_client;
|
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);
|
construct_at<Resources>(&_resources, _parent_client);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue
Block a user