This patch changes init's service forwarding such that pending requests
are kept unanswered as long as the requested service is not present
(yet). In dynamic-init scenarios, this is needed in situtions where the
dynamic init is known to eventually provide the service but the internal
subsystem is not ready yet. Previously, a client that attempted to
request a session in this early phase would get a 'Service_denied'
exception. By deferring the forwarding in this situation, the behaviour
becomes deterministic.
If a matching '<service>' exists but there is no matching policy sub
node, the request is answered with 'Service_denied' - as expected.
If a child is allowed to constrain physical memory allocations but left
the 'phys_start' and 'phys_size' session arguments blank, init applies
builtin constraints for allocating DMA buffers.
The only component that makes use of the physical-memory constraint
feature is the platform driver. Since the built-in heuristics are
applied to the platform driver's environment RAM session, all
allocations performed by the platform driver satisfy the DMA
constraints.
To justify building-in these heuristics into init as opposed to
supplying the values as configuration arguments, the values differ
between 32 and 64 bit. The configuration approach would raise the need
to differentiate init configurations for both cases, which are
completely identical otherwise.
Issue #2407
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
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
This patch reworks the implementation of core's RAM service to make use
of the 'Session_object' and to remove the distinction between the
"metadata" quota and the managed RAM quota. With the new implementation,
the session implicitly allocates its metadata from its own account. So
there is not need to handle 'Out_of_metadata' and 'Quota_exceeded' via
different exceptions. Instead, the new version solely uses the
'Out_of_ram' exception.
Furthermore, the 'Allocator::Out_of_memory' exception has become an alias
for 'Out_of_ram', which simplifies the error handling.
Issue #2398
The 'diag' flag can be defined by a target node of a route in init's
configuration. It is propagated as session argument to the server, which
may evaluate the flag to enable diagnostic output for the corresponding
session.
Issue #2398
This patch makes use of the new 'Quota_transfer::Account' by the service
types in base/service.h and uses 'Quota_transfer' objects in
base/child.cc and init/server.cc.
Furthermore, it decouples the notion of an 'Async_service' from
'Child_service'. Init's 'Routed_service' is no longer a 'Child_service'
but is based on the new 'Async_service' instead.
With this patch in place, quota transfers do no longer implicitly use
'Ram_session_client' objects. So transfers can in principle originate
from component-local 'Ram_session_component' objects, e.g., as used by
noux. Therefore, this patch removes a strumbling block for turning noux
into a single threaded component in the future.
Issue #2398
This patch replaces the 'Parent::Quota_exceeded',
'Service::Quota_exceeded', and 'Root::Quota_exceeded' exceptions
by the single 'Insufficient_ram_quota' exception type.
Furthermore, the 'Parent' interface distinguished now between
'Out_of_ram' (the child's RAM is exhausted) from
'Insufficient_ram_quota' (the child's RAM donation does not suffice to
establish the session).
This eliminates ambiguities and removes the need to convert exception
types along the path of the session creation.
Issue #2398
This patch replaces the former use of size_t with the use of the
'Ram_quota' type to improve type safety (in particular to avoid
accidentally mixing up RAM quotas with cap quotas).
Issue #2398
This patch augments the existing session/session.h with useful types for
the session creation:
* The new 'Insufficient_ram_quota' and 'Insufficient_cap_quota'
exceptions are meant to supersede the old 'Quota_exceeded' exception
of the 'Parent' and 'Root' interfaces.
* The 'Session::Resources' struct subsumes the information about the
session quota provided by the client.
* The boolean 'Session::Diag' type will allow sessions to operate in a
diagnostic mode.
* The existing 'Session_label' is not also available under the alias
'Session::Label'.
* A few helper functions ease the extraction of typed session arguments
from the session-argument string.
Issue #2398
Init's service forwarding functionality did not take the service type
into account when forwarding a session request. If a server provides
multiple services, e.g. fb_sdl that provides both "Input" and
"Framebuffer", the type of the forwarded session request did not always
correspond to the actually requested type.
This patch equips init with the ability to act as a server that forwards
session requests to its children. Session requests can be routed
depending of the requested service type and the session label
originating from init's parent.
The feature is configured by one or multiple <service> nodes hosted in
init's <config> node. The routing policy is selected by via the regular
server-side policy-selection mechanism, for example:
<config>
...
<service name="LOG">
<policy label="noux">
<child name="terminal_log" label="important"/>
</policy>
<default-policy> <child name="nitlog"/> </default-policy>
</service>
...
</config>
Each policy node must have a <child> sub node, which denotes name of the
server with the 'name' attribute. The optional 'label' attribute defines
the session label presented to the server, analogous to how the
rewriting of session labels works in session routes. If not specified,
the client-provided label is presented to the server as is.
Fixes#2247
This patch removes the formerly built-in policy of responding to
resource requests with handing out slack quota. Instead, resource
requests have to be answered by an update of the init configuration with
adjusted quota values.
Note that this patch may break run scripts that depend on init's
original policy. Those run scripts may be adjusted by increasing the
quota for the components that use to inflate their RAM usage during
runtime such that the specified quota suffices for the entire lifetime
of the component.
This patch improves init's dynamic reconfigurability with respect to
adjustments of the RAM quota assigned to the children.
If the RAM quota is decreased, init withdraws as much quota from the
child's RAM session as possible. If the child's RAM session does not
have enough available quota, a resource-yield request is issued to
the child. Cooparative children may respond to such a request by
releasing memory.
If the RAM quota is increased, the child's RAM session is upgraded.
If the configuration exceeds init's available RAM, init re-attempts
the upgrade whenever new slack memory becomes available (e.g., by
disappearing other children).
This patch improves the accuracy of init's quota-saturation feature
(handing out all slack quota to a child by specifying an overly high RAM
quota for the child) and makes the RAM preserved by init configurable.
The preservation is specified as follows:
! <config>
! ...
! <resource name="RAM" preserve="1M"/>
! ...
! </config>
If not specified, init has a reasonable default of 160K (on 32 bit) and
320K (on 64 bit).
This patch lets init apply configuration changes to a running scenario
in a differential way. Children are restarted if any of their session
routes change, new children can be added to a running scenario, or
children can deliberately be removed.
Furthermore, the new version of init is able to propagate configuration
changes (modifications of <config> nodes) to its children without
restarting them.
This patch improves the accounting for the backing store of
session-state meta data. Originally, the session state used to be
allocated by a child-local heap partition fed from the child's RAM
session. However, whereas this approach was somehow practical from a
runtime's (parent's) point of view, the child component could not count
on the quota in its own RAM session. I.e., if the Child::heap grew at
the parent side, the child's RAM session would magically diminish. This
caused two problems. First, it violates assumptions of components like
init that carefully manage their RAM resources (and giving most of them
away their children). Second, if a child transfers most of its RAM
session quota to another RAM session (like init does), the child's RAM
session may actually not allow the parent's heap to grow, which is a
very difficult error condition to deal with.
In the new version, there is no Child::heap anymore. Instead, session
states are allocated from the runtime's RAM session. In order to let
children pay for these costs, the parent withdraws the local session
costs from the session quota donated from the child when the child
initiates a new session. Hence, in principle, all components on the
route of the session request take a small bite from the session quota to
pay for their local book keeping
Consequently, the session quota that ends up at the server may become
depleted more or less, depending on the route. In the case where the
remaining quota is insufficient for the server, the server responds with
'QUOTA_EXCEEDED'. Since this behavior must generally be expected, this
patch equips the client-side 'Env::session' implementation with the
ability to re-issue session requests with successively growing quota
donations.
For several of core's services (ROM, IO_MEM, IRQ), the default session
quota has now increased by 2 KiB, which should suffice for session
requests to up to 3 hops as is the common case for most run scripts. For
longer routes, the retry mechanism as described above comes into effect.
For the time being, we give a warning whenever the server-side quota
check triggers the retry mechanism. The warning may eventually be
removed at a later stage.
This patch equips init with the ability to report its internal state in
the form of a "state" report. This feature can be enabled by placing a
'<report>' node in init's configuration.
The report node accepts the following arguments (with their default
values):
'delay_ms="100"': specifies the number of milliseconds to wait before
producing a new report. This way, many consecutive state changes -
like they occur during the startup - do not result in an overly
large number of reports but are merged into one final report.
'buffer="4K"': the maximum size of the report in bytes. The attribute
accepts the use of K/M/G as units.
'init_ram="no"': if enabled, the report will contain a '<ram>' node
with the memory stats of init.
'ids="no"': supplement the children in the report with unique IDs, which
may be used to infer the lifetime of children accross configuration
updates in the future;
'requested="no"': if enabled, the report will contain information about
all session requests initiated by the children.
'provided="no"': if enabled, the report will contain information about
all sessions provided by all servers.
'session_args="no"': level of detail of the session information
generated via 'requested' or 'provided'.
'child_ram="no"': if enabled, the report will contain a '<ram>' node
for each child based on the information obtained from the child's RAM
session.
Issue #2246
This is a redesign of the root and parent interfaces to eliminate
blocking RPC calls.
- New session representation at the parent (base/session_state.h)
- base-internal root proxy mechanism as migration path
- Redesign of base/service.h
- Removes ancient 'Connection::KEEP_OPEN' feature
- Interface change of 'Child', 'Child_policy', 'Slave', 'Slave_policy'
- New 'Slave::Connection'
- Changed child-construction procedure to be compatible with the
non-blocking parent interface and to be easier to use
- The child's initial LOG session, its binary ROM session, and the
linker ROM session have become part of the child's envirenment.
- Session upgrading must now be performed via 'env.upgrade' instead
of performing a sole RPC call the parent. To make RAM upgrades
easier, the 'Connection' provides a new 'upgrade_ram' method.
Issue #2120
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
Replace 'attribute(...).has_value("yes")`
with 'attribute_value(..., false)'.
This allows for boolean configuration to be set with values such as
"true", "false", "yes", "no", or "1", "0".
Fixes#2002
This patch makes the former 'Process' class private to the 'Child'
class and changes the constructor of the 'Child' in a way that
principally enables the implementation of single-threaded runtime
environments that virtualize the CPU, PD, and RAM services. The
new interfaces has become free from side effects. I.e., instead
of implicitly using Genode::env()->rm_session(), it takes the reference
to the local region map as argument. Also, the handling of the dynamic
linker via global variables is gone. Now, the linker binary must be
provided as constructor argument.
Fixes#1949
When init destroys a child server with an open session, the client must
be updated as it will otherwise store a pointer to a no-more existing
service object which will be dereferenced when the child client is
destroyed.
Fixes#1912
Instead of holding SPEC-variable dependent files and directories inline
within the repository structure, move them into 'spec' subdirectories
at the corresponding levels, e.g.:
repos/base/include/spec
repos/base/mk/spec
repos/base/lib/mk/spec
repos/base/src/core/spec
...
Moreover, this commit removes the 'platform' directories. That term was
used in an overloaded sense. All SPEC-relative 'platform' directories are
now named 'spec'. Other files, like for instance those related to the
kernel/architecture specific startup library, where moved from 'platform'
directories to explicit, more meaningful places like e.g.: 'src/lib/startup'.
Fix#1673
If some sessions run out of memory in init, resource requests will be issued
to core, which it never will satisfy. Setting some default signal handler
avoids that the default implementation will block init for ever.
Issue #1632
This patch changes the top-level directory layout as a preparatory
step for improving the tools for managing 3rd-party source codes.
The rationale is described in the issue referenced below.
Issue #1082