Re: Stability (2.2.14/15/16/17pre1)

From: Rik van Riel (riel@conectiva.com.br)
Date: Wed Jun 14 2000 - 17:22:12 EST


On Wed, 14 Jun 2000, Andrea Arcangeli wrote:

> I quote 2.2.16:

> if (nr_free_pages > freepages.high)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> goto ok_to_allocate;

[snip]

> /* Somebody needs to free pages so we free some of our own. */
> if (atomic_read(&free_before_allocate)) {
> current->flags |= PF_MEMALLOC;
> freed = try_to_free_pages(gfp_mask);

> As far as the nr_free_pages is over freepages.high (you may have
> 20 process that are trying to free memory at the same time ok?)
> then everybody is allowed to eat the pages without blocking
> while such 20 process are freeing their memory. When such 20
> processes will return and the nr_free_pages will be again only a
> mere freepages.high that isn't enough to succeed all the
> allocations.

Indeed, in theory this could happen if the difference between
freepages.high and freepages.min is less than the number of
processes waiting in try_to_free_pages.

In practice, however, things seem to behave differently...

> I guess what you wanted to do is instead something like:
>
> if (!(current->flags & PF_MEMALLOC)) {
> int freed;
> extern struct wait_queue * kswapd_wait;
>
> /* Somebody needs to free pages so we free some of our own. */
> if (atomic_read(&free_before_allocate)) {
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ do this check first
> current->flags |= PF_MEMALLOC;
> freed = try_to_free_pages(gfp_mask);
> current->flags &= ~PF_MEMALLOC;
> if (freed)
> goto ok_to_allocate;
> }
>
> if (nr_free_pages > freepages.high)
> goto ok_to_allocate;
>
> The above is fondamentally different and it would make more
> sense to me.
>
> Comments?

My original code was like this; it blew up in my face at the
first serious stress test. The reason for this is simple.

If you have multiple processes in try_to_free_pages, most likely
at least one of them will be waiting on disk. This will cause a
"pileup" of processes in try_to_free_pages, which will never stop.

One reason why it never stops is that in a lot of situations where
the VM subsystem is under load, the average time between allocations
is *less* than the time try_to_free_pages spends waiting on disk, so
we'll have a positive feedback loop ... the more processes waiting
in try_to_free_pages, the more other processes will join them.

And once this feedback loop is there, the system will slowly try
to free *all* memory, until every non-sleeping process is stuck in
try_to_free_pages on a system with 80% of memory free ;)

If you have the time you should try it ... it's kind of spectacular.

regards,

Rik

--
The Internet is not a network of computers. It is a network
of people. That is its real strength.

Wanna talk about the kernel? irc.openprojects.net / #kernelnewbies http://www.conectiva.com/ http://www.surriel.com/

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Jun 15 2000 - 21:00:33 EST