Re: More on lockups in 2.0.30

Dr. Werner Fink (werner@suse.de)
Wed, 4 Jun 1997 17:32:48 +0200


> A few days ago, I described how "dd if=/dev/hda of=/dev/null bs=1k count=102400"
> would lock up a machine with 16MB of RAM and a 2.0.30 kernel.
>
> I've been playing with /proc/sys/vm/freepages and have these results:
> 200 300 400 OK,
> 150 225 300 OK,
> 140 210 280 OK,
> 130 195 260 fails immediately,
> 140 210 260 fails immediately,
> 130 210 280 fails after a few seconds.
> The last two are interesting.
>
> Looking through fs/buffer.c, I found this code at about line #609:
> while (nr_free_pages > min_free_pages*2 && needed > 0 &&
> grow_buffers(GFP_BUFFER, size)) {
> needed -= PAGE_SIZE;
> }
>
> I tried replacing min_free_pages*2 with free_pages_high since they normally have
> the same value. In this case, the above mesasurements are the same except that
> the 130 210 280 test always succeeds.
>
> These numbers are quite a bit larger than the defaults, so maybe the defaults
> should be changed.

Hmmm ... IMHO this is only a symptom but not the reason for. Let's have a look
into 2.0.29 fs/buffer.c (line 580 to 596) there is a code sequence:

while(maybe_shrink_lav_buffers(size))
{
if(!grow_buffers(GFP_BUFFER, size)) break;
needed -= PAGE_SIZE;
if(needed <= 0) return;
};

which is removed together with other code sequences (because this stuff is
not used and in some cases run into trouble ??). But ... one side effect
of this code is calling grow_buffers often more than without, isn't it?
... which slows down refill_freelist() _and_ leads to a higher success
rate in getting a free page. Therefore the behaviour in 2.0.29 is not as
often triggered as in 2.0.30.

Some of the bugs found in fs/buffer.c of 2.0.30 are found in fs/buffer.c of
2.0.29 too.

Maybe on problem is: How to swap out unused pages to get free pages in
refill_freelist()? The function grow_buffers calls at least __get_free_pages()
in mm/page_alloc.c. In __get_free_pages() the function try_to_free_page()
of mm/vmscan.c is called only for non buffer pages to avoid dead locks.
try_to_free_page() would call shrink_mmap() which is not useful at the same
time when requesting buffer pages. There is no equivalent function to get
free pages for buffer by swapping out non buffer pages.

Werner