From: drew@kinglear.cs.colorado.edu (Drew Eckhardt)
Subject: Re: Stabilizing Linux
Organization: University of Colorado at Boulder
Date: Fri, 14 Aug 1992 23:00:15 GMT

In article <1992Aug14.132232.22899@crd.ge.com> davidsen@crd.ge.com (bill davidsen) writes:
>In article <1992Aug13.195406.23296@colorado.edu>, drew@ophelia.cs.colorado.edu (Drew Eckhardt) writes:
>| In article <1992Aug13.133313.15221@crd.ge.com> davidsen@crd.ge.com (bill davidsen) writes:
>| >In article <1992Aug12.173012.17552@colorado.edu>, drew@kinglear.cs.colorado.edu (Drew Eckhardt) writes:
>| >
>| >And the person trying to install on a new machine can't rebuild the
>| >kernel, so s/he needs another working system to get going. Bleh.
>| >Relocation at load time might take 1-2 sec of cpu. Big deal. Without
>| >loadable device drivers you must have a working system to generate a new
>| >kernel.
>| 
>| Most Unices distribute the distribution kernel as a generic kernel,
>| ie one with support for all device drivers compiled in.  It gets a little
>| bloated, but if you can boot it, you can run anything.
>
>  Sounds to me like you think the Linux kernel as distributed contains
>all the devices anyone would ever want to use, so there's no need for
>being able to support new devices.

The assumption is that as new devices get added (such as Ross's 
ethernet drivers), that they will eventually make it into the 
distribution kernel, both in the sources and the generic binary.  

You can recompile (now), or relink (when a working config 
program is implemented) the kernel to add anything you need
before then - propriety GPIB driver, intelligent serial
driver, Ross's ethernet drivers, etc.

>  It also sounds like you're trying to say that you think it's too
>hard, and you personally don't need it, so you want to convince
>everyone it's a bad idea.

My opinion is that the percieved benefits (being able to add drivers at run 
time, saving a relink, rather than regenerating the kernel Makefile and 
relinking), are outweighed by the increased complexity 
of the device driver initialization, and memory allocation code.

- You add a new device driver, when one becomes available, or you
	install new hardware.  Neither is a frequent event. 

- Configuring a system, where you recompile ioconf.c or table.c, 
	and simply link in already compiled .o files for 
	everything else will take less than a minute on 
	anything that isn't thrashing - ie, a minimal 
	386 with ~4M of memory.  A reboot without fsck's 
	(ie, after a clean shutdown) about the same.

	So, you save two minutes everytime you add a new
	device driver.  I added a SCSI disk driver when I 
	finished the code, and will add a SLIP or CSLIP driver
	when one becomes stable.

	That's two drivers since last November.  

- Loadable device drivers let you shrink kernel size by leaving 
	out drivers you don't need.  You get the same effect 
	from a config program, only the kernel is even smaller because
	it doesn't need any of the hacks needed to accomodate 
	loadable drivers.  

I don't see any real benefits there.  

You can argue that loadable device drivers would make debugging 
easier for developers.  What's ideal for developers isn't necessarily 
ideal for users - ask any one who used the early, non-interrupt 
driven versions of the SCSI drivers.  They'll tell you about the 
wonderful interactive performance, and that the system would 
never hang for ~30 seconds while the disk(s) synced.  

When I did the SCSI code, I put in support for both interrupt, and 
non-interrupt driven SCSI drivers, thinking that "It would be 
much easier to debug the non-interrupt driven version."  It was
marginally easier, and all of the initial SCSI efforts ended up 
being of the non-interrupt driven variety that were the bane 
of SCSI users. It took us some time to debug the interrupt code (
one line needed moving in scsi.c), modify all of the 
lowlevel drivers, and get it back into the "stock" Linux distribution.

Interrupt driven SCSI drivers didn't make the stock distribution until
.97, and we've had SCSI versions since .12, support in the 
stock distribution since .95.

It's easier to do it right the first time, and avoid things of 
questionable value that may come back to haunt you.

I don't know that loadable device drivers would help that much 
during code development.  Much of the time is spent in design
and coding.  With device drivers, there are good chances of a 
bad device driver (ie wild pointer) corrupting the rest of the 
system.  Even if you can unload the driver, recompile, and load a 
new one, you may not want to, because something may have 
become corrupt in the rest of the system.  If you are booting 
from harddisk, the reboot-test cycle is not that bad.

I wouldn't say that loadable device drivers are "too hard" to implement - 
just that the added mess in the Linux code, and time it would take 
to do so aren't worth the benefits.

Linux is not a completely clean design.  Isolation between the 
various parts is not absolute.  Especially in the cases of 
pseudo-devices, like the lowlevel SCSI drivers, there is an
incestuous relationship between the driver code and the surrounding 
kernel.  The hard disk and SCSI drivers have special consideration 
given to them in ll_rw_block.c so they can get multi-block 
requests as one device driver request.  All of this would 
have to change, and in some cases, you may get nicer (but 
less tight) code.  

Like BSD, Linux uses certain "pseudo-devices."  These have 
a different interface than the normal block/character devices,
and will need special handling code.  Examples would include 
SYSV STREAMS, BSD network drivers, the Linux low level 
SCSI code.

Different parts of Linux are very dependant on eachother - for 
instance, some of the device drivers assume that kernel memory
is identity mapped.  malloc() preserves this assumption, but can 
only allocate 1 page at a time.  The same is true for get_page().

Current Linux devices have no way to "dettach" from the system,
necessary if you use loadable drivers for debugging, the only 
real reason you would want them. You need that, a way to track
what's mounted on block devices, etc.  

Current Linux code initializes all devices before the move to 
user mode, and most of it happens before buffercache, etc, is 
allocated.  (Well, sys_setup() is called from user mode, but that
just handles the partition tables on disk devices).  You'll need
to add all of the code to keep Linux happy when a new device 
is added.

It shouldn't be difficult, but I'd rather see people dedicate their
time to useful projects, like a SLIP driver for the TCP/IP package, 
a new VM using one page table per process to ease VM386 support,
remove the 64 process limit, increase the address space size, and 
support SYSV sghared memory semantics.  

Personally, I'll finish the SCSI driver rewrite (Experiments show that 
we can expect 3X current performance on unbuffered disks with 1K block file 
systems, 2 block read ahead, 12X if we move to 4K block sizes on the 
new file systems.  Buffered devices will see SOME improvement, I don';t
have one and can't say how much.) before playing with something useless.  






-- 
Microsoft is responsible for propogating the evils it calls DOS and Windows, 
IBM for AIX (appropriately called Aches by those having to administer it), but neither is as bad as AT&T.  Boycott AT&T, and let them know how you feel. 

Newsgroups: comp.os.linux