The fundamental thing is that we can _never_ return early out of
swap_out(). There are no local decisions we can make that make any sense.
The fact that we're out of swap-space is only meaningful _after_ we've
verified that we have no shared mappings.
Now, there _is_ another approach we can take, which is to notice _before_
we call swap_out() that it's not going to help us. With all anonymous
pages on the LRU list, we do have enough information in shrink_caches() to
notice that the pages we want to get rid of require backing store: that's
as easy as seeing "page->mapping == NULL".
But we can not make that decision in swap_out(), and any code that _tries_
to make that decision is clearly bogus.
Which is, indeed, why I feel strongly that swap_out() needs to be "void".
(Well, right now it technically isn't, but we ignore the value it returns,
so it doesn't much matter ;).
But in shrink_cache(), we could add something like
- increment a count every time we see a page with a mapping, and in the
right memory zone: all such pages _can_ be dropped and do not need
swap-space.
- add logic somewhat like
if (nr_swap_pages || page_mapping_count > 5%)
we're not oom
(note that "page_mapping_count" in _theory_ is the same as
"page_cache_size", except that we need to count only pages in the right
zones. It doesn't help us if we have tons of highmem pages free, if we're
unable to get rid of normal pages. There are simply too many things that
can not use the high pages, and we have to consider that to be oom).
Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/