"Jun-ichi Odagiri" jun-ichi.odagiri@kek.jp writes:
[...] The essential point, for my application, is that the both types of clients must work in a single user address space, i.e. they must be user-level threads, which are to be created through the Linux clone() system call.
Please note that currently L4Linux puts threads started by clone(...CLONE_VM...) into different L4 tasks. They will have the same memory view, but they use different address spaces as far as L4 is concerned. In other words, the L4Linux page table is shared, but L4's isn't.
In standard Linux, a process does not cause page faults once it has invoked the mlockall() system call. It does not apply to L4Linux since you have two different sets of page tables for an L4Linux client. One in the Linux server, and the other in the L4 kernel. The former is filled once mlockall() has invoked. However, the latter is left unchanged even after mlockall() returns. Page faults are still needed just to update the page tables in the L4 kernel. As you pointed out in the above 1, my real-time L4Linux client must not do Linux system calls, nor page faults.
There is an additional problem. Suppose your program shares pages with another process (e.g., a shared-library text segment) and the L4Linux needs to flush these page mappings for the other process. In that case, L4Linux calls l4_fpage_unmap(fpage, L4_FP_OTHER_SPACES). This call results in the shared page being flushed not only from the other task's address space, but also from your address space. You will have to remap it on page fault.
I don't quite remember all cases L4Linux would have to do that, but I seem to remember that it happens when a process is killed:
L4Linux needs to flush all mappings a dying task owned. As there is no way for L4Linux to tell if a task had granted away some pages, a simple task deletion is not enough; L4Linux must flush all mappings separately.
For this reason (no way to prevent granting), the L4 API currently does not have a primitive for flushing a page only in a specific address space. In consequence, L4Linux needs to flush all client mappings at once.
A possible extension of the L4 API would provide these two mechanisms.
A possible workaround for you might be to just disable the flushing at task-delete time (Jean or Frank probably could tell you what to change), although, as I said, I don't remember if there are other places that flush mappings.
So, I made a Linux system call that makes the Linux server fill the page tables of the calling L4Linux client in the L4 kernel. In order to implement the Linux system call, I had to add an L4 system call, l4_fpage_map(), which allows an L4 task (the Linux server) to send a flex page to another L4 task (an L4Linux client) without the recipient's agreement. I believe you do not like it because it harms the security of the system. But, being a control system, it's still acceptable by me (may be...).
You could do without the L4-kernel modification if your L4Linux system call just toggled a flag that told L4Linux to map the whole address space (l4_fpage(...L4_WHOLE_ADDRESS_SPACE...)) to the current process on page-fault. Subsequently, your client can ``forge'' a page-fault message to the L4Linux server.
See URL:http://os.inf.tu-dresden.de/papers_ps/part98.ps for a description of the implementation.
I failed in openning the .ps file on my system. I'll try it later again.
I had no problem in downloading and opening the file, so it probably is a transient problem.
Regards, Michael
"Michael Hohmuth" hohmuth@innocent.com writes:
Please note that currently L4Linux puts threads started by clone(...CLONE_VM...) into different L4 tasks. [...]
I've noticed this point. It implies that a TLB flush is required upon a "thread" switching ( L4 task switching ). It will take... how long? Maybe 10 microseconds or so, I guess.
There is an additional problem. Suppose your program shares pages with another process (e.g., a shared-library text segment) and the L4Linux needs to flush these page mappings for the other process. [...].
I overlooked this point. It seems to take some time for me to digest the story. Thanks a lot for your detailed explanation and suggestion.
You could do without the L4-kernel modification if your L4Linux system call just toggled a flag that told L4Linux to map the whole address space (l4_fpage(...L4_WHOLE_ADDRESS_SPACE...)) to the current process on page-fault. Subsequently, your client can ``forge'' a page-fault message to the L4Linux server.
I got the picture. Still, I do not see exactly how I can do it. I might ask you again after consulting the source.
Jun-ichi
[Jun-ichi Odagiri]
"Michael Hohmuth" hohmuth@innocent.com writes:
Please note that currently L4Linux puts threads started by clone(...CLONE_VM...) into different L4 tasks. [...]
I've noticed this point. It implies that a TLB flush is required upon a "thread" switching ( L4 task switching ). It will take... how long? Maybe 10 microseconds or so, I guess.
Think close to 100 (?) cycles for the instruction itself and 25 cycles for each following TLB miss (numbers depending on CPU and memory access speeds of course). Assuming something above 100 TLB misses, you would then on a 500MHz processor get, as you say, an additional cost of about 10 microseconds. On a P4 these additional costs are even higher.
eSk
l4-hackers@os.inf.tu-dresden.de