platform/x86: fix quota for local ram session

Transfer quota to the session local RAM session to react to the
Quota_exceeded exception properly.

The platform driver keeps a session local RAM session for each of its
clients that is used to allocate DMA memory. A client needs to transfer
some of its quota to the platform driver, which in return transfers this
quota to the session local RAM session. As it happens allocating memory
from a RAM session involves book keeping and in this case, where the
available quota in the session did not suffice and the request was only
a few KiB, the platform driver handled the exception wrongly and did not
transfer the quota.

This problem did not surface up to now because all drivers allocate DMA
memory in larger chunks and the book keeping overhead was of no
consequence as the initial quota transfer probably covered the overhead.

Fixes #2316.
This commit is contained in:
Josef Söntgen 2017-03-09 13:23:40 +01:00 committed by Christian Helmuth
parent 62e605325e
commit bf96c7f16e

View File

@ -952,14 +952,26 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
[&] () {
Ram_capability ram = Genode::retry<Genode::Ram_session::Out_of_metadata>(
[&] () { return _ram.alloc(size, Genode::UNCACHED); },
[&] () { throw Genode::Ram_session::Quota_exceeded(); });
[&] () {
if (!_env_ram.withdraw(UPGRADE_QUOTA)) {
_rollback(size);
}
/* upgrade meta-data quota */
_ram.upgrade_ram(UPGRADE_QUOTA);
});
return ram;
},
[&] () {
if (!_env_ram.withdraw(UPGRADE_QUOTA))
_rollback(size);
_ram.upgrade_ram(UPGRADE_QUOTA);
/*
* This condition is mostly triggered when the session
* specific ram session is low on quota and it cannot
* process the request due to book-keeping overhead.
* It is therefore enough to increase the quota in
* UPGRADE_QUOTA steps.
*/
_env_ram.transfer_quota<Out_of_metadata>(_ram, UPGRADE_QUOTA);
});
if (!ram_cap.valid())