Simple custom pager

Stefan Kalkowski stefan.kalkowski at ...1...
Mon Jul 11 15:46:57 CEST 2011


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

-- 
Stefan Kalkowski
Genode Labs

http://www.genode-labs.com/ · http://genode.org/

Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden
Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth




More information about the users mailing list