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