Mon, 04 Sep 2000 Sheldon Hoffman wrote:
[...]
> Why can't I define the stack size for my RTL interrupt service routine?
Basically because any normal system runs all ISRs on the same stack; only
*tasks* have their own stacks. Most architectures have hardware support for
two stacks (some call them "user mode stack" and "privileged mode stack"), and
all tasks use the "user mode stack" - the scheduler changes the stack pointer
upon task switches to make it appear as if the tasks are running on their own
CPUs.
In other words, a single shared stack for drivers, schedulers and other ISR code
is the natural way of doing it. Anything else requires extra work and extra
overhead.
> Isn't the stack for an RTL interrupt service routine a RTL system
> resource that should be managed by the RTLinux system?
It's more like a hardware resource, actually; shared by everything that
executes in "interrupt mode".
> Wouldn't
> that make it more robust (ie deterministic) than having to hope and
> pray that other Linux drivers don't intermittently use "too much"
> stack?
It's not impossible to do it the way you wan't, but it's not entirely
staightforward to implement, I'm afraid... (As opposed to tasks, ISRs must
be able to handle reentrance correctly.)
> I can use the pthread_attr_setstacksize() to define the stack for my
> RTLinux processes but how do I do this for a fifo handler?
A FIFO handler executes in the same context as any device driver *operation
call, AFAIK. That is, it sees the same environment as any syscall code.
> For init_module() and cleanup_module() code?
Same here, I think...
> For my RTL interrupt service routine?
ISR. There aren't really any real contexts on this level (at least not on the
x86 architecture, AFAIK) - the interrupt controller gives the CPU a vector and
signals an IRQ, and the CPU pushes the current context (which may be a lower
prio ISR executing!) and jumps where the vector indicates. It would probably be
possible to do something like a task switch somewhere around here, but any
normal OS just saves the CPU state and regs, calls the driver ISR(s), restores
the regs and state and does an RTI. The same stack is shared by all ISRs -
the one that was set up some time during kernel initialization.
> I want my code to run predictably (ie deterministically) and not crash
> unpredictably because of some other code as consumed too much stack.
Well, a missed deadline is better than a crash, but still, unless *all* memory
is preallocated and locked, determinism goes out the window... The "proper"
solution is probably to take ISRs for what they are; Interrupt Service
Routines, *not* tasks, and view that layer more like a driver than a part of
the application. Try to keep stuff that uses too much stack space in real RT
threads, which communicate/synchronize with the ISRs as required.
Alternatively (if this means too much overhead), do the job in the ISRs, but
use preallocated memory, object pools or whatever, instead of the stack. If you
really want to be "OOM safe", use pools and make the allocator send of a
request for more memory to a non-RTL (kernel) thread and then go to sleep until
the memory has been allocated.
This turns your system into a soft real time system, but that's as close as
you get without rewriting the memory management of Linux to be capable of hard
RT allocations.
> I'm beginning to realize that there are quite a number of different
> execution contexts, each with its own largely undocumented set of
> rules. I would like to find out what "rules" there are for stack
> usage in each of these contexts.
>
> Here's what I count (so far) for execution contexts:
>
> Standard Linux
> USER MODE
> 1. linux processes
>
> KERNEL MODE
> 2. init_module()
> 3. cleanup_module()
> 4. linux device driver code
> 5. linux interrupt service routine
>
> RT Linux (all of the above plus:)
> KERNEL MODE
> 6. RTL init_module() (additional rtl_xxx functions are available)
> 7. RTL cleanup_module() "
As you note, the rtl_xxx functions are available here, but that's the only
difference from 2/3 AFAIK.
> 8. RTL fifo handler
Identical to 4, with the same exception, AFAIK.
> 9. RTL interrupt service routine
Pretty much the same as 5, with the rather important difference that this one
cannot be disabled by standard Linux, which means that you cannot safely do
everything you can from within standard Linux ISRs. (There might be additional
details as well...)
> 10 RTL processes (stack size set with pthread_attr_setstacksize())
These are real threads, but in relation to standard Linux, they have to be
veiwed as running in ISR context; ie the same restrictions WRT standard Linux as
for RTL ISRs apply.
> There may actually be more execution contexts ("environments"?) that these.
> RTLinux seems to have undocumented "rules" such as (in my words):
>
> The stack size for an RTL interrupt service routine is extremely
> limited and is not settable by the application programmer. To
> be on the safe side, an RTL ISR should use no more than 10 or 20
> bytes of stack. If an ISR overflows the stack, a system crash
> will result. It is not possible for an ISR to determine how
> much stack space it has available to it.
>
> The stack size for an RTL process can be defined in the processes's
> attribute block with the pthread_attr_setstacksize() function
> before calling pthread_create(). pthread_attr_setstacksize() is
> not found by the "man" program.
>
> In otherwords, I think the stack should be a RTL system controlled
> resource. Its use is unavoidable.
Not really; the RTL ISRs are related to RTL threads pretty much as Linux ISRs
are related to Linux user space threads. In the latter case, it's obvious that
you're supposed to do "heavier" work in user space and keep drivers as simple
as possible, and this philosophy can be applied to RTL as well in many cases.
> My wish: I would like to see RTLinux provide a way for me, the
> application programmer, to define the stack size for each of these
> contexts (#6-#9 above).
Honestly, to me that sounds like a lot of work to encourage bad application
design. Maybe there is a need for a faster and/or simpler way to promote
actual work from an ISR or handler to an RTL thread, but I'd be worried about
the risk of hiding hard RT hostile constructs below the application source
level...
> Interestingly, I did not find any information about the stack in
> Rubini's Linux Device Drivers book.
>
> Well, I feel that what I'm trying to do constitues a "real case" and
> I am definitely interested in learning more about the using of the
> stack in the RTLinux system.
Why do you use "lots" of stack space inside RTL ISRs and FIFO handlers in the
first place?
Whatever is done in the RTL ISRs will interfere with the scheduling of RTL
threads if it takes too long - any heavier processing should generally be done
in threads to allow more control over the timing.
As to FIFO handlers, these are actually standard Linux syscalls, and (unless
you're analysing the timing of your user space tasks) there's no reason to
consider this code hard RT. Any processing that's done there now might as well
be done in user space - that would be just as (non)deterministic, and would
eliminate the stack problem. Protected memory is an extra bonus.
> I haven't had the chance to review RTAI but I would also be interested
> in a discussion from that camp.
The basic principles are the same, of course (Linux, x86 and even based on the
same idea), but I don't know if RTAI has special features in this area.
David Olofson
Programmer
Reologica Instruments AB
[EMAIL PROTECTED]
..- M u C o S --------------------------------. .- David Olofson ------.
| A Free/Open Multimedia | | Audio Hacker |
| Plugin and Integration Standard | | Linux Advocate |
`------------> http://www.linuxdj.com/mucos -' | Open Source Advocate |
..- A u d i a l i t y ------------------------. | Singer |
| Rock Solid Low Latency Signal Processing | | Songwriter |
`---> http://www.angelfire.com/or/audiality -' `-> [EMAIL PROTECTED] -'
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
---
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/