mm: reclaim invalidated page ASAP
[pandora-kernel.git] / mm / swap.c
index 1b9e4eb..0a33714 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -354,26 +354,61 @@ void add_page_to_unevictable_list(struct page *page)
  * head of the list, rather than the tail, to give the flusher
  * threads some time to write it out, as this is much more
  * effective than the single-page writeout from reclaim.
+ *
+ * If the page isn't page_mapped and dirty/writeback, the page
+ * could reclaim asap using PG_reclaim.
+ *
+ * 1. active, mapped page -> none
+ * 2. active, dirty/writeback page -> inactive, head, PG_reclaim
+ * 3. inactive, mapped page -> none
+ * 4. inactive, dirty/writeback page -> inactive, head, PG_reclaim
+ * 5. inactive, clean -> inactive, tail
+ * 6. Others -> none
+ *
+ * In 4, why it moves inactive's head, the VM expects the page would
+ * be write it out by flusher threads as this is much more effective
+ * than the single-page writeout from reclaim.
  */
 static void lru_deactivate(struct page *page, struct zone *zone)
 {
        int lru, file;
+       bool active;
 
-       if (!PageLRU(page) || !PageActive(page))
+       if (!PageLRU(page))
                return;
 
        /* Some processes are using the page */
        if (page_mapped(page))
                return;
 
+       active = PageActive(page);
+
        file = page_is_file_cache(page);
        lru = page_lru_base_type(page);
-       del_page_from_lru_list(zone, page, lru + LRU_ACTIVE);
+       del_page_from_lru_list(zone, page, lru + active);
        ClearPageActive(page);
        ClearPageReferenced(page);
        add_page_to_lru_list(zone, page, lru);
-       __count_vm_event(PGDEACTIVATE);
 
+       if (PageWriteback(page) || PageDirty(page)) {
+               /*
+                * PG_reclaim could be raced with end_page_writeback
+                * It can make readahead confusing.  But race window
+                * is _really_ small and  it's non-critical problem.
+                */
+               SetPageReclaim(page);
+       } else {
+               /*
+                * The page's writeback ends up during pagevec
+                * We moves tha page into tail of inactive.
+                */
+               list_move_tail(&page->lru, &zone->lru[lru].list);
+               mem_cgroup_rotate_reclaimable_page(page);
+               __count_vm_event(PGROTATED);
+       }
+
+       if (active)
+               __count_vm_event(PGDEACTIVATE);
        update_page_reclaim_stat(zone, page, file, 0);
 }