Hi, I'm having problem with some intermittent error reported as follows:
[init -> test-pager-2] Test::Pager::Pager(): Pager constructed OK. page fault (READ pf_addr=1004000 pf_ip=1011748 from 44a000) page fault (READ pf_addr=1006000 pf_ip=1011748 from 44a000) page fault (READ pf_addr=1008000 pf_ip=1011748 from 44a000) [init -> test-pager-2] Test-pager-2 example. ;-)) [init -> test-pager-2] Test::SharedMemory::SharedMemory(): About to start the pager.
KERNEL: Warning: nothing mapped: (Obj_space) from [0xfcdcedec/a3]: 00000407 size: 00000001 to [0xfcdcedec/a3]
KERNEL: Warning: nothing mapped: (Obj_space) from [0xfcdcedec/a3]: 0000040b size: 00000001 to [0xfcdcef4c/b]
KERNEL: Warning: nothing mapped: (Obj_space) from [0xfcdcef4c/b]: 00000206 size: 00000001 to [0xfcdcef4c/b]
KERNEL: Warning: nothing mapped: (Obj_space) from [0xfcdcedec/a3]: 0000040b size: 00000001 to [0xfcdcef4c/b]
KERNEL: Warning: nothing mapped: (Obj_space) from [0xfcdcef4c/b]: 00000206 size: 00000001 to [0xfcdcef4c/b] page fault (READ pf_addr=4db30 pf_ip=4db30 from 44a000) page fault (READ pf_addr=4a310 pf_ip=4a310 from 44a000) page fault (READ pf_addr=49ce0 pf_ip=49ce0 from 44a000) page fault (READ pf_addr=6b004 pf_ip=4ac5b from 44a000) page fault (READ pf_addr=6c008 pf_ip=4ac5b from 44a000) page fault (READ pf_addr=6d000 pf_ip=4a958 from 44a000) page fault (READ pf_addr=6e004 pf_ip=4ac5b from 44a000) page fault (READ pf_addr=6f00c pf_ip=4ac5b from 44a000) page fault (WRITE pf_addr=231c pf_ip=4c111 from 44a000) page fault (READ pf_addr=47ae0 pf_ip=47ae0 from 44a000) page fault (READ pf_addr=48134 pf_ip=48135 from 44a000) page fault (READ pf_addr=8e034 pf_ip=4b17e from 44a000) page fault (READ pf_addr=4eb70 pf_ip=4eb70 from 44a000) page fault (READ pf_addr=44770 pf_ip=44770 from 44a000) page fault (READ pf_addr=46030 pf_ip=46030 from 44a000) page fault (READ pf_addr=456d0 pf_ip=456d0 from 44a000) [init -> test-pager-2] C++ runtime: Genode::Rm_session::Invalid_thread [init -> test-pager-2] void* abort(): abort called
In the following code it seems to occur as a result of the Signal / _receiver calls.
Any ideas??
#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 <foc_cpu_session/foc_cpu_session.h> #include <foc_cpu_session/client.h>
#include <root/component.h> #include <util/avl_string.h> #include <util/misc_math.h> #include <assert.h> #include <stdlib.h>
#include <omnios/thread.h> #include <omnios/sleep.h>
#define PAGE_SIZE 4096 #define SHARED_MEMORY_SIZE (1*PAGE_SIZE) using namespace Genode;
namespace Test {
/** * Example pager class * * @return */ class Pager : public OmniOS::Thread { private:
Signal_receiver _receiver;
public:
// ctor Pager() { PDBG("Pager constructed OK."); }
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; Genode::size_t _size; Dataspace_capability _ds; Dataspace_client _ds_client; unsigned long _iter;
public: // ctor Physical_backing_store(Genode::size_t size): _rm(0,size), _ds(env()->ram_session()->alloc(SHARED_MEMORY_SIZE)), _ds_client(_ds), _iter(0) { _size = size; assert(_size > 0); }
virtual ~Physical_backing_store() { }
/** * Page fault handler. * */ void handle_fault() { Rm_session::State state = _rm.state();
if(state.type != Rm_session::READY) { if(__sync_fetch_and_add(&_iter,1) > 0) { PDBG("Entered PF handler again!!!\n"); return; } else PDBG("Entered PF handler for 1st time!\n"); }
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 {
try {
/* print out the physical address */ { Genode::addr_t addr = _ds_client.phys_addr(); printf("Physical addr of dataspace:0x%lX\n",addr); }
/* write something in for testing */ char * addr = (char*) env()->rm_session()->attach(_ds);
assert(addr); addr[0] = 1; addr[1] = 2; addr[2] = 3;
env()->rm_session()->detach((void*)addr);
} 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() { while (true) { try { // THIS code BREAKS THINGS 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"); } } }
class SharedMemory { private: void * _vaddr;
Genode::Cancelable_lock _vaddr_lock; Test::Physical_backing_store _bs;
/* create pager object */ static Test::Pager _pager;
public:
SharedMemory(): _vaddr(NULL),_bs(SHARED_MEMORY_SIZE) {
PDBG("About to start the pager."); /* lets start the pager thread */ _pager.start();
/* allocate some backing store */ try {
/* connect pager to fault handler */ _bs.connect_pager(_pager);
/* attach to dataspace */ assert(!_vaddr);
addr_t target_va = 0xfff000; /* look, we can use a specific VA address */
PDBG("About to attach to vaddr (0x%p)\n",_vaddr); _vaddr = env()->rm_session()->attach(_bs.ds(),SHARED_MEMORY_SIZE,0,true,target_va); PDBG("Attached dataspace to vaddr (0x%p)\n",_vaddr); assert(_vaddr); } catch(...) { PERR("Something failed in SharedMemory ctor.\n"); enter_kdebug("Unexpected condition."); }
}
void r_access(unsigned int tid) { assert(_vaddr);
/* trigger read fault */ char* c = (char*) _vaddr; printf("Read (va=%p) [%d %d %d] (tid=%u)\n",c,c[0],c[1],c[2],tid); }
void w_access() { assert(_vaddr); /* trigger write fault */ char* c = (char*) _vaddr; c[0]=2; c[1]=3; c[2]=4; }
};
/* static initializers */ Test::Pager Test::SharedMemory::_pager;
}
int main() { Genode::printf("Test-pager-2 example. ;-))\n");
Test::SharedMemory shmem; Genode::printf("shmem created ok.\n");
Genode::sleep_forever(); return 0; }