Change in try_to_free_page(): just my opinion.

Gerard Roudier (
Thu, 8 May 1997 20:21:13 +0000 (GMT)

Here is the loop that seems to make problems:

switch (state) {
do {
case 0:
if (shrink_mmap(i, dma))
return 1;
state = 1;
case 1:
if (shm_swap(i, dma))
return 1;
state = 2;
if (swap_out(i, dma, wait))
return 1;
state = 0;
} while ((i - stop) >= 0);

That is not a code construction I use to deal with.

If the loop begins with state=0, all the functions are called with the
same priority (i) for i=6,5,... until one of them returns not zero, meaning
at least 1 page has been freed.

BUT when state is not zero, the first 2 functions may not be called for
the first value of i (lowest priority).
That balances probably very well when the system is not under memory
stress, but is quite useless when it is.
The author probably wanted to call the functions in a circular way and to
restart just after the one which returns ok the last time.

If this loop fails when wait!=0 => stop=0, that means that all functions
returned 0 (no page freed) for i=0 (max priority).

The patch in 2.0.31 does the following:

- call schedule()
- set stop=9 ????, let i unchanged
- go back to the loop.

In my opinion, the author wanted to do something like the following:

if (wait) {
i = 0; (or some other initial priority)
goto we_slept;

If this change fixes things, why to not use it.

However, it seems to me that such situation has very fiew chance to happen,
unless the memory is requested as DMAable.