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,28 +31,40 @@ 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;
_pd.attach_dma(ds_cap, dma_addr).with_result( bool retry = false;
[&] (Pd_session::Attach_dma_ok) { do {
_pd.attach_dma(ds_cap, dma_addr).with_result(
page = dma_addr; [&] (Pd_session::Attach_dma_ok) {
/* trigger eager mapping of memory */
_pd.map(page, size);
},
[&] (Attach_dma_error e) {
switch (e) {
case Attach_dma_error::OUT_OF_RAM: throw Out_of_ram();
case Attach_dma_error::OUT_OF_CAPS: throw Out_of_caps();
case Attach_dma_error::DENIED:
warning("Pd_session::attach_dma denied");
page = dma_addr; page = dma_addr;
break;
/* trigger eager mapping of memory */
_pd.map(page, size);
retry = false;
},
[&] (Attach_dma_error e) {
switch (e) {
case Attach_dma_error::OUT_OF_RAM:
_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:
warning("Pd_session::attach_dma denied");
page = dma_addr;
retry = false;
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);
} }
); );
}, },
[&] () { [&] () {
enum { UPGRADE_RAM_QUOTA = 4096 }; upgrade_ram();
Ram_quota const ram { UPGRADE_RAM_QUOTA };
_ram_guard.withdraw(ram);
_env.pd().transfer_quota(_pd.rpc_cap(), ram);
} }
); );
} }
Local_addr attach_at(Dataspace_capability ds, void upgrade_ram()
addr_t local_addr, {
size_t size = 0, enum { UPGRADE_RAM_QUOTA = 4096 };
off_t offset = 0) { Ram_quota const ram { UPGRADE_RAM_QUOTA };
return attach(ds, size, offset, true, local_addr); }; _ram_guard.withdraw(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);
}
} _address_space; } _address_space;
public: public: