shrink_cache() detects that, inside the lock, and puts the page back
if it has a zero refcount.
refill_inactive doesn't need to do that, because it calls page_cache_release(),
which should look like this:
void __page_cache_release(struct page *page)
{
unsigned long flags;
spin_lock_irqsave(&_pagemap_lru_lock, flags);
if (TestClearPageLRU(page)) {
if (PageActive(page))
del_page_from_active_list(page);
else
del_page_from_inactive_list(page);
}
if (page_count(page) != 0)
page = NULL;
spin_unlock_irqrestore(&_pagemap_lru_lock, flags);
if (page)
__free_pages_ok(page, 0);
}
If the page count and non-LRUness are both seen inside the lock,
the page is freeable.
We do a similar thing with inodes, via atomic_dec_and_lock.
Despite the transformations, it's based on the 2.4 approach. But you've
successfully worried me, and I'm not really sure it's right, and I'm
dead sure it's too hairy. Something simpler-but-not-sucky is needed.
-
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/