part_blk: free memory on session close

the dataspace used for the packetstream

Fixes #2148
This commit is contained in:
Alexander Boettcher 2016-10-24 22:07:35 +02:00 committed by Christian Helmuth
parent afed9cfd95
commit 466bec038f
2 changed files with 41 additions and 4 deletions

View File

@ -87,8 +87,10 @@ class Block::Session_component : public Block::Session_rpc_object,
try {
_driver.io(write, off, cnt, addr, *this, _p_to_handle);
} catch (Block::Session::Tx::Source::Packet_alloc_failed) {
_req_queue_full = true;
Session_component::wait_queue().insert(this);
if (!_req_queue_full) {
_req_queue_full = true;
Session_component::wait_queue().insert(this);
}
}
}
@ -139,6 +141,15 @@ class Block::Session_component : public Block::Session_rpc_object,
_tx.sigh_packet_avail(_sink_submit);
}
~Session_component()
{
_driver.remove_dispatcher(*this);
if (_req_queue_full)
wait_queue().remove(this);
}
Ram_dataspace_capability const rq_ds() const { return _rq_ds; }
Partition *partition() { return _partition; }
void dispatch(Packet_descriptor &request, Packet_descriptor &reply)
@ -165,7 +176,7 @@ class Block::Session_component : public Block::Session_rpc_object,
static void wake_up()
{
for (Session_component *c = wait_queue().first(); c; c = c->next())
for (; Session_component *c = wait_queue().first();)
{
wait_queue().remove(c);
c->_req_queue_full = false;
@ -204,10 +215,17 @@ class Block::Root :
protected:
void _destroy_session(Session_component *session) override
{
Ram_dataspace_capability rq_ds = session->rq_ds();
Genode::Root_component<Session_component>::_destroy_session(session);
_env.ram().free(rq_ds);
}
/**
* Always returns the singleton block-session component
*/
Session_component *_create_session(const char *args)
Session_component *_create_session(const char *args) override
{
long num = -1;

View File

@ -70,6 +70,9 @@ class Block::Driver
if (ret) _dispatcher.dispatch(_cli, reply);
return ret;
}
bool same_dispatcher(Block_dispatcher &same) {
return &same == &_dispatcher; }
};
private:
@ -152,6 +155,22 @@ class Block::Driver
_session.tx()->submit_packet(p);
}
void remove_dispatcher(Block_dispatcher &dispatcher)
{
for (Request *r = _r_list.first(); r;) {
if (!r->same_dispatcher(dispatcher)) {
r = r->next();
continue;
}
Request *remove = r;
r = r->next();
_r_list.remove(remove);
Genode::destroy(&_r_slab, remove);
}
}
};
#endif /* _PART_BLK__DRIVER_H_ */