upcalls

Paul Barton-Davis (pbd@Op.Net)
Wed, 30 Sep 1998 10:55:13 -0400


OK, lets try to start a sensible discussion about this.

An upcall is a mechanism that allows the kernel to execute a function
in userspace, and potentially be returned information as a result.

An upcall is like a signal, except that the kernel may use it at any
time, for any purpose, including in an interrupt handler.

This means that an upcall can potentially destroy the behaviour of the
kernel. If an interrupt handler decides to ask a user space function
for some information, and the function page faults or does blocking
IO, your kernel is quite likely trashed.

So, upcalls aren't there for everyday software development. But for
specific purposes, they can be extremely useful. Larry talked about
response times. I don't have the code in front of me, but my
recollection of the scheduler activations for Mach upcall mechanism
was roughly as follows:

(see ftp://ftp.cs.washington.edu/tr/1992/08/UW-CSE-92-08-03.PS.Z for
more details).

A process asks to use upcalls, and passes the kernel the addresses of
a series of stacks to execute upcalls on. The kernel wires down down
the stacks. The process registers functions associated with a set of
predefined events (such as a page fault or blocking I/O). When such an
event happens, the thread for which the event occured to doesn't call
schedule(), but instead switches to an upcall stack, constructs a
dummy trap return so that on return to user space it will execute the
upcall, and returns to user space via a trap return.

Even Larry will, I hope, admit that this is a pretty fast process,
much faster than a context switch, and way faster than a call to
*any* schedule().

Note however that the function *NEVER RETURNS TO THE KERNEL*,
something I'd like to differently in an upcall mechanism for Linux. I
have a recollection that we also chose to wire down the pages
containing the upcall function(s), to avoid page faulting, although in
our system, things worked (suboptimally) without this.

Mach was pretty easy to do this with: any time a thread needs to
"stop" it called thread_block(), which eventually called
thread_select() (roughly the equivalent of schedule()). We just added
some code to thread_block() and thread_select() to make them do the
right thing if the thread was marked as using upcalls.

Why would you want upcalls ? Well, we implemented upcalls specifically
for a thread package that uses an idea called scheduler activations;
every time a kernel thread blocks on I/O or suffers a page fault, the
kernel "activates" the user level thread scheduler and tells it what
happened. This way, the user level thread scheduler can continue to
use the processor by deciding to run some other thread. This solves
the problems associated with both kernel and user level threads: user
level threads have fast context switch times, but suffer badly when
blocks or page faults occur, whereas kernel threads handle blocking
and faulting very well, but have slow context switch times (which get
worse on modern CPU's). Note that SA's aren't of much use of
uniprocessor machines, although they aren't totally useless either.

In this case, the upcall mechanism is completely hidden in the thread
package (which was a drop in replacement for the Mach user level
thread library CThreads), and so you the application developer didn't
have to know anything about it - the user level thread scheduler did
the right thing.

But there are other reasons to want upcalls, as Larry has described
already. It would also allow much more precise timing for Linux user
space code, because a process could register a function (and yes, it
has to be a very carefully designed process) to be executed *by* the
timer interrupt (probably the timer code BH), not whenever the process
gets woken by the timer interrupt and then run.

Ultimately, scheduler activations are not my own choice for the best
way to handle the kernel/user thread issue. But the upcall mechanism
we relied on is a generalized method for accomplishing a variety of
ends, and I think Linux could be improved by adding it.

I'd welcome ideas on this. I'm happy to plan on implementing this, but
I'm not sure when, since most of my coding time these days is spent on
MIDI and audio applications.

--pbd

-
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/