Re: Strange interrupt behaviour

Linus Torvalds (torvalds@transmeta.com)
Mon, 13 Jul 1998 13:32:07 -0700 (PDT)


On Sun, 12 Jul 1998, Gerard Roudier wrote:
> >
> > However, I'd prefer to still try out some other ways of handling this. For
> > example, "__get_free_pages()" currently only re-tries once. It shouldn't
> > be hard to make it re-try a few more times, and it might well be enough to
> > make the problem go away.
>
> This has been proven to be broken, at least with the current VM/MM stuff.
> Trying hard to get 2 contiguous pages leads very often to throw away more
> that half the available cached objects, regardless the actual memory size
> being used.

Note that we actually _do_ have code that tries to keeps memory free
enough to allocate dual pages - that's what the kswapd deamon is there
for.

One of the problems is that the kswapd deamon is completely asynchronous,
which means that yes, it will free up pages in the background, but that
doesn't help if at the moment when you wanted two pages they weren't
there: __get_free_pages() at no point tries to wait for kswapd to do its
thing. So there is memory available, it's just right now busy being
swapped out..

This is why fork() normally works, but then sometimes when the system is
busy doing a lot of things the free memory pool has been temporarily
depleted because kswapd hasn't had time to react to things yet, and you
get a fork() failure.

And this is why I think that there should be some fairly simple approach
to fixing it.. It might be as simple as a "wait for kswapd" thing after
we have failed to allocate something.

There is a second problem, which is that we often don't select the right
pool of pages to throw out. There are obvious problems on low-memory
machines that seem to get fragmented by inodes and dentries. The mm code
has code to dispose of the dentry cache when it's low on memory, but that
doesn't seem to be triggered as well as it should be (and I suspect that
one of the reasons is the code that looks like

if (((buffermem >> PAGE_SHIFT) * 100 > buffer_mem.borrow_percent * num_physpages)
|| (page_cache_size * 100 > page_cache.borrow_percent * num_physpages))
state = 0;

which will "reset" the swap-out state to try to get rid of the page cache
and the buffer cache, but it will also mean that the code that tries to
shrink the dcache won't be reached very easily.. The above code in turn
was a trial to try to get the swapper to be more aggressive in throwing
out page cache and buffer pages, and it may be that it backfired in other
ways..

Linus

-
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.altern.org/andrebalsa/doc/lkml-faq.html