mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-12 21:53:28 +00:00
hw: cancel unresolved faults before pager dissolve
If an RM client gets dissolved the RM server tries to first dissolve and then destruct the according pager object. As pager objects previously cancelled unresolved faults only in destructor the dissolve operation blocked forever when an unresolved fault existed. As every pager object should get dissolved before it gets destructed (signal-context complains otherwise) no more unresolved-fault cancelling is needed in the destructor. ref #989
This commit is contained in:
parent
8eef91f2ac
commit
f4bd2368f6
@ -20,6 +20,9 @@
|
||||
#include <base/signal.h>
|
||||
#include <pager/capability.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <placement_new.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Cap_session;
|
||||
@ -132,9 +135,38 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
|
||||
|
||||
Signal_context_capability _signal_context_cap;
|
||||
Thread_capability _thread_cap;
|
||||
bool _signal_valid;
|
||||
char _signal_buf[sizeof(Signal)];
|
||||
unsigned const _badge;
|
||||
|
||||
/**
|
||||
* Remember an incoming fault for handling
|
||||
*
|
||||
* \param s fault signal
|
||||
*/
|
||||
void _take_fault(Signal const & s)
|
||||
{
|
||||
new (_signal_buf) Signal(s);
|
||||
_signal_valid = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* End handling of current fault
|
||||
*/
|
||||
void _end_fault()
|
||||
{
|
||||
_signal()->~Signal();
|
||||
_signal_valid = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* End handling of current fault if there is one
|
||||
*/
|
||||
void _end_fault_if_pending()
|
||||
{
|
||||
if (_signal_valid) { _end_fault(); }
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
@ -151,27 +183,22 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
|
||||
*/
|
||||
Pager_object(unsigned const badge, Affinity::Location);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~Pager_object() { }
|
||||
|
||||
/**
|
||||
* The faulter has caused a fault and awaits paging
|
||||
*
|
||||
* \param s signal that communicated the fault
|
||||
*/
|
||||
void fault_occured(Signal const & s);
|
||||
void fault_occured(Signal const & s) { _take_fault(s); }
|
||||
|
||||
/**
|
||||
* Current fault has been resolved so resume faulter
|
||||
*/
|
||||
void fault_resolved();
|
||||
void fault_resolved() { _end_fault(); }
|
||||
|
||||
/**
|
||||
* User identification of pager object
|
||||
*/
|
||||
unsigned badge() const;
|
||||
unsigned badge() const { return _badge; }
|
||||
|
||||
/**
|
||||
* Resume faulter
|
||||
@ -183,6 +210,29 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
|
||||
*/
|
||||
void exception_handler(Signal_context_capability);
|
||||
|
||||
/**
|
||||
* Install information that is necessary to handle page faults
|
||||
*
|
||||
* \param c linkage between signal context and a signal receiver
|
||||
* \param p linkage between pager object and a pager entry-point
|
||||
*/
|
||||
void start_paging(Signal_context_capability const & c,
|
||||
Pager_capability const & p)
|
||||
{
|
||||
_signal_context_cap = c;
|
||||
Object_pool<Pager_object>::Entry::cap(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall paging information and cancel unresolved faults
|
||||
*/
|
||||
void stop_paging()
|
||||
{
|
||||
Object_pool<Pager_object>::Entry::cap(Native_capability());
|
||||
_signal_context_cap = Signal_context_capability();
|
||||
_end_fault_if_pending();
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
** Pure virtual **
|
||||
@ -207,8 +257,6 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
|
||||
|
||||
void thread_cap(Thread_capability const & c);
|
||||
|
||||
void cap(Native_capability const & c);
|
||||
|
||||
unsigned signal_context_id() const;
|
||||
};
|
||||
|
||||
|
@ -15,9 +15,6 @@
|
||||
#include <base/pager.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <placement_new.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
@ -70,25 +67,10 @@ void Pager_object::wake_up() { fault_resolved(); }
|
||||
|
||||
void Pager_object::exception_handler(Signal_context_capability) { }
|
||||
|
||||
void Pager_object::fault_resolved() { _signal()->~Signal(); }
|
||||
|
||||
unsigned Pager_object::badge() const { return _badge; }
|
||||
|
||||
|
||||
void Pager_object::fault_occured(Signal const & s)
|
||||
{
|
||||
new (_signal()) Signal(s);
|
||||
}
|
||||
|
||||
|
||||
void Pager_object::cap(Native_capability const & c)
|
||||
{
|
||||
Object_pool<Pager_object>::Entry::cap(c);
|
||||
}
|
||||
|
||||
|
||||
Pager_object::Pager_object(unsigned const badge, Affinity::Location)
|
||||
:
|
||||
_signal_valid(0),
|
||||
_badge(badge)
|
||||
{ }
|
||||
|
||||
@ -126,12 +108,8 @@ Native_capability Pager_activation_base::cap()
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object * const o)
|
||||
{
|
||||
/* let entrypoint dissolve the pager object */
|
||||
remove_locked(o);
|
||||
o->cap(Native_capability());
|
||||
|
||||
/* let activation signal-receiver dissolve the pager signal-context */
|
||||
o->_signal_context_cap = Signal_context_capability();
|
||||
o->stop_paging();
|
||||
_activation->Signal_receiver::dissolve(o);
|
||||
}
|
||||
|
||||
@ -147,13 +125,10 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *,
|
||||
|
||||
Pager_capability Pager_entrypoint::manage(Pager_object * const o)
|
||||
{
|
||||
/* let activation signal-receiver manage the pager signal-context */
|
||||
o->_signal_context_cap = _activation->Signal_receiver::manage(o);
|
||||
|
||||
/* let entrypoint manage the pager object */
|
||||
unsigned const dst = _activation->cap().dst();
|
||||
Native_capability c = Native_capability(dst, o->badge());
|
||||
o->cap(c);
|
||||
unsigned const d = _activation->cap().dst();
|
||||
unsigned const b = o->badge();
|
||||
auto const p = reinterpret_cap_cast<Pager_object>(Native_capability(d, b));
|
||||
o->start_paging(_activation->Signal_receiver::manage(o), p);
|
||||
insert(o);
|
||||
return reinterpret_cap_cast<Pager_object>(c);
|
||||
return p;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user