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; }
After further digging I now wonder if it has something to do with the construction of Signal_receiver which is ultimately called by the static constructor for the _pager object. Too early may be?
Daniel
On 07/28/2011 05:37 PM, Daniel Waddington wrote:
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; }
--
*Daniel G. Waddington Ph.D. C.Sci. **| **Samsung Information Systems America (SISA)*
Principal Engineer/Research Manager, Systems Research Group, Computer Science Lab
t: 408-544-5675 f: 408-544-5540 c: 408-890-0479
d.waddington@...60... mailto:d.waddington@...60...
*****P*Please consider the environment before printing this email.
This message is intended only for the named recipient(s) above and may contain confidential or privileged information or protected attorney work product. If you are not the intended recipient, any review, dissemination, distribution or copying is strictly prohibited. If you have received this message in error, please immediately notify the sender and delete this message and its attachments from your computer and dispose of all other copies or printouts. Thank you.
Got Input? Slashdot Needs You. Take our quick survey online. Come on, we don't ask for help often. Plus, you'll get a chance to win $100 to spend on ThinkGeek. http://p.sf.net/sfu/slashdot-survey
Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Daniel,
I am not able to reproduce the problem using Genode's SVN head and Fiasco.OC (tested with both revisions 31 and 36). I get the following output:
int main(): --- create local services --- int main(): --- start init --- int main(): transferred 56 MB to init int main(): --- init created, waiting for exit condition --- [init -> test-daniel] Starting ldso ... [init -> test-daniel] Starting application ... environ: 1058 [init -> test-daniel] Test::Pager::Pager(): Pager constructed OK. [init -> test-daniel] Test-pager-2 example. ;-)) [init -> test-daniel] Test::SharedMemory::SharedMemory(): About to start the pager. [init -> test-daniel] Test::SharedMemory::SharedMemory(): About to attach to vaddr (0x0) [init -> test-daniel] Test::SharedMemory::SharedMemory(): Attached dataspace to vaddr (0xfff000) [init -> test-daniel] shmem created ok.
Looks ok to me. If in doubt about the construction time of the '_pager' object, I suggest constructing the object using a function with a local static variable:
Test::Pager *pager() { static Test:Pager instance; return &instance; }
This way, 'instance' is constructed at the first call of 'pager()'. So you have much better control over the time of construction. As a nice side effect, the execution order of constructors (if global objects depend on each other) becomes correct by definition. For this reason, we usually avoid the use of global constructors altogether.
Regards Norman
Hi Norman, Yes, eliminating the global static constructor for the pager solved the problem.
Daniel
On 07/29/2011 04:45 AM, Norman Feske wrote:
Hi Daniel,
I am not able to reproduce the problem using Genode's SVN head and Fiasco.OC (tested with both revisions 31 and 36). I get the following output:
int main(): --- create local services --- int main(): --- start init --- int main(): transferred 56 MB to init int main(): --- init created, waiting for exit condition --- [init -> test-daniel] Starting ldso ... [init -> test-daniel] Starting application ... environ: 1058 [init -> test-daniel] Test::Pager::Pager(): Pager constructed OK. [init -> test-daniel] Test-pager-2 example. ;-)) [init -> test-daniel] Test::SharedMemory::SharedMemory(): About to start the pager. [init -> test-daniel] Test::SharedMemory::SharedMemory(): About to attach to vaddr (0x0) [init -> test-daniel] Test::SharedMemory::SharedMemory(): Attached dataspace to vaddr (0xfff000) [init -> test-daniel] shmem created ok.
Looks ok to me. If in doubt about the construction time of the '_pager' object, I suggest constructing the object using a function with a local static variable:
Test::Pager *pager() { static Test:Pager instance; return&instance; }
This way, 'instance' is constructed at the first call of 'pager()'. So you have much better control over the time of construction. As a nice side effect, the execution order of constructors (if global objects depend on each other) becomes correct by definition. For this reason, we usually avoid the use of global constructors altogether.
Regards Norman