Commit 9bdedfce authored by Andrew Morton's avatar Andrew Morton Committed by Oleg Drokin

[PATCH] Fix a race between __page_cache_release() and shrink_cache()

__page_cache_release() needs to recheck the page count inside the LRU
lock, because shrink_cache() may have found the page on the LRU and
incremented its refcount again.

Which is carefully documented over __pagevec_release().  Duh.
parent ac31cf70
...@@ -81,14 +81,17 @@ void __page_cache_release(struct page *page) ...@@ -81,14 +81,17 @@ void __page_cache_release(struct page *page)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&_pagemap_lru_lock, flags); spin_lock_irqsave(&_pagemap_lru_lock, flags);
if (!TestClearPageLRU(page)) if (TestClearPageLRU(page)) {
BUG();
if (PageActive(page)) if (PageActive(page))
del_page_from_active_list(page); del_page_from_active_list(page);
else else
del_page_from_inactive_list(page); del_page_from_inactive_list(page);
}
if (page_count(page) != 0)
page = NULL;
spin_unlock_irqrestore(&_pagemap_lru_lock, flags); spin_unlock_irqrestore(&_pagemap_lru_lock, flags);
} }
if (page)
__free_pages_ok(page, 0); __free_pages_ok(page, 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment