Simple custom pager
Daniel Waddington
d.waddington at ...60...
Thu Jul 14 18:31:26 CEST 2011
Hi Stefan,
Not to rush you, but any idea how long a fix will be? (Just so I can
re-prioritize if need be)
Thanks,
Daniel
On 07/11/2011 06:46 AM, Stefan Kalkowski wrote:
> Hi Daniel,
>
> we tried to reproduce your problem, and thereby had to recognize that in
> the current Fiasco.OC/Genode version there is something fundamentally
> broken with the rm-fault handling. We will further investigate the
> issue, and provide a fix as soon as possible.
>
> Thank you for reporting the issue!
>
> Regards
> Stefan
>
> On 09.07.2011 01:45, Daniel Waddington wrote:
>> Hi,
>> As a toy exercise I'm trying to write a very simple custom pager which
>> simply allocates memory from RAM to handle page faults. When I try to
>> handle the fault I get a region conflict exception. Can someone tell me
>> why?? I think I am missing something fundamental here.
>>
>> Thanks
>> Daniel
>>
>> ----
>>
>> #include<base/printf.h>
>> #include<base/sleep.h>
>> #include<base/rpc_server.h>
>> #include<cap_session/connection.h>
>> #include<dataspace/client.h>
>> #include<rom_session/connection.h>
>> #include<rm_session/connection.h>
>> #include<ram_session/connection.h>
>> #include<root/component.h>
>> #include<util/avl_string.h>
>> #include<util/misc_math.h>
>> #include<assert.h>
>>
>> #define PAGE_SIZE 4096
>>
>> using namespace Genode;
>>
>> namespace Test
>> {
>>
>> /**
>> * Example pager class
>> *
>> * @return
>> */
>> class Pager : public Thread<8192>
>> {
>> private:
>>
>> Signal_receiver _receiver;
>>
>> public:
>>
>> Signal_receiver *signal_receiver() { return&_receiver; }
>>
>> void entry();
>> };
>>
>> /**
>> * Example backing store class - this one uses physical memory
>> *
>> */
>> class Physical_backing_store : public Signal_context
>> {
>> private:
>> Rm_connection _rm;
>> size_t _size;
>>
>> public:
>> // ctor
>> Physical_backing_store(size_t size): _rm(0,_size) {
>> _size = size;
>> assert(_size> 0);
>> }
>>
>> virtual ~Physical_backing_store() {
>> }
>>
>> /**
>> * Page fault handler.
>> *
>> */
>> void handle_fault()
>> {
>> Rm_session::State state = _rm.state();
>>
>> printf("Test::Physical_backing_store:: rm session state is %s,
>> pf_addr=0x%lx\n",
>> state.type == Rm_session::READ_FAULT ? "READ_FAULT" :
>> state.type == Rm_session::WRITE_FAULT ? "WRITE_FAULT" :
>> state.type == Rm_session::EXEC_FAULT ? "EXEC_FAULT" :
>> "READY",
>> state.addr);
>>
>> if (state.type == Rm_session::READY)
>> return;
>>
>> try {
>>
>> Dataspace_capability _ds;
>> try {
>> _ds = env()->ram_session()->alloc(PAGE_SIZE);
>> }
>> catch(...) { PERR("Actual page allocation failed.\n"); }
>>
>> _rm.attach_at(_ds, state.addr& ~(PAGE_SIZE - 1));
>>
>> PDBG("attached data space OK!\n");
>> }
>> catch (Genode::Rm_session::Region_conflict) {
>> PERR("Region conflict - this should not happen\n");
>> }
>> catch (Genode::Rm_session::Out_of_metadata) {
>> PERR("Out of meta data!\n");
>> }
>> catch(...) {
>> PERR("Something else caused attach to fail in fault handler.\n");
>> }
>>
>> return;
>> }
>>
>> Rm_connection *rm() { return&_rm; }
>> Dataspace_capability ds() { return _rm.dataspace(); }
>>
>> void connect_pager(Pager& _pager) {
>> /* connect pager signal receiver to the fault handler */
>> _rm.fault_handler(_pager.signal_receiver()->manage(this));
>> }
>>
>> };
>>
>>
>> /**
>> * Entry point for pager thread.
>> *
>> */
>> void Pager::entry()
>> {
>> printf("Pager thread started OK.\n");
>>
>> while (true) {
>> try {
>> Signal signal = _receiver.wait_for_signal();
>>
>> for (int i = 0; i< signal.num(); i++) {
>> static_cast<Physical_backing_store
>> *>(signal.context())->handle_fault();
>> }
>> } catch (...) {
>> PDBG("unexpected error while waiting for signal");
>> }
>> }
>> }
>>
>>
>> }
>>
>> int main()
>> {
>> Genode::printf("Test-pager example. ;-))\n");
>>
>> Test::Pager _pager;
>>
>> /* start pager thread */
>> _pager.start();
>>
>> /* create dataspace etc. */
>> try {
>>
>> enum { MANAGED_DS_SIZE = 64*1024*1024 };
>> Test::Physical_backing_store bs(MANAGED_DS_SIZE);
>>
>> /* connect pager to fault handler */
>> bs.connect_pager(_pager);
>>
>> /* attach to dataspace */
>> char * addr = (char*) env()->rm_session()->attach(bs.ds());
>> assert(addr);
>>
>> /* trigger read fault */
>> printf("!!!Triggering fault...\n");
>> printf("%c%c%c\n",addr[0],addr[1],addr[2]);
>>
>> printf("Fault handled OK.\n");
>>
>> }
>> catch(...) {
>> PERR("Something failed ????.\n");
>> }
>>
>> printf("test-pager completed.\n");
>> Genode::sleep_forever();
>> return 0;
>> }
>>
>>
>>
>>
>> ------------------------------------------------------------------------------
>> All of the data generated in your IT infrastructure is seriously valuable.
>> Why? It contains a definitive record of application performance, security
>> threats, fraudulent activity, and more. Splunk takes this data and makes
>> sense of it. IT sense. And common sense.
>> http://p.sf.net/sfu/splunk-d2d-c2
>>
>>
>>
>> _______________________________________________
>> Genode-main mailing list
>> Genode-main at lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/genode-main
More information about the users
mailing list