mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 10:46:25 +00:00
base: fix quota transfer to async env services
Whenever an environment session was provided by an asynchronous service, e.g., the depot_rom of the sculpt scenario, the session quota was not transferred to the server at session-creation time. This resulted in a slow depletion of the server's quota over time. This patch ensures that the delivery of session quota is consistent with the information reported to the server as session argument.
This commit is contained in:
parent
578bec11ac
commit
81613afa03
@ -447,6 +447,15 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
_child(child), _service(service)
|
||||
{ }
|
||||
|
||||
/*
|
||||
* The 'Local_connection' may call 'initial_request' multiple
|
||||
* times. We use 'initial_request' as a hook to transfer the
|
||||
* session quota to an async service but we want to transfer
|
||||
* the session quota only once. The '_first_request' allows
|
||||
* us to distinguish the first from subsequent calls.
|
||||
*/
|
||||
bool _first_request = true;
|
||||
|
||||
void initiate_request(Session_state &session) override
|
||||
{
|
||||
session.ready_callback = this;
|
||||
@ -454,6 +463,23 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
|
||||
_service.initiate_request(session);
|
||||
|
||||
/*
|
||||
* If the env session is provided by an async service,
|
||||
* transfer the session resources.
|
||||
*/
|
||||
bool const async_service =
|
||||
session.phase == Session_state::CREATE_REQUESTED;
|
||||
|
||||
if (_first_request && async_service
|
||||
&& _service.name() != Pd_session::service_name()) {
|
||||
|
||||
Ram_quota const ram_quota { CONNECTION::RAM_QUOTA };
|
||||
Cap_quota const cap_quota { CONNECTION::CAP_QUOTA };
|
||||
_child._policy.ref_pd().transfer_quota(cap(ram_quota), ram_quota);
|
||||
_child._policy.ref_pd().transfer_quota(cap(cap_quota), cap_quota);
|
||||
_first_request = false;
|
||||
}
|
||||
|
||||
if (session.phase == Session_state::SERVICE_DENIED)
|
||||
error(_child._policy.name(), ": environment ",
|
||||
CONNECTION::service_name(), " session denied "
|
||||
@ -585,7 +611,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
return _connection.constructed() ? _connection->cap()
|
||||
: Capability<SESSION>(); }
|
||||
|
||||
bool alive() const { return _connection.constructed() && _connection->alive(); }
|
||||
bool closed() const { return !_connection.constructed() || _connection->closed(); }
|
||||
|
||||
void close() { if (_connection.constructed()) _connection->close(); }
|
||||
};
|
||||
@ -689,9 +715,14 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
*/
|
||||
bool env_sessions_closed() const
|
||||
{
|
||||
if (_linker.constructed() && _linker->alive()) return false;
|
||||
if (_linker.constructed() && !_linker->closed()) return false;
|
||||
|
||||
return !_cpu.alive() && !_log.alive() && !_binary.alive();
|
||||
/*
|
||||
* Note that the state of the CPU session remains unchecked here
|
||||
* because the eager CPU-session destruction does not work on all
|
||||
* kernels (search for KERNEL_SUPPORTS_EAGER_CHILD_DESTRUCTION).
|
||||
*/
|
||||
return _log.closed() && _binary.closed();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,7 +175,8 @@ class Genode::Local_connection : Local_connection_base
|
||||
service.wakeup();
|
||||
}
|
||||
|
||||
bool alive() const { return _session_state->alive(); }
|
||||
bool alive() const { return _session_state->alive(); }
|
||||
bool closed() const { return _session_state->closed(); }
|
||||
|
||||
using Local_connection_base::close;
|
||||
};
|
||||
|
@ -211,6 +211,26 @@ class Genode::Session_state : public Parent::Client, public Parent::Server
|
||||
return false;
|
||||
}
|
||||
|
||||
bool closed() const
|
||||
{
|
||||
switch (phase) {
|
||||
|
||||
case SERVICE_DENIED:
|
||||
case INSUFFICIENT_RAM_QUOTA:
|
||||
case INSUFFICIENT_CAP_QUOTA:
|
||||
case CLOSED:
|
||||
return true;
|
||||
|
||||
case CREATE_REQUESTED:
|
||||
case AVAILABLE:
|
||||
case CAP_HANDED_OUT:
|
||||
case UPGRADE_REQUESTED:
|
||||
case CLOSE_REQUESTED:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return client-side label of the session request
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user