legacy_platform_drv: update quotas on 'attach_dma_mem'

'Platform::Device_pd::attach_dma_mem' may lead to insufficient resources
for meta data, which is reflected to the client via 'Out_of_caps' or
'Out_of_ram'. In case the client upgrades its session the quotas need to
be passed to core as done by
'Platform::Device_pd::Expanding_region_map_client::attach'.

issue #4451
This commit is contained in:
Sebastian Sumpf 2022-04-05 14:26:34 +02:00 committed by Christian Helmuth
parent abc0bf3220
commit 7a06a6ac59
2 changed files with 43 additions and 28 deletions

View File

@ -31,9 +31,11 @@ void Platform::Device_pd::attach_dma_mem(Dataspace_capability ds_cap,
addr_t page = ~0UL; addr_t page = ~0UL;
using Attach_dma_error = Pd_session::Attach_dma_error; using Attach_dma_error = Pd_session::Attach_dma_error;
bool retry = false;
do {
_pd.attach_dma(ds_cap, dma_addr).with_result( _pd.attach_dma(ds_cap, dma_addr).with_result(
[&] (Pd_session::Attach_dma_ok) { [&] (Pd_session::Attach_dma_ok) {
@ -42,17 +44,27 @@ void Platform::Device_pd::attach_dma_mem(Dataspace_capability ds_cap,
/* trigger eager mapping of memory */ /* trigger eager mapping of memory */
_pd.map(page, size); _pd.map(page, size);
retry = false;
}, },
[&] (Attach_dma_error e) { [&] (Attach_dma_error e) {
switch (e) { switch (e) {
case Attach_dma_error::OUT_OF_RAM: throw Out_of_ram(); case Attach_dma_error::OUT_OF_RAM:
case Attach_dma_error::OUT_OF_CAPS: throw Out_of_caps(); _address_space.upgrade_ram();
retry = true;
break;
case Attach_dma_error::OUT_OF_CAPS:
_address_space.upgrade_caps();
retry = true;
break;
case Attach_dma_error::DENIED: case Attach_dma_error::DENIED:
warning("Pd_session::attach_dma denied"); warning("Pd_session::attach_dma denied");
page = dma_addr; page = dma_addr;
retry = false;
break; break;
} }
}); }
);
} while (retry);
/* sanity check */ /* sanity check */
if ((page == ~0UL) || (page != dma_addr)) { if ((page == ~0UL) || (page != dma_addr)) {

View File

@ -75,28 +75,31 @@ class Platform::Device_pd
executable, executable,
writeable); }, writeable); },
[&] () { [&] () {
enum { UPGRADE_CAP_QUOTA = 2 }; upgrade_caps();
Cap_quota const caps { UPGRADE_CAP_QUOTA };
_cap_guard.withdraw(caps);
_env.pd().transfer_quota(_pd.rpc_cap(), caps);
} }
); );
}, },
[&] () { [&] () {
upgrade_ram();
}
);
}
void upgrade_ram()
{
enum { UPGRADE_RAM_QUOTA = 4096 }; enum { UPGRADE_RAM_QUOTA = 4096 };
Ram_quota const ram { UPGRADE_RAM_QUOTA }; Ram_quota const ram { UPGRADE_RAM_QUOTA };
_ram_guard.withdraw(ram); _ram_guard.withdraw(ram);
_env.pd().transfer_quota(_pd.rpc_cap(), ram); _env.pd().transfer_quota(_pd.rpc_cap(), ram);
} }
);
void upgrade_caps()
{
enum { UPGRADE_CAP_QUOTA = 2 };
Cap_quota const caps { UPGRADE_CAP_QUOTA };
_cap_guard.withdraw(caps);
_env.pd().transfer_quota(_pd.rpc_cap(), caps);
} }
Local_addr attach_at(Dataspace_capability ds,
addr_t local_addr,
size_t size = 0,
off_t offset = 0) {
return attach(ds, size, offset, true, local_addr); };
} _address_space; } _address_space;
public: public: