"Jun-ichi Odagiri" jun-ichi.odagiri@kek.jp writes:
On Friday 15 June 2001 8:49 PM, Frank Mehnert wrote:
You should not expect any real-time behavior if you use a L4Linux task to serve interrupts.
Here, you mean a "process of L4Linux" by the word "L4Linux task", wright?
Yes, he does. Below, I will use the term L4Linux client to avoid confusion.
Instead of this, implement the time-critical code (e.g. I/O to VME board, computations of output values) in an L4 task.
I'm aware that your suggestion is the right way. Still, it is convenient for me if a "process" can be used to serve interrupts in my application. I guess your "an L4 task" can be a "process" of L4-Linux if it has a priority higher than that of the Linux server task, am I right? I noticed that a process can cause page faults even after it has called "mlockall" to make itself memory-resident. I've taken care of this.
You're right in principle, but there are some obstacles.
1. Obviously your real-time L4Linux client must not do Linux system calls.
2. How do you increase the L4 priority of your program? In an L4Linux client you can't because it has an MCP (maximum controlled priority) of 0. You need to implement an L4Linux driver or a program external to L4Linux (an "L4 task") to increase your client's priority.
3. As you noticed, mlockall() makes the program memory-resident, but doesn't prevent page faults: When L4Linux kills an L4Linux client, it flushes some pages from all clients' address spaces (which these clients need to map in again upon the next page fault). You said you've taken care of this problem. How?
One solution would be to use an external memory manager (an L4 task) that provides nonpageable memory.
Then you will get worst-case latencies of about 85 microseconds (P800).
The worst-case interrupt latency I got was roughly 700 microseconds. What dominates the latency in L4-linux is not the performance of L4 (I'm using Fiasco, actually) but the critical sections of Linux, which are executed with disabling interrupts. RT-linux people found that standard Linux disables interrupts as long as 600 microseconds. It applies to the Linux server task of L4-Linux as well, I guess. I'm thinking of replaceing the "interrupts off" with another method to achieve required mutual exclusion. Then, I will get the number you suggested, hopefully.
This is exactly the problem the "tamed server" option Frank recommended solves:
Note that you should use the tamed version of L4Linux (make menuconfig - "L4Linux options" - "Use tamed server").
I'm going to check what the option does. Still, I was wondering if you could explain the point to me.
See URL:http://os.inf.tu-dresden.de/papers_ps/part98.ps for a description of the implementation.
Regards, Michael
Hello,
I' m very sorry for my late reply to your response. I've been sick in bed last 10 days, even worse, abroad most of the duration. Now, I'm up and would like to continue the discussion a bit more if you may allow me to do so.
"Jun-ichi Odagiri" jun-ichi.odagiri@kek.jp wrote:
"Michael Hohmuth" hohmuth@innocent.com wrore:
I guess your "an L4 task" can be a "process" of L4-Linux if it has a
priority
higher than that of the Linux server task, am I right? [...]
You're right in principle, but there are some obstacles.
- Obviously your real-time L4Linux client must not do Linux system calls.
It's OK. All the real-time L4Linux clients need to do is just read/write data from/to a device, or some other primitive work. L4 system calls will do it for the real-time clinents. Other non-real-time L4Linux clients take care of higher level processing by callinng Linux system calls. 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.
- How do you increase the L4 priority of your program? In an L4Linux
client you can't because it has an MCP (maximum controlled priority) of 0. [...]
I just changed the MCPs of L4Linux clients from 0 to 255.
- As you noticed, mlockall() makes the program memory-resident, but
doesn't prevent page faults: When L4Linux kills an L4Linux client, it flushes some pages from all clients' address spaces (which these clients need to map in again upon the next page fault). You said you've taken care of this problem. How?
Let me confirm if we are sharing the point in the first place. 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.
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...).
The worst-case interrupt latency I got was roughly 700 microseconds. What dominates the latency ...
This is exactly the problem the "tamed server" option Frank recommended solves:
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. But I guess, from your comments, I've already gotten the solution.
Thanks a lot for your comments, suggestions and patience to read this heavy mail.
Jun-ichi
l4-hackers@os.inf.tu-dresden.de