Subject: Re: But why?
To: David S. Miller <davem@caip.rutgers.edu>
From: Larry McVoy <lm@neteng.engr.sgi.com>
List: tech-kern
Date: 10/22/1996 14:39:10
:    I disagree with "broken", except if you generalize it to "inefficient".
:    Your fanaticism is showing :)
: 
: I'm not the only one who calls it "broken" openly.  Larry McVoy and
: several engineers at SGI (and Sun, both past and present) have heard
: my complete argument and standpoint, all of them agree with me that
: the BSD/At&T unix way of doing system calls is indeed "broken" just as
: I have stated it and that the Linux method is clearly the superior one
: that exists today.

Broken is too strong a word, but stupid is definitely not too strong a word.
Linux has a better system call design, they do the work required when it is
required, not every time.  The main issue is signal handling and restarting
system calls; Linux unravels the mess if they have to restart, not every
time.  Most Unix implementations save enough state to restart every time
they enter the kernel, which is a lot of extra work.

I think a more important observation is that Linus & David & Co. have a
philosophy that is different than commercial or standard OS development.
In the "normal" world, people add "features" or implement "designs" and
claim success when they benchmark their new feature against the old system 
and it is no slower.  For example, suppose you were to add mandatory locking
to your Unix.  Suppose the way you did it added a few extra cache misses
in a relatively long code path.  Benchmarking that would show little or
no difference, so it is easy to claim success.

In the Linux world, it works upside down from that.  The performance
weenies think about were cache misses are likely to happen and go get
rid of them.  New features are added in such a way that they introduce
no new cache misses, or at least no new unexpected ones (sometimes ya
gotta do what ya gotta do).  But the point is that the OS people have a 
mental image of the critical code path and what that code path costs. 
Additions to the code path are heavily discouraged.

The philosophy is, to crib from Colin Fletcher (the backpacker guy)
"You take care of the cache misses and the performance will take care of 
itself".  (He actually said "You take care of the ounces and the pounds
take care of themself".)

I'm not trying to imply that others don't think this is a good idea.  I
am trying to imply that most people buy off on the philosophy but do
little more than give it lip service.  The Linux crowd seems to eat
and breathe that sort of thinking; I like that.

:    >>    You'd think that when people put together function call conventions
:    >>    for a particular processor, the OS people would take a look at this
:    >>    and find a way to take advantage of this.  In fact, believe it or
:    >>    not, they have not to this very day.
: 
:    Actually, OS people have done this A LOT.  Just look at L3.
:    Microkernel dudes have put out plethoras of papers on reducing system
:    call overhead, particularly since their system calls require two
:    kernel-boundary crossings.
:    Critical code paths are not unrepresented in the literature.

So get lmbench numbers for a Microkernel.  QNX posted theirs in days after 
I released the benchmark.  It's been over a year (maybe two) and no results
from the uKernel camps.  Why not?

:    It is definitely faster.  However, the thing you haven't answered here
:    is "what do you lose by doing it this way?".  The answer is "portability".
:    You now have to write the backend of every system call in assembler
:    (but see below!).

I think you should go study it a bit.  You do need to do some unraveling
at signal dispatch but it is the sort of stuff you typically do in the
kernel; it's all standard locore techniques; our kernel engineers here
have looked at it and understood immediately the idea.

: Larry McVoy has even stated the above publicly.

Sure have.  I think there may be a few corner cases that I havent tested
for, but in general, you get standard Unix semantics faster.

: It is broken because it does not allow the programmer to express very
: natural things to it, like the way GCC does.  

GCC is pretty cool.  It has a lot of useful stuff that the commercial
vendors haven't picked up yet.  The inlining works, the assembler
interface is good, the -Wall is great (checks printf strings and
lints them against the arguments).  Etc.

:    Although I realize you are enthusiastic (and should be, especially if
:    you are trying to "convert" people over), beware of marginalizing your
:    "competitors" or their products.  You're speaking to a wide range of
:    audiences, and calling something broken when it isn't is not a good idea.

When talking to David, or other passionate kernel jocks, "broken" translates
to "not as good as it could be".  If it could bebetter, it is "broken".  It's
a nice, albeit unusual, definition of "broken".  It is not the normal
"it gives you the wrong answer" sort of broken.


Wow, look, I speak a foreign  language, I speak the Linux dialect of Kernel :-)