On 29.06.2011 23:00, Chen Tian wrote:
Hi Stefan,
So that means each Pager_object also has a corresponding Fiasco OC kernel object, which can do the IPC to the pager thread, right?
Hi Chen,
each Pager_object has an own IPC-gate (kernel-object) to the pager-thread, the pager-thread thereby distinguishes different faulters from each other.
By looking at the cap_session_component.cc, I think the kernel object is essentially an IPC-gate to the pager thread, i.e., _pager_ep->activation. Can you briefly tell me how the ipc-gate works? I think I will spend some time on the kernel later. Thanks a lot.
An IPC-gate is some kind of a thread's wrapper object. In addition to the target thread object, you can assign a label to it, during its creation. The label is received by the destination thread whenever IPC is send through the IPC-gate. This label value cannot be altered by some (remote) owner of the IPC-capability. Moreover, when owning the IPC-gate you cannot e.g. destroy the corresponding thread (which you can do, if you own the "real" thread capability), but only do IPC with it.
Regards Stefan
Best, Chen
-----Original Message----- From: Stefan Kalkowski [mailto:stefan.kalkowski@...1...] Sent: Tuesday, June 28, 2011 2:22 AM To: Genode OS Framework Mailing List Subject: Re: set pager in foc
Hi Chen,
On 27.06.2011 23:17, Chen Tian wrote:
Hi Stefan,
Sorry for the late response, as I am busy with something else.
Can you please explain to me what _pager->cap().dst() is and when it is defined?
'_pager' is a 'Pager_object' - an object which is local to the pager, and encapsulates the state of a pager's client. It is referenced from outside (e.g. by a failing client) via the pager-capability. The 'Pager_object' has a 'Genode::Capability' member, which is returned by 'Pager_object::cap()'. This is the capability which references the 'Pager_object'. The 'Genode::Capability' is Genode's own abstraction of a capability, and shouldn't be mixed up with the capability provided by the Fiasco.OC kernel. Nevertheless, every Genode capability internally uses a kernel capability. The kernel capability can be accessed via 'Genode::Capability::dst()'.
So in short _pager->cap().dst() gives you the capability, that references the pager-thread kernel-object, which can be used e.g. to do IPC to that thread. The 'Genode::Capability' member of the Pager_object is set, when it gets associated with a pager, have a look at the Pager_entrypoint::manage(...) function in:
base-foc/src/base/pager/pager.cc
In core this is done, whenever someone calls 'add_client(Thread_capability thread)' via the rm_session interface. Have a look at here:
base/src/core/rm_session_component.cc
the essential line is the following:
return Pager_capability(_pager_ep->manage(cl));
Is this the global pager thread we are talking about?
If you will, yes. (Once again we've to restrict this statement to core's pager implementation on Fiasco.OC. ;-) )
I hope it helped you to better understand the code around the paging issues.
Regards Stefan
I am looking at add_client function and found that only Pager_object::_badge is initialized through Rm_client constructor. Thanks.
Best, Chen
-----Original Message----- From: Stefan Kalkowski [mailto:stefan.kalkowski@...1...] Sent: Wednesday, June 22, 2011 2:09 AM To: Genode OS Framework Mailing List Subject: Re: set pager in foc
Hi Chen,
On 22.06.2011 02:54, Chen Tian wrote:
Thanks for the reply, two more questions.
First, why _pager is considered global? Isn't it constructed for each
thread
as a client of an RM session?
Yeah you're right. That's why I put global pager in double quotes. With global pager I meant that for almost all applications in Genode/Fiasco.OC there is only one pager thread in core, like you've stated before. So the local member _pager is mostly the same capability for all different thread objects (except for instance L4Linux).
Second, the pager thread whose entry() is defined in pager.cc should be
the
one that receives the page fault request from the kernel. But how is this thread registered into kernel so that the kernel knows its existence?
At first, the pager thread is a normal thread which starts up and waits for IPC messages. In Fiasco.OC one can send IPC messages to a thread only, when owning a capability for that thread. Whenever a thread raises a pagefault, the kernel delivers an IPC-message to the pager of that thread. Therefore the kernel uses a capability, that was registered as the thread's pager thread beforehand. This registration of the pager capability is done via the l4_thread_control_* system call.
Does that clarify your question?
regards Stefan
Thanks for the help.
Best, Chen
-----Original Message----- From: Stefan Kalkowski [mailto:stefan.kalkowski@...1...] Sent: Monday, June 20, 2011 7:10 AM To: Genode OS Framework Mailing List Subject: Re: set pager in foc
Hello Chian,
On 18.06.2011 01:38, Chen Tian - SISA wrote:
Hello,
After the set_pager function of a thread is called through a cpu_session, the _pager of that thread is set and used when the actual platform thread starts.
That's true at least for the implementation of the rm_session interface in core with respect to Genode/Fiasco.OC.
But there is only one thread (pager) to resolve all page faults for all threads.
This is almost true for the Fiasco.OC version of Genode. Like Norman explained in a previous mail, other platforms don't necessarily have only one pager. In the current implementation for Fiasco.OC this is true for normal Genode applications. L4Linux for example pages its VCPUs, and applications itself. A VCPU (some kind of special thread concept in recent Fiasco.OC revisions) is constructed by Genode's core process, but afterwards the capability slot containing the global pager capability gets overmapped to contain a special pager thread, which is running in the L4Linux-kernel protection-domain.
I think the pager mapping happened in platform_thread::start (platform_thread.cc:40-47). Can somebody please explain to me the meaning of this l4_task_map call?
In Fiasco.OC a pager gets assigned to a thread by choosing a capability slot in the capability space of the target protection domain, wherein the new thread will run. The capability in that slot should point to the pager thread. That why we first map the capability of the pager (which was set by the cpu_session interface first) into the capability space of the target protection domain. This is what the following snipet does:
l4_task_map(_platform_pd->native_task(), L4_BASE_TASK_CAP, l4_obj_fpage(_pager->cap().dst(), 0, L4_FPAGE_RWX), _remote_pager_cap | L4_ITEM_MAP);
After that, you instruct the kernel to use the capability slot, we just filled with life, as pager and exception-handler:
l4_thread_control_start(); l4_thread_control_pager(_remote_pager_cap); l4_thread_control_exc_handler(_remote_pager_cap); l4_thread_control_bind(_utcb, _platform_pd->native_task());
I suspect that “_remote_pager_cap” is corresponding to the global pager, but cannot find any evidence. Thanks a lot.
The '_remote_pager_cap' denotes the capability slot in the thread's capability space, whereby '_pager' is the capability slot in core's capability space, that gets mapped to '_remote_pager_cap' by l4_task_map. The '_pager' variable is set via the cpu_session interface, like you've stated before. Although, this is normally the "one global pager", Genode's design and the Fiasco.OC specific implementation is not limited to use only that one pager thread.
Best regards Stefan
Best,
Chen
--
EditLive Enterprise is the world's most technically advanced content authoring tool. Experience the power of Track Changes, Inline Image Editing and ensure content is compliant with Accessibility Checking. http://p.sf.net/sfu/ephox-dev2dev
Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main