base: split Pd_account from Pd_session

Core uses an instance of 'Pd_session_component' as a representative
for RAM/cap quota accounts used whenever session resources are
donated to core's services. All other facets of 'Pd_sesson_component'
remain unused. Core's instance of 'Pd_session_component' is hosted
at 'Core_env'. Upon its construction, all unused facets of
'Pd_session_component' are initialized by dummy arguments in 'Core_env'.

To overcome the need for dummy arguments, this patch splits the
accounting part of the PD-session interface into a separate
'Pd_account' interface. This gives us the prospect of narrowing
core's current use of 'Pd_session_component' by 'Pd_account',
alleviating dead code and the need for any dummy arguments.

Issue #5408
This commit is contained in:
Norman Feske 2024-12-16 15:49:24 +01:00
parent 404e21017a
commit 4aabe39e36
18 changed files with 131 additions and 166 deletions

View File

@ -118,18 +118,18 @@ struct Genode::Child_policy
}
/**
* Reference PD session
* Reference PD-sesson account
*
* The PD session returned by this method is used for session cap-quota
* The PD account returned by this method is used for session cap-quota
* and RAM-quota transfers.
*/
virtual Pd_session &ref_pd() = 0;
virtual Pd_session_capability ref_pd_cap() const = 0;
virtual Pd_account &ref_account() = 0;
virtual Capability<Pd_account> ref_account_cap() const = 0;
/**
* RAM allocator used as backing store for '_session_md_alloc'
*/
virtual Ram_allocator &session_md_ram() { return ref_pd(); }
virtual Ram_allocator &session_md_ram() = 0;
/**
* Respond to the release of resources by the child
@ -459,10 +459,10 @@ class Genode::Child : protected Rpc_object<Parent>,
Cap_quota const cap_quota { CONNECTION::CAP_QUOTA };
if (cap(ram_quota).valid())
_child._policy.ref_pd().transfer_quota(cap(ram_quota), ram_quota);
_child._policy.ref_account().transfer_quota(cap(ram_quota), ram_quota);
if (cap(cap_quota).valid())
_child._policy.ref_pd().transfer_quota(cap(cap_quota), cap_quota);
_child._policy.ref_account().transfer_quota(cap(cap_quota), cap_quota);
_first_request = false;
}
@ -489,13 +489,12 @@ class Genode::Child : protected Rpc_object<Parent>,
_child._try_construct_env_dependent_members();
}
using Transfer_ram_quota_result = Pd_session::Transfer_ram_quota_result;
using Transfer_cap_quota_result = Pd_session::Transfer_ram_quota_result;
using Transfer_result = Pd_session::Transfer_result;
/**
* Service (Ram_transfer::Account) interface
*/
Ram_transfer_result transfer(Pd_session_capability to, Ram_quota amount) override
Transfer_result transfer(Capability<Pd_account> to, Ram_quota amount) override
{
Ram_transfer::Account &from = _service;
return from.transfer(to, amount);
@ -504,7 +503,7 @@ class Genode::Child : protected Rpc_object<Parent>,
/**
* Service (Ram_transfer::Account) interface
*/
Pd_session_capability cap(Ram_quota) const override
Capability<Pd_account> cap(Ram_quota) const override
{
Ram_transfer::Account &to = _service;
return to.cap(Ram_quota());
@ -513,7 +512,7 @@ class Genode::Child : protected Rpc_object<Parent>,
/**
* Service (Cap_transfer::Account) interface
*/
Cap_transfer_result transfer(Pd_session_capability to, Cap_quota amount) override
Transfer_result transfer(Capability<Pd_account> to, Cap_quota amount) override
{
Cap_transfer::Account &from = _service;
return from.transfer(to, amount);
@ -522,7 +521,7 @@ class Genode::Child : protected Rpc_object<Parent>,
/**
* Service (Cap_transfer::Account) interface
*/
Pd_session_capability cap(Cap_quota) const override
Capability<Pd_account> cap(Cap_quota) const override
{
Cap_transfer::Account &to = _service;
return to.cap(Cap_quota());

View File

@ -21,8 +21,8 @@ namespace Genode {
template <typename SESSION, typename UNIT, typename RESULT> class Quota_transfer;
using Ram_transfer = Quota_transfer<Pd_session, Ram_quota, Pd_session::Transfer_ram_quota_result>;
using Cap_transfer = Quota_transfer<Pd_session, Cap_quota, Pd_session::Transfer_cap_quota_result>;
using Ram_transfer = Quota_transfer<Pd_account, Ram_quota, Pd_account::Transfer_result>;
using Cap_transfer = Quota_transfer<Pd_account, Cap_quota, Pd_account::Transfer_result>;
}
@ -107,9 +107,6 @@ class Genode::Quota_transfer
Account &_from;
Account &_to;
static bool _exceeded(Ram_quota, RESULT r) { return (r == RESULT::OUT_OF_RAM); }
static bool _exceeded(Cap_quota, RESULT r) { return (r == RESULT::OUT_OF_CAPS); }
public:
class Quota_exceeded : Exception { };
@ -129,7 +126,7 @@ class Genode::Quota_transfer
if (!_from.cap(UNIT()).valid() || !_to.cap(UNIT()).valid())
return;
if (_exceeded(UNIT{}, _from.transfer(_to.cap(UNIT()), amount)))
if (_from.transfer(_to.cap(UNIT()), amount) == RESULT::EXCEEDED)
throw Quota_exceeded();
}

View File

@ -476,7 +476,7 @@ class Genode::Child_service : public Async_service
/**
* Ram_transfer::Account interface
*/
Ram_transfer_result transfer(Pd_session_capability to, Ram_quota amount) override
Ram_transfer_result transfer(Capability<Pd_account> to, Ram_quota amount) override
{
return to.valid() ? _pd.transfer_quota(to, amount)
: Ram_transfer_result::OK;
@ -485,12 +485,12 @@ class Genode::Child_service : public Async_service
/**
* Ram_transfer::Account interface
*/
Pd_session_capability cap(Ram_quota) const override { return _pd.rpc_cap(); }
Capability<Pd_account> cap(Ram_quota) const override { return _pd.rpc_cap(); }
/**
* Cap_transfer::Account interface
*/
Cap_transfer_result transfer(Pd_session_capability to, Cap_quota amount) override
Cap_transfer_result transfer(Capability<Pd_account> to, Cap_quota amount) override
{
return to.valid() ? _pd.transfer_quota(to, amount)
: Cap_transfer_result::OK;
@ -499,7 +499,7 @@ class Genode::Child_service : public Async_service
/**
* Cap_transfer::Account interface
*/
Pd_session_capability cap(Cap_quota) const override { return _pd.rpc_cap(); }
Capability<Pd_account> cap(Cap_quota) const override { return _pd.rpc_cap(); }
};
#endif /* _INCLUDE__BASE__SERVICE_H_ */

View File

@ -64,11 +64,10 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
Capability<Region_map> linker_area() override {
return call<Rpc_linker_area>(); }
Ref_account_result ref_account(Capability<Pd_session> pd) override {
Ref_account_result ref_account(Capability<Pd_account> pd) override {
return call<Rpc_ref_account>(pd); }
Transfer_cap_quota_result transfer_quota(Capability<Pd_session> pd,
Cap_quota amount) override
Transfer_result transfer_quota(Capability<Pd_account> pd, Cap_quota amount) override
{
return call<Rpc_transfer_cap_quota>(pd, amount);
}
@ -88,10 +87,9 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
return ds.valid() ? Dataspace_client(ds).size() : 0;
}
Transfer_ram_quota_result transfer_quota(Pd_session_capability pd_session,
Ram_quota amount) override
Transfer_result transfer_quota(Capability<Pd_account> pd, Ram_quota amount) override
{
return call<Rpc_transfer_ram_quota>(pd_session, amount);
return call<Rpc_transfer_ram_quota>(pd, amount);
}
Ram_quota ram_quota() const override { return call<Rpc_ram_quota>(); }

View File

@ -23,6 +23,7 @@
#include <base/ram_allocator.h>
namespace Genode {
struct Pd_account;
struct Pd_session;
struct Pd_session_client;
struct Parent;
@ -30,7 +31,22 @@ namespace Genode {
}
struct Genode::Pd_session : Session, Ram_allocator
struct Genode::Pd_account : Interface, Noncopyable
{
enum class Transfer_result { OK, EXCEEDED, INVALID };
virtual Transfer_result transfer_quota(Capability<Pd_account>, Cap_quota) = 0;
virtual Transfer_result transfer_quota(Capability<Pd_account>, Ram_quota) = 0;
GENODE_RPC(Rpc_transfer_cap_quota, Transfer_result, transfer_quota,
Capability<Pd_account>, Cap_quota);
GENODE_RPC(Rpc_transfer_ram_quota, Transfer_result, transfer_quota,
Capability<Pd_account>, Ram_quota);
GENODE_RPC_INTERFACE(Rpc_transfer_ram_quota, Rpc_transfer_cap_quota);
};
struct Genode::Pd_session : Session, Pd_account, Ram_allocator
{
/**
* \noapi
@ -200,21 +216,7 @@ struct Genode::Pd_session : Session, Ram_allocator
/**
* Define reference account for the PD session
*/
virtual Ref_account_result ref_account(Capability<Pd_session>) = 0;
enum class Transfer_cap_quota_result { OK, OUT_OF_CAPS, INVALID_SESSION, NO_REF_ACCOUNT };
/**
* Transfer capability quota to another PD session
*
* \param to receiver of quota donation
* \param amount amount of quota to donate
*
* Quota can only be transfered if the specified PD session is either the
* reference account for this session or vice versa.
*/
virtual Transfer_cap_quota_result transfer_quota(Capability<Pd_session> to,
Cap_quota amount) = 0;
virtual Ref_account_result ref_account(Capability<Pd_account>) = 0;
/**
* Return current capability-quota limit
@ -244,20 +246,6 @@ struct Genode::Pd_session : Session, Ram_allocator
* which comprises the actual allocation and deallocation operations.
*/
enum class Transfer_ram_quota_result { OK, OUT_OF_RAM, INVALID_SESSION, NO_REF_ACCOUNT };
/**
* Transfer quota to another RAM session
*
* \param to receiver of quota donation
* \param amount amount of quota to donate
*
* Quota can only be transfered if the specified PD session is either the
* reference account for this session or vice versa.
*/
virtual Transfer_ram_quota_result transfer_quota(Capability<Pd_session> to,
Ram_quota amount) = 0;
/**
* Return current quota limit
*/
@ -364,15 +352,11 @@ struct Genode::Pd_session : Session, Ram_allocator
GENODE_RPC(Rpc_address_space, Capability<Region_map>, address_space);
GENODE_RPC(Rpc_stack_area, Capability<Region_map>, stack_area);
GENODE_RPC(Rpc_linker_area, Capability<Region_map>, linker_area);
GENODE_RPC(Rpc_ref_account, Ref_account_result, ref_account, Capability<Pd_session>);
GENODE_RPC(Rpc_transfer_cap_quota, Transfer_cap_quota_result, transfer_quota,
Capability<Pd_session>, Cap_quota);
GENODE_RPC(Rpc_ref_account, Ref_account_result, ref_account, Capability<Pd_account>);
GENODE_RPC(Rpc_cap_quota, Cap_quota, cap_quota);
GENODE_RPC(Rpc_used_caps, Cap_quota, used_caps);
GENODE_RPC(Rpc_try_alloc, Alloc_result, try_alloc, size_t, Cache);
GENODE_RPC(Rpc_free, void, free, Ram_dataspace_capability);
GENODE_RPC(Rpc_transfer_ram_quota, Transfer_ram_quota_result, transfer_quota,
Capability<Pd_session>, Ram_quota);
GENODE_RPC(Rpc_ram_quota, Ram_quota, ram_quota);
GENODE_RPC(Rpc_used_ram, Ram_quota, used_ram);
GENODE_RPC(Rpc_native_pd, Capability<Native_pd>, native_pd);
@ -382,16 +366,16 @@ struct Genode::Pd_session : Session, Ram_allocator
GENODE_RPC(Rpc_attach_dma, Attach_dma_result, attach_dma,
Dataspace_capability, addr_t);
GENODE_RPC_INTERFACE(Rpc_assign_parent, Rpc_assign_pci, Rpc_map,
Rpc_signal_source, Rpc_free_signal_source,
Rpc_alloc_context, Rpc_free_context, Rpc_submit,
Rpc_alloc_rpc_cap, Rpc_free_rpc_cap, Rpc_address_space,
Rpc_stack_area, Rpc_linker_area, Rpc_ref_account,
Rpc_transfer_cap_quota, Rpc_cap_quota, Rpc_used_caps,
Rpc_try_alloc, Rpc_free,
Rpc_transfer_ram_quota, Rpc_ram_quota, Rpc_used_ram,
Rpc_native_pd, Rpc_system_control_cap,
Rpc_dma_addr, Rpc_attach_dma);
GENODE_RPC_INTERFACE_INHERIT(Pd_account,
Rpc_assign_parent, Rpc_assign_pci, Rpc_map,
Rpc_signal_source, Rpc_free_signal_source,
Rpc_alloc_context, Rpc_free_context, Rpc_submit,
Rpc_alloc_rpc_cap, Rpc_free_rpc_cap, Rpc_address_space,
Rpc_stack_area, Rpc_linker_area, Rpc_ref_account,
Rpc_cap_quota, Rpc_used_caps, Rpc_try_alloc, Rpc_free,
Rpc_ram_quota, Rpc_used_ram,
Rpc_native_pd, Rpc_system_control_cap,
Rpc_dma_addr, Rpc_attach_dma);
};
#endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */

View File

@ -16,6 +16,7 @@
#include <base/registry.h>
#include <base/quota_guard.h>
#include <pd_session/pd_session.h>
/* core includes */
#include <types.h>
@ -132,33 +133,33 @@ class Core::Account
_ref_account->_adopt(orphan); });
}
using Transfer_result = Pd_account::Transfer_result;
/**
* Transfer quota to/from other account
*
* \throw Unrelated_account
* \throw Limit_exceeded
*/
void transfer_quota(Account &other, UNIT amount)
[[nodiscard]] Transfer_result transfer_quota(Account &other, UNIT amount)
{
{
Mutex::Guard guard(_mutex);
/* transfers are permitted only from/to the reference account */
if (_ref_account != &other && other._ref_account != this)
throw Unrelated_account();
return Transfer_result::INVALID;
/* make sure to stay within the initial limit */
if (amount.value > _transferrable_quota().value)
throw Limit_exceeded();
return Transfer_result::EXCEEDED;
/* downgrade from this account */
if (!_quota_guard.try_downgrade(amount))
throw Limit_exceeded();
return Transfer_result::EXCEEDED;
}
/* credit to 'other' */
Mutex::Guard guard(other._mutex);
other._quota_guard.upgrade(amount);
return Transfer_result::OK;
}
UNIT limit() const

View File

@ -308,10 +308,10 @@ class Core::Pd_session_component : public Session_object<Pd_session>
** Capability and RAM trading and accounting **
***********************************************/
Ref_account_result ref_account(Capability<Pd_session>) override;
Ref_account_result ref_account(Capability<Pd_account>) override;
Transfer_cap_quota_result transfer_quota(Capability<Pd_session>, Cap_quota) override;
Transfer_ram_quota_result transfer_quota(Capability<Pd_session>, Ram_quota) override;
Transfer_result transfer_quota(Capability<Pd_account>, Cap_quota) override;
Transfer_result transfer_quota(Capability<Pd_account>, Ram_quota) override;
Cap_quota cap_quota() const override
{

View File

@ -182,8 +182,10 @@ class Core_child : public Child_policy
_core_cpu.transfer_quota(cap, Cpu_session::quota_lim_upscale(100, 100));
}
Pd_session &ref_pd() override { return _core_pd; }
Pd_session_capability ref_pd_cap() const override { return _core_pd_cap; }
Ram_allocator &session_md_ram() override { return _core_pd; }
Pd_account &ref_account() override { return _core_pd; }
Capability<Pd_account> ref_account_cap() const override { return _core_pd_cap; }
size_t session_alloc_batch_size() const override { return 128; }

View File

@ -100,7 +100,7 @@ size_t Pd_session_component::dataspace_size(Ram_dataspace_capability ds_cap) con
}
Pd_session::Ref_account_result Pd_session_component::ref_account(Capability<Pd_session> pd_cap)
Pd_session::Ref_account_result Pd_session_component::ref_account(Capability<Pd_account> pd_cap)
{
/* the reference account can be defined only once */
if (_cap_account.constructed())
@ -125,63 +125,41 @@ Pd_session::Ref_account_result Pd_session_component::ref_account(Capability<Pd_s
}
Pd_session::Transfer_cap_quota_result
Pd_session_component::transfer_quota(Capability<Pd_session> pd_cap, Cap_quota amount)
Pd_session::Transfer_result
Pd_session_component::transfer_quota(Capability<Pd_account> pd_cap, Cap_quota amount)
{
if (!_cap_account.constructed())
return Transfer_cap_quota_result::NO_REF_ACCOUNT;
if (this->cap() == pd_cap)
return Transfer_cap_quota_result::OK;
return Transfer_result::OK;
Transfer_cap_quota_result result = Transfer_cap_quota_result::INVALID_SESSION;
return _ep.apply(pd_cap, [&] (Pd_session_component *pd) {
_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
if (!pd || !pd->_cap_account.constructed() || !_cap_account.constructed())
return Transfer_result::INVALID;
if (!pd || !pd->_cap_account.constructed())
return;
Transfer_result const result = _cap_account->transfer_quota(*pd->_cap_account, amount);
try {
_cap_account->transfer_quota(*pd->_cap_account, amount);
if (result == Transfer_result::OK)
diag("transferred ", amount, " caps "
"to '", pd->_cap_account->label(), "' (", _cap_account, ")");
result = Transfer_cap_quota_result::OK;
}
catch (Account<Cap_quota>::Unrelated_account) { }
catch (Account<Cap_quota>::Limit_exceeded) {
result = Transfer_cap_quota_result::OUT_OF_CAPS;
}
return result;
});
return result;
}
Pd_session::Transfer_ram_quota_result
Pd_session_component::transfer_quota(Capability<Pd_session> pd_cap, Ram_quota amount)
Pd_session::Transfer_result
Pd_session_component::transfer_quota(Capability<Pd_account> pd_cap, Ram_quota amount)
{
if (!_ram_account.constructed())
return Transfer_ram_quota_result::NO_REF_ACCOUNT;
if (this->cap() == pd_cap)
return Transfer_ram_quota_result::OK;
return Transfer_result::OK;
Transfer_ram_quota_result result = Transfer_ram_quota_result::INVALID_SESSION;
return _ep.apply(pd_cap, [&] (Pd_session_component *pd) {
_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
if (!pd || !pd->_ram_account.constructed() || !_ram_account.constructed())
return Transfer_result::INVALID;
if (!pd || !pd->_ram_account.constructed())
return;
try {
_ram_account->transfer_quota(*pd->_ram_account, amount);
result = Transfer_ram_quota_result::OK;
}
catch (Account<Ram_quota>::Unrelated_account) { }
catch (Account<Ram_quota>::Limit_exceeded) {
result = Transfer_ram_quota_result::OUT_OF_RAM;
}
return _ram_account->transfer_quota(*pd->_ram_account, amount);
});
return result;
}

View File

@ -83,26 +83,26 @@ struct Genode::Expanding_pd_session_client : Pd_session_client
}
}
Transfer_ram_quota_result transfer_quota(Pd_session_capability pd_session, Ram_quota amount) override
Transfer_result transfer_quota(Capability<Pd_account> to, Ram_quota amount) override
{
/*
* Should the transfer fail because we don't have enough quota, request
* the needed amount from the parent.
*/
for (;;) {
auto const result = Pd_session_client::transfer_quota(pd_session, amount);
if (result != Transfer_ram_quota_result::OUT_OF_RAM)
auto const result = Pd_session_client::transfer_quota(to, amount);
if (result != Transfer_result::EXCEEDED)
return result;
_request_ram_from_parent(amount.value);
}
}
Transfer_cap_quota_result transfer_quota(Pd_session_capability pd_session, Cap_quota amount) override
Transfer_result transfer_quota(Capability<Pd_account> to, Cap_quota amount) override
{
for (;;) {
auto const result = Pd_session_client::transfer_quota(pd_session, amount);
if (result != Transfer_cap_quota_result::OUT_OF_CAPS)
auto const result = Pd_session_client::transfer_quota(to, amount);
if (result != Transfer_result::EXCEEDED)
return result;
_request_caps_from_parent(amount.value);

View File

@ -195,8 +195,8 @@ Parent::Session_result Child::session(Parent::Client::Id id,
session.closed_callback = this;
try {
Ram_transfer::Remote_account ref_ram_account { _policy.ref_pd(), _policy.ref_pd_cap() };
Cap_transfer::Remote_account ref_cap_account { _policy.ref_pd(), _policy.ref_pd_cap() };
Ram_transfer::Remote_account ref_ram_account { _policy.ref_account(), _policy.ref_account_cap() };
Cap_transfer::Remote_account ref_cap_account { _policy.ref_account(), _policy.ref_account_cap() };
Ram_transfer::Remote_account ram_account { pd(), pd_session_cap() };
Cap_transfer::Remote_account cap_account { pd(), pd_session_cap() };
@ -342,8 +342,8 @@ Parent::Upgrade_result Child::upgrade(Client::Id id, Parent::Upgrade_args const
Arg_string::find_arg(args.string(), "cap_quota").ulong_value(0) };
try {
Ram_transfer::Remote_account ref_ram_account { _policy.ref_pd(), _policy.ref_pd_cap() };
Cap_transfer::Remote_account ref_cap_account { _policy.ref_pd(), _policy.ref_pd_cap() };
Ram_transfer::Remote_account ref_ram_account { _policy.ref_account(), _policy.ref_account_cap() };
Cap_transfer::Remote_account ref_cap_account { _policy.ref_account(), _policy.ref_account_cap() };
Ram_transfer::Remote_account ram_account { pd(), pd_session_cap() };
Cap_transfer::Remote_account cap_account { pd(), pd_session_cap() };
@ -397,11 +397,11 @@ Parent::Upgrade_result Child::upgrade(Client::Id id, Parent::Upgrade_args const
void Child::_revert_quota_and_destroy(Session_state &session)
{
Ram_transfer::Remote_account ref_ram_account(_policy.ref_pd(), _policy.ref_pd_cap());
Ram_transfer::Remote_account ref_ram_account(_policy.ref_account(), _policy.ref_account_cap());
Ram_transfer::Account &service_ram_account = session.service();
Ram_transfer::Remote_account child_ram_account(pd(), pd_session_cap());
Cap_transfer::Remote_account ref_cap_account(_policy.ref_pd(), _policy.ref_pd_cap());
Cap_transfer::Remote_account ref_cap_account(_policy.ref_account(), _policy.ref_account_cap());
Cap_transfer::Account &service_cap_account = session.service();
Cap_transfer::Remote_account child_cap_account(pd(), pd_session_cap());
@ -544,10 +544,10 @@ void Child::session_response(Server::Id id, Session_response response)
* withdraw the session quota from the server ('this') to
* the reference account, and destroy the session object.
*/
Ram_transfer::Remote_account ref_ram_account(_policy.ref_pd(), _policy.ref_pd_cap());
Ram_transfer::Remote_account ref_ram_account(_policy.ref_account(), _policy.ref_account_cap());
Ram_transfer::Account &service_ram_account = session.service();
Cap_transfer::Remote_account ref_cap_account(_policy.ref_pd(), _policy.ref_pd_cap());
Cap_transfer::Remote_account ref_cap_account(_policy.ref_account(), _policy.ref_account_cap());
Cap_transfer::Account &service_cap_account = session.service();
try {

View File

@ -464,8 +464,10 @@ struct Libc::Forked_child : Child_policy, Child_ready
Binary_name binary_name() const override { return _binary_name; }
Pd_session &ref_pd() override { return _env.pd(); }
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
Ram_allocator &session_md_ram() override { return _env.ram(); }
Pd_account &ref_account() override { return _env.pd(); }
Capability<Pd_account> ref_account_cap() const override { return _env.pd_session_cap(); }
void init(Pd_session &session, Pd_session_capability cap) override
{

View File

@ -108,14 +108,16 @@ class Shim::Main : public Child_policy
Binary_name binary_name() const override { return "binary"; }
Pd_session &ref_pd() override { return _env.pd(); }
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
Ram_allocator &session_md_ram() override { return _env.ram(); }
Pd_account &ref_account() override { return _env.pd(); }
Capability<Pd_account> ref_account_cap() const override { return _env.pd_session_cap(); }
void init(Pd_session &pd, Pd_session_capability pd_cap) override
{
pd.ref_account(ref_pd_cap());
ref_pd().transfer_quota(pd_cap, _cap_quota);
ref_pd().transfer_quota(pd_cap, _ram_quota);
pd.ref_account(_env.pd_session_cap());
ref_account().transfer_quota(pd_cap, _cap_quota);
ref_account().transfer_quota(pd_cap, _ram_quota);
}
Route resolve_session_request(Service::Name const &name,

View File

@ -247,7 +247,7 @@ void Sandbox::Child::_apply_resource_upgrade(QUOTA &assigned, QUOTA const config
assigned.value += transfer.value;
ref_pd().transfer_quota(_child.pd_session_cap(), transfer);
ref_account().transfer_quota(_child.pd_session_cap(), transfer);
/* wake up child that blocks on a resource request */
if (_requested_resources.constructed()) {
@ -304,7 +304,7 @@ void Sandbox::Child::_apply_resource_downgrade(QUOTA &assigned, QUOTA const conf
QUOTA const transfer { min(avail - preserved.value, decrement.value) };
try {
_child.pd().transfer_quota(ref_pd_cap(), transfer);
_child.pd().transfer_quota(ref_account_cap(), transfer);
assigned.value -= transfer.value;
break;
} catch (...) { }

View File

@ -715,15 +715,15 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
Child_policy::Name name() const override { return _unique_name; }
Pd_session &ref_pd() override
Pd_account &ref_account() override
{
Pd_session *_ref_pd_ptr = nullptr;
Pd_account *_ref_account_ptr = nullptr;
_with_pd_intrinsics([&] (Pd_intrinsics::Intrinsics &intrinsics) {
_ref_pd_ptr = &intrinsics.ref_pd; });
return *_ref_pd_ptr;
_ref_account_ptr = &intrinsics.ref_pd; });
return *_ref_account_ptr;
}
Pd_session_capability ref_pd_cap() const override { return _ref_pd_cap; }
Capability<Pd_account> ref_account_cap() const override { return _ref_pd_cap; }
Ram_allocator &session_md_ram() override { return _env.ram(); }

View File

@ -118,7 +118,7 @@ class Sandbox::Routed_service : public Async_service, public Abandonable
/**
* Ram_transfer::Account interface
*/
Ram_transfer_result transfer(Pd_session_capability to, Ram_quota amount) override
Ram_transfer_result transfer(Capability<Pd_account> to, Ram_quota amount) override
{
return to.valid() ? _pd_accessor.pd().transfer_quota(to, amount)
: Ram_transfer_result::OK;
@ -127,7 +127,7 @@ class Sandbox::Routed_service : public Async_service, public Abandonable
/**
* Ram_transfer::Account interface
*/
Pd_session_capability cap(Ram_quota) const override
Capability<Pd_account> cap(Ram_quota) const override
{
return _pd_accessor.pd_cap();
}
@ -135,7 +135,7 @@ class Sandbox::Routed_service : public Async_service, public Abandonable
/**
* Cap_transfer::Account interface
*/
Cap_transfer_result transfer(Pd_session_capability to, Cap_quota amount) override
Cap_transfer_result transfer(Capability<Pd_account> to, Cap_quota amount) override
{
return to.valid() ? _pd_accessor.pd().transfer_quota(to, amount)
: Cap_transfer_result::OK;
@ -144,7 +144,7 @@ class Sandbox::Routed_service : public Async_service, public Abandonable
/**
* Cap_transfer::Account interface
*/
Pd_session_capability cap(Cap_quota) const override
Capability<Pd_account> cap(Cap_quota) const override
{
return _pd_accessor.pd_cap();
}

View File

@ -55,27 +55,27 @@ struct Monitor::Monitored_pd_session : Monitored_rpc_object<Pd_session>
return result;
}
Transfer_cap_quota_result transfer_quota(Capability<Pd_session> pd_cap,
Transfer_cap_quota_result transfer_quota(Capability<Pd_account> to,
Cap_quota amount) override
{
Transfer_cap_quota_result result = Transfer_cap_quota_result::INVALID_SESSION;
_with_pd_arg(pd_cap,
_with_pd_arg(static_cap_cast<Pd_session>(to),
[&] (Monitored_pd_session &pd) {
result = _real.call<Rpc_transfer_cap_quota>(pd._real, amount); },
[&] {
result = _real.call<Rpc_transfer_cap_quota>(pd_cap, amount); });
result = _real.call<Rpc_transfer_cap_quota>(to, amount); });
return result;
}
Transfer_ram_quota_result transfer_quota(Pd_session_capability pd_cap,
Transfer_ram_quota_result transfer_quota(Capability<Pd_account> to,
Ram_quota amount) override
{
Transfer_ram_quota_result result = Transfer_ram_quota_result::INVALID_SESSION;
_with_pd_arg(pd_cap,
_with_pd_arg(static_cap_cast<Pd_session>(to),
[&] (Monitored_pd_session &pd) {
result = _real.call<Rpc_transfer_ram_quota>(pd._real, amount); },
[&] {
result = _real.call<Rpc_transfer_ram_quota>(pd_cap, amount); });
result = _real.call<Rpc_transfer_ram_quota>(to, amount); });
return result;
}
};

View File

@ -80,8 +80,10 @@ class Bomb_child : public Child_policy
_env.pd().transfer_quota(pd_cap, _ram_quota);
}
Pd_session &ref_pd() override { return _env.pd(); }
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
Ram_allocator &session_md_ram() override { return _env.ram(); }
Pd_account &ref_account() override { return _env.pd(); }
Capability<Pd_account> ref_account_cap() const override { return _env.pd_session_cap(); }
Service &_matching_service(Service::Name const &service_name,
Session_label const &label)