platform_drv(arm): fix cap and memory leaks

* Track all caps and ram quotas of the sub-sessions properly
* Release DMA buffers, it is not done implicitely when destroying
  the Constrained_ram_allocator
* Do not replenish quota before really releasing memory from
  the allocator

Issue #4330
This commit is contained in:
Johannes Schlatow 2021-11-17 15:27:02 +01:00 committed by Christian Helmuth
parent e256969489
commit 916683b6d6
2 changed files with 14 additions and 9 deletions

View File

@ -51,9 +51,6 @@ void Driver::Device::release(Session_component & sc)
{
if (_session != sc.label()) { return; }
sc.replenish(Cap_quota{_cap_quota_required()});
sc.replenish(Ram_quota{_ram_quota_required()});
_io_mem_list.for_each([&] (Io_mem & io_mem) {
if (io_mem.io_mem) {
destroy(sc.heap(), io_mem.io_mem);
@ -69,6 +66,9 @@ void Driver::Device::release(Session_component & sc)
});
_session = Platform::Session::Label();;
sc.replenish(Cap_quota{_cap_quota_required()});
sc.replenish(Ram_quota{_ram_quota_required()});
}
@ -151,9 +151,12 @@ void Driver::Device::report(Xml_generator & xml, Session_component & sc)
Genode::size_t Driver::Device::_cap_quota_required()
{
size_t total = 0;
/* one cap is needed for the device component itself */
size_t total = 1;
_io_mem_list.for_each([&] (Io_mem &) {
total += Io_mem_session::CAP_QUOTA; });
_irq_list.for_each([&] (Irq &) {
total += Irq_session::CAP_QUOTA; });
return total;
}
@ -162,7 +165,9 @@ Genode::size_t Driver::Device::_ram_quota_required()
{
size_t total = 0;
_io_mem_list.for_each([&] (Io_mem &) {
total += 4096; });
total += Io_mem_session::RAM_QUOTA; });
_irq_list.for_each([&] (Irq &) {
total += Irq_session::RAM_QUOTA; });
return total;
}

View File

@ -87,9 +87,6 @@ Session_component::acquire_device(Platform::Session::Device_name const &name)
break;
}
/* account one device capability needed */
_cap_quota_guard().replenish(Cap_quota{1});
return _env.env.ep().rpc_ep().manage(e->object());
}
@ -113,7 +110,6 @@ void Session_component::release_device(Capability<Platform::Device_interface> de
if (!dc)
return;
_env.env.ep().rpc_ep().dissolve(dc);
_cap_quota_guard().replenish(Cap_quota{1});
dc->release();
});
}
@ -206,6 +202,10 @@ Session_component::~Session_component()
destroy(_md_alloc, e->object());
}
/* also free up dma buffers */
while (_buffer_list.first())
free_dma_buffer(_buffer_list.first()->cap);
/* replenish quota for rom sessions, see constructor for explanation */
_cap_quota_guard().replenish(Cap_quota{1});
_ram_quota_guard().replenish(Ram_quota{5*1024});