Some of us get linux-kernel in digest mode, and "a few messages down"
means "several hours later that day".
>The counter to that is "we don't want to". Which is weak. Suppose that
>you had a system that was capable of sustaining an interrupt rate of
>X/sec. You needed to process events at Y/second where Y was slightly
>less than X. You could imagine a set of values for Y where it just
>simply wasn't an option to process this data at user level unless you
>could transition to user level for free. At that point, you're doing
>it in the driver because you have no choice. Right?
[ .. An excellent cost breakdown analysis of the in-kernel versus in-user
space approaches elided ...
]
Userspace:
> Total 46 usecs
Kernel:
> Total 15 usecs
>You tell me what you would do.
OK, I can't tell you what I would do in this case. I don't know the
nature of the computation thats done in the 5usec you postulated, how
much it depends on extensive in-memory data structures, persistent
information thats recomputed from a file periodically or whatever. It
may well be that putting it into a driver/module is the right
solution, and Linux is certainly the easiest platform I know of for
doing so.
However, let me give you a related example with which I am very
familiar that illustrates some of the difficulties of just putting it
in the driver. I'll try to make it brief(ish).
I have a music-related application that needs about 2msec resolution
in the ideal case. Given that on Intel, HZ=100 is a pretty close to
optimal setting, giving only 10msec maximal resolution in the kernel,
and 10msec +/- 5msec in userspace via sigitimer(2) or any
wake_up()-based solution. An obvious solution is to put the code into
the kernel, and get precise timing, either from the system timer
(particularly with the help of the UTIMER patch), or better yet one of
the nano-second timers present on most audio cards.
But the nature of the "central computation" in this case is intimately
connected to a GUI that fronts the program, and in some common
situations, you *CANNOT* do the computation until the relevant "timer
interrupt" is received. There's no way to compute it ahead of time,
since the computation consists of blending information from multiple,
independently timed, possibly random event streams controlled by the
GUI.
So, to put the computation in this case into the kernel also means
designing a protocol for moving the state of the GUI back-and-forth
between user-space and the kernel. This protocol isn't hard to do, but
it complicates the future evolution of the program: every time the
program is tweaked, it becomes necessary to decide whether the change
should be made in the kernel component or the userspace component. It
also means reimplementing the entire design, since you can't easily
run C++ code in the kernel. It also means adding a moderately
substantial chunk of code and a notable chunk of memory to the
kernel-side.
I still haven't decided what to do yet. Its possible that I can only
get 2msec timing by going down the module route and running the code
in the kernel. I might just stick with the currently poor time
resolution offered by sigitmer(2).
My example isn't like Richard's in most respects. But it does
illustrate that "putting it in a driver" isn't a simple
decision. Sometimes the computation that we want done with low latency
relies on a much larger framework of data manipulation, and although
we don't mind having the computation itself be in the kernel, there
are many times when it would very inappropriate to do the whole thing
there.
Sometimes, the driver route is the right one. Sometimes, its
not. Enabling behaviour in the kernel that avoids forcing the driver
solution on situations where its less than ideal seems like a nice
idea to me. Decreasing the latency associated with switching to an RT
thread after an interrupt seems like that kind of thing to me.
--p
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/