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 { try {
_driver.io(write, off, cnt, addr, *this, _p_to_handle); _driver.io(write, off, cnt, addr, *this, _p_to_handle);
} catch (Block::Session::Tx::Source::Packet_alloc_failed) { } catch (Block::Session::Tx::Source::Packet_alloc_failed) {
_req_queue_full = true; if (!_req_queue_full) {
Session_component::wait_queue().insert(this); _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); _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; } Partition *partition() { return _partition; }
void dispatch(Packet_descriptor &request, Packet_descriptor &reply) 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() 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); wait_queue().remove(c);
c->_req_queue_full = false; c->_req_queue_full = false;
@ -204,10 +215,17 @@ class Block::Root :
protected: 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 * 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; long num = -1;

View File

@ -70,6 +70,9 @@ class Block::Driver
if (ret) _dispatcher.dispatch(_cli, reply); if (ret) _dispatcher.dispatch(_cli, reply);
return ret; return ret;
} }
bool same_dispatcher(Block_dispatcher &same) {
return &same == &_dispatcher; }
}; };
private: private:
@ -152,6 +155,22 @@ class Block::Driver
_session.tx()->submit_packet(p); _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_ */ #endif /* _PART_BLK__DRIVER_H_ */