2014-10-02 12:47:08 +00:00
|
|
|
/*
|
|
|
|
* \brief Child handling
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2013-10-05
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 12:23:52 +00:00
|
|
|
* Copyright (C) 2013-2017 Genode Labs GmbH
|
2014-10-02 12:47:08 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 12:23:52 +00:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2014-10-02 12:47:08 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _INCLUDE__CLI_MONITOR__CHILD_H_
|
|
|
|
#define _INCLUDE__CLI_MONITOR__CHILD_H_
|
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <util/list.h>
|
2016-11-06 13:27:26 +00:00
|
|
|
#include <base/registry.h>
|
2014-10-02 12:47:08 +00:00
|
|
|
#include <base/child.h>
|
|
|
|
#include <init/child_policy.h>
|
|
|
|
#include <os/child_policy_dynamic_rom.h>
|
|
|
|
#include <cpu_session/connection.h>
|
2015-05-05 06:50:16 +00:00
|
|
|
#include <pd_session/connection.h>
|
2016-05-12 12:58:51 +00:00
|
|
|
#include <base/session_label.h>
|
2014-10-02 12:47:08 +00:00
|
|
|
|
|
|
|
/* CLI-monitor includes */
|
|
|
|
#include <cli_monitor/ram.h>
|
|
|
|
|
2017-01-03 11:52:42 +00:00
|
|
|
namespace Cli_monitor { class Child_base; }
|
2015-09-15 13:37:42 +00:00
|
|
|
|
2017-01-03 11:52:42 +00:00
|
|
|
|
|
|
|
class Cli_monitor::Child_base : public Genode::Child_policy
|
2014-10-02 12:47:08 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX derive donated quota from information to be provided by
|
|
|
|
* the used 'Connection' interfaces
|
|
|
|
*/
|
|
|
|
enum { DONATED_RAM_QUOTA = 128*1024 };
|
|
|
|
|
|
|
|
class Quota_exceeded : public Genode::Exception { };
|
|
|
|
|
|
|
|
typedef Genode::size_t size_t;
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
typedef Genode::Cap_quota Cap_quota;
|
2014-10-02 12:47:08 +00:00
|
|
|
|
2016-11-06 13:27:26 +00:00
|
|
|
typedef Genode::Registered<Genode::Parent_service> Parent_service;
|
|
|
|
|
2014-10-02 12:47:08 +00:00
|
|
|
private:
|
|
|
|
|
|
|
|
Ram &_ram;
|
|
|
|
|
2017-02-17 09:53:59 +00:00
|
|
|
Genode::Allocator &_alloc;
|
|
|
|
|
2016-05-12 12:58:51 +00:00
|
|
|
Genode::Session_label const _label;
|
2016-11-06 13:27:26 +00:00
|
|
|
Binary_name const _binary_name;
|
|
|
|
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
Genode::Pd_session_capability _ref_pd_cap;
|
|
|
|
Genode::Pd_session &_ref_pd;
|
|
|
|
|
2016-11-06 13:27:26 +00:00
|
|
|
Genode::Ram_session_capability _ref_ram_cap;
|
|
|
|
Genode::Ram_session &_ref_ram;
|
2014-10-02 12:47:08 +00:00
|
|
|
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
Cap_quota _cap_quota;
|
|
|
|
|
2016-05-10 16:05:38 +00:00
|
|
|
size_t _ram_quota;
|
|
|
|
size_t _ram_limit;
|
|
|
|
|
2017-02-17 09:53:59 +00:00
|
|
|
struct Parent_services : Genode::Registry<Parent_service>
|
|
|
|
{
|
|
|
|
Genode::Allocator &_alloc;
|
|
|
|
Parent_services(Genode::Allocator &alloc) : _alloc(alloc) { }
|
|
|
|
~Parent_services()
|
|
|
|
{
|
|
|
|
for_each([&] (Parent_service &s) { Genode::destroy(_alloc, &s); });
|
|
|
|
}
|
|
|
|
} _parent_services { _alloc };
|
2014-10-02 12:47:08 +00:00
|
|
|
|
|
|
|
enum { ENTRYPOINT_STACK_SIZE = 12*1024 };
|
|
|
|
Genode::Rpc_entrypoint _entrypoint;
|
|
|
|
|
|
|
|
Genode::Child_policy_dynamic_rom_file _config_policy;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If set to true, immediately withdraw resources yielded by the child
|
|
|
|
*/
|
|
|
|
bool _withdraw_on_yield_response = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Arguments of current resource request from the child
|
|
|
|
*/
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
Genode::Parent::Resource_args _resource_args { };
|
2014-10-02 12:47:08 +00:00
|
|
|
|
|
|
|
Genode::Signal_context_capability _yield_response_sigh_cap;
|
|
|
|
|
2015-09-15 13:37:42 +00:00
|
|
|
Genode::Signal_context_capability _exit_sig_cap;
|
|
|
|
|
|
|
|
/* true if child is scheduled for destruction */
|
|
|
|
bool _exited = false;
|
|
|
|
|
2016-11-06 13:27:26 +00:00
|
|
|
Genode::Child _child;
|
|
|
|
|
2014-10-02 12:47:08 +00:00
|
|
|
public:
|
|
|
|
|
2016-11-06 13:27:26 +00:00
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* \param ref_ram used as reference account for the child'd RAM
|
|
|
|
* session and for allocating the backing store
|
|
|
|
* for the child's configuration
|
2017-02-17 09:53:59 +00:00
|
|
|
* \param alloc allocator used to fill parent-service registry
|
|
|
|
* on demand
|
2016-11-06 13:27:26 +00:00
|
|
|
*/
|
2014-10-02 12:47:08 +00:00
|
|
|
Child_base(Ram &ram,
|
2017-02-17 09:53:59 +00:00
|
|
|
Genode::Allocator &alloc,
|
2016-11-06 13:27:26 +00:00
|
|
|
Name const &label,
|
|
|
|
Binary_name const &binary_name,
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
Genode::Pd_session &ref_pd,
|
|
|
|
Genode::Pd_session_capability ref_pd_cap,
|
2016-11-06 13:27:26 +00:00
|
|
|
Genode::Ram_session &ref_ram,
|
|
|
|
Genode::Ram_session_capability ref_ram_cap,
|
|
|
|
Genode::Region_map &local_rm,
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
Cap_quota cap_quota,
|
2014-10-02 12:47:08 +00:00
|
|
|
Genode::size_t ram_quota,
|
|
|
|
Genode::size_t ram_limit,
|
2015-09-15 13:37:42 +00:00
|
|
|
Genode::Signal_context_capability yield_response_sig_cap,
|
2016-11-06 13:27:26 +00:00
|
|
|
Genode::Signal_context_capability exit_sig_cap)
|
2014-10-02 12:47:08 +00:00
|
|
|
:
|
2017-02-17 09:53:59 +00:00
|
|
|
_ram(ram), _alloc(alloc),
|
2016-11-06 13:27:26 +00:00
|
|
|
_label(label), _binary_name(binary_name),
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
_ref_pd_cap (ref_pd_cap), _ref_pd (ref_pd),
|
2016-11-06 13:27:26 +00:00
|
|
|
_ref_ram_cap(ref_ram_cap), _ref_ram(ref_ram),
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
_cap_quota(cap_quota), _ram_quota(ram_quota), _ram_limit(ram_limit),
|
|
|
|
_entrypoint(&ref_pd, ENTRYPOINT_STACK_SIZE, _label.string(), false),
|
2017-02-16 10:28:21 +00:00
|
|
|
_config_policy(local_rm, "config", _entrypoint, &ref_ram),
|
2015-09-15 13:37:42 +00:00
|
|
|
_yield_response_sigh_cap(yield_response_sig_cap),
|
2016-11-06 13:27:26 +00:00
|
|
|
_exit_sig_cap(exit_sig_cap),
|
|
|
|
_child(local_rm, _entrypoint, *this)
|
2014-10-02 12:47:08 +00:00
|
|
|
{ }
|
|
|
|
|
2016-05-12 12:58:51 +00:00
|
|
|
Genode::Session_label label() const { return _label; }
|
2014-10-02 12:47:08 +00:00
|
|
|
|
|
|
|
void configure(char const *config, size_t config_len)
|
|
|
|
{
|
|
|
|
_config_policy.load(config, config_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
void start()
|
|
|
|
{
|
|
|
|
_entrypoint.activate();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Issue yield request to the child
|
|
|
|
*/
|
|
|
|
void yield(size_t amount, bool greedy)
|
|
|
|
{
|
|
|
|
if (requested_ram_quota())
|
|
|
|
return; /* resource request in flight */
|
|
|
|
|
|
|
|
char buf[128];
|
2016-09-15 12:40:37 +00:00
|
|
|
Genode::snprintf(buf, sizeof(buf), "ram_quota=%ld", amount);
|
2014-10-02 12:47:08 +00:00
|
|
|
_withdraw_on_yield_response = greedy;
|
|
|
|
_child.yield(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return amount of RAM currently requested by the child
|
|
|
|
*/
|
|
|
|
size_t requested_ram_quota() const
|
|
|
|
{
|
|
|
|
return Genode::Arg_string::find_arg(_resource_args.string(), "ram_quota").ulong_value(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Withdraw quota from the child
|
|
|
|
*
|
|
|
|
* \throw Ram::Transfer_quota_failed
|
|
|
|
*/
|
|
|
|
void withdraw_ram_quota(size_t amount)
|
|
|
|
{
|
|
|
|
if (!amount)
|
|
|
|
return;
|
|
|
|
|
2016-11-06 13:27:26 +00:00
|
|
|
_ram.withdraw_from(_child.ram_session_cap(), amount);
|
2014-10-02 12:47:08 +00:00
|
|
|
_ram_quota -= amount;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Upgrade quota of child
|
|
|
|
*
|
|
|
|
* \throw Ram::Transfer_quota_failed
|
|
|
|
*/
|
|
|
|
void upgrade_ram_quota(size_t amount)
|
|
|
|
{
|
2016-11-06 13:27:26 +00:00
|
|
|
_ram.transfer_to(_child.ram_session_cap(), amount);
|
2014-10-02 12:47:08 +00:00
|
|
|
_ram_quota += amount;
|
|
|
|
|
|
|
|
/* wake up child if resource request is in flight */
|
|
|
|
size_t const req = requested_ram_quota();
|
2017-05-07 23:33:40 +00:00
|
|
|
if (req && _child.ram().avail_ram().value >= req) {
|
2014-10-02 12:47:08 +00:00
|
|
|
_child.notify_resource_avail();
|
|
|
|
|
|
|
|
/* clear request state */
|
|
|
|
_resource_args = Genode::Parent::Resource_args("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Try to respond to a current resource request issued by the child
|
|
|
|
*
|
2015-03-20 16:50:41 +00:00
|
|
|
* This method evaluates the conditions, under which a resource
|
2014-10-02 12:47:08 +00:00
|
|
|
* request can be answered: There must be enough room between the
|
|
|
|
* current quota and the configured limit, and there must be enough
|
|
|
|
* slack memory available. If both conditions are met, the quota
|
|
|
|
* of the child gets upgraded.
|
|
|
|
*/
|
|
|
|
void try_response_to_resource_request()
|
|
|
|
{
|
|
|
|
size_t const req = requested_ram_quota();
|
|
|
|
|
|
|
|
if (!req)
|
|
|
|
return; /* no resource request in flight */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Respond to the current request if the requested quota fits
|
|
|
|
* within the limit and if there is enough free quota available.
|
|
|
|
*/
|
|
|
|
if (req <= _ram.status().avail && req + _ram_quota <= _ram_limit) {
|
|
|
|
try { upgrade_ram_quota(req); }
|
|
|
|
catch (Ram::Transfer_quota_failed) { }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set limit for on-demand RAM quota expansion
|
|
|
|
*/
|
|
|
|
void ram_limit(size_t limit)
|
|
|
|
{
|
|
|
|
_ram_limit = limit;
|
|
|
|
try_response_to_resource_request();
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Ram_status
|
|
|
|
{
|
|
|
|
size_t quota = 0, limit = 0, xfer = 0, used = 0, avail = 0, req = 0;
|
|
|
|
|
|
|
|
Ram_status() { }
|
|
|
|
Ram_status(size_t quota, size_t limit, size_t xfer, size_t used,
|
|
|
|
size_t avail, size_t req)
|
|
|
|
:
|
|
|
|
quota(quota), limit(limit), xfer(xfer), used(used),
|
|
|
|
avail(avail), req(req)
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return RAM quota status of the child
|
|
|
|
*
|
2015-03-20 16:50:41 +00:00
|
|
|
* XXX should be a const method, but the 'Ram_session' accessors
|
2014-10-02 12:47:08 +00:00
|
|
|
* are not const
|
|
|
|
*/
|
|
|
|
Ram_status ram_status()
|
|
|
|
{
|
|
|
|
return Ram_status(_ram_quota,
|
|
|
|
_ram_limit,
|
2017-05-07 23:33:40 +00:00
|
|
|
_ram_quota - _child.ram().ram_quota().value,
|
|
|
|
_child.ram().used_ram().value,
|
|
|
|
_child.ram().avail_ram().value,
|
2014-10-02 12:47:08 +00:00
|
|
|
requested_ram_quota());
|
|
|
|
}
|
|
|
|
|
2015-09-15 13:37:42 +00:00
|
|
|
/**
|
|
|
|
* Return true if child exited and should be destructed
|
|
|
|
*/
|
|
|
|
bool exited() const { return _exited; }
|
|
|
|
|
2014-10-02 12:47:08 +00:00
|
|
|
|
|
|
|
/****************************
|
|
|
|
** Child_policy interface **
|
|
|
|
****************************/
|
|
|
|
|
2016-11-23 16:07:49 +00:00
|
|
|
Name name() const override { return _label; }
|
|
|
|
Binary_name binary_name() const override { return _binary_name; }
|
2014-10-02 12:47:08 +00:00
|
|
|
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 19:35:43 +00:00
|
|
|
Genode::Pd_session_capability ref_pd_cap() const override { return _ref_pd_cap; }
|
|
|
|
Genode::Pd_session &ref_pd() override { return _ref_pd; }
|
|
|
|
|
|
|
|
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);
|
2017-05-11 18:03:28 +00:00
|
|
|
_ref_pd.transfer_quota(cap, Genode::Ram_quota{_ram_quota});
|
2016-11-06 13:27:26 +00:00
|
|
|
}
|
2014-10-02 12:47:08 +00:00
|
|
|
|
2016-11-06 13:27:26 +00:00
|
|
|
Genode::Service &resolve_session_request(Genode::Service::Name const &name,
|
|
|
|
Genode::Session_state::Args const &args) override
|
|
|
|
{
|
|
|
|
Genode::Service *service = nullptr;
|
2014-10-02 12:47:08 +00:00
|
|
|
|
|
|
|
/* check for config file request */
|
2016-11-06 13:27:26 +00:00
|
|
|
if ((service = _config_policy.resolve_session_request(name.string(), args.string())))
|
|
|
|
return *service;
|
|
|
|
|
|
|
|
/* populate session-local parent service registry on demand */
|
|
|
|
_parent_services.for_each([&] (Parent_service &s) {
|
|
|
|
if (s.name() == name)
|
|
|
|
service = &s; });
|
|
|
|
|
|
|
|
if (service)
|
|
|
|
return *service;
|
2014-10-02 12:47:08 +00:00
|
|
|
|
2017-02-17 09:53:59 +00:00
|
|
|
return *new (_alloc) Parent_service(_parent_services, name);
|
2014-10-02 12:47:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void yield_response()
|
|
|
|
{
|
|
|
|
if (_withdraw_on_yield_response) {
|
|
|
|
enum { RESERVE = 4*1024*1024 };
|
|
|
|
|
2017-05-07 23:33:40 +00:00
|
|
|
size_t amount = _child.ram().avail_ram().value < RESERVE
|
|
|
|
? 0 : _child.ram().avail_ram().value - RESERVE;
|
2014-10-02 12:47:08 +00:00
|
|
|
|
|
|
|
/* try to immediately withdraw freed-up resources */
|
|
|
|
try { withdraw_ram_quota(amount); }
|
|
|
|
catch (Ram::Transfer_quota_failed) { }
|
|
|
|
}
|
|
|
|
|
|
|
|
/* propagate yield-response signal */
|
|
|
|
Genode::Signal_transmitter(_yield_response_sigh_cap).submit();
|
|
|
|
}
|
|
|
|
|
|
|
|
void resource_request(Genode::Parent::Resource_args const &args)
|
|
|
|
{
|
|
|
|
_resource_args = args;
|
|
|
|
try_response_to_resource_request();
|
|
|
|
}
|
2015-09-15 13:37:42 +00:00
|
|
|
|
|
|
|
void exit(int exit_value) override
|
|
|
|
{
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
Genode::log("subsystem \"", name(), "\" exited with value ", exit_value);
|
2015-09-15 13:37:42 +00:00
|
|
|
_exited = true;
|
|
|
|
|
|
|
|
/* trigger destruction of the child */
|
|
|
|
Genode::Signal_transmitter(_exit_sig_cap).submit();
|
|
|
|
}
|
2014-10-02 12:47:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* _INCLUDE__CLI_MONITOR__CHILD_H_ */
|