[2.1.98] - It compiled and I ran...

Ian and Iris (brooke@jump.net)
Fri, 24 Apr 1998 13:42:09 -0500


Then I decided to run my new kernel 2.1.98.

2.1.98 seems to do very well on my machine. Sound works great, and it
DOES BOOT. Printing works, and tcp/ip over ppp seems not to suck too
much. (I think that some routers may not like linux, as I get no freezes
on win95.) The swapping starts to get pretty hairy when netscape is
running and I start WINE, but WINE does start, which is good.

The box is p166mmx 32mb ide up, mss sound and dual-boot.

People have mentioned a configurably aggressive kswapd. Here is my two
cents, without so much as LOOKING at the code, but rather from
overhearing the hot debates:

When looking for free 128k blocks eg for DMA xfers, rather than actually
SWAPPING, consider the very valid option of not kicking ANY memory out.
Do a lazy single pass at defragmenting just enough main memory. You can
do that - it's all virtual, anyway. Just copy the memory, update some
page table somewhere, and voila - a free large block. I'll warrant it's
faster than waiting for ANY hard drive. You can even invent "good"
mem-move policies, eg:

1. Find biggest free block within DMA availible range.
2. Move memory from either side out of the way, like up high in the
memory space where ISA DMA can't happen.
3. Coalesce free blocks.

This costs slightly more initially than kicking out a random block of
128k of cache, but if the average re-read percentage is big enough, it
may be worth it. This will be affected by the size of what's already in
cache. It may be a good idea to run a quick cost estimate of doing
things either way. With lots in cache, you may not care about
"forgetting". With lots in state, you just might rather defrag some than
swap.

If you really run low on main memory (under some ADAPTIVE threshold) or
if the defrag-attempt does not help, go ahead and kick pages. But
consider two other things:
Kicking a cache (code, static data, file system structure) page costs
when (if) the disk block is accessed again. Kicking a state (stack,
heap) page costs when the decision is made to kick, and AGAIN if the
page is needed again, and I'll warant it will be. This means that
kicking cache has average cost less than one, and kicking state has
average cost greater than one. The only problem is that the units are
different. The cost of swapping is that of the swap device. The cost of
rereading a page of disk is the cost of the disk. Unless these are
significantly different (eg nfs over isdn) then it only makes sense to
kick cache, not state, where possible. Worried about running out of
memory on your 16-32 mb personal machine from X, Netscape, Emacs, and
GCC all running at once? Demand loading and cache-kicking works against
the executable taking up too much memory. If state memory lacks, then go
ahead, swap. But only swap STATE. Understand the cost of what you are
doing when your algorithm makes a decicion about how to free some core.

There are some things which make this better:

Take advantage of idle time on the swap device. If there's free space in
swap, and disk time to spare, copy (lru? random?) dirty pages of state
to the swap device, just so that when the time comes to kick out pages,
you have some state pages whose kick-cost is similar to that of cache.

When choosing a page to kick, don't use strict priorities. Instead give
each page type a weighted, random chance. Let that weight be assigned
dynamically based on the percentage of that page type in core and the
average cost of kicking it.

Now, let's take full advantage of the "free memory" scenario: When
reading executable images or mmapping, consider a large read-ahead, and
dumping the unrequested pages immediately on the LRU list, somewhere
near, but not quite at, the end. This takes proactive advantage of
locality of reference. This also helps versus the following scenario:

Process A and process B both want to read a byte at a time, and process
it. Process A will wait until the next byte is availible to process. So
will process B. Process A wants data from the beginning of the disk.
Process B wants data from the end. A submits a request to read. The IO
subsystem queues the request, and A goes to sleep. Process B takes the
helm and instantly requests a faraway read. The IO queues the request.
Later, process A wakes up with data. It queues a request shortly after
the first, but already IO has gone off to service B's request. By the
time A's next request is fulfilled, B has already finished processing
its data and wants another block shortly BEFORE the last. As we can see,
this quickly leads to less than ideal seeking behavior. The larger the
read ahead, in this scenario, the better. Granted, this is a
particularly bad case, but consider starting netscape, or even gunzip.
If we can afford it at the time in terms of free memory, we may as well
do it. It has a value. It may improve interactive performance, and data
which is LIKELY to be used is better to have in core than a block of
zeros.

The fundamental idea here is analyze the cost of an operation IN CONTEXT
to decide how best to obtain a needed resource. When the O/S is doing
this inteligently, it's going to be faster.

Now, I'll get off my soap box and go start twiddling code.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu