Messages in this thread | | | Date | Mon, 13 Jul 1998 13:32:07 -0700 (PDT) | From | Linus Torvalds <> | Subject | Re: Strange interrupt behaviour |
| |
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
| |