/* * Writeback is about to end against a page which has been marked for immediate * reclaim. If it still appears to be reclaimable, move it to the tail of the * inactive list. The page still has PageWriteback set, which will pin it. * * We don't expect many pages to come through here, so don't bother batching * things up. * * To avoid placing the page at the tail of the LRU while PG_writeback is still * set, this function will clear PG_writeback before performing the page * motion. Do that inside the lru lock because once PG_writeback is cleared * we may not touch the page. * * Returns zero if it cleared PG_writeback. */ int rotate_reclaimable_page(struct page *page) { struct zone *zone; unsigned long flags; if (PageLocked(page)) return 1; if (PageDirty(page)) return 1; if (PageActive(page)) return 1; if (!PageLRU(page)) return 1; zone = page_zone(page); spin_lock_irqsave(&zone->lru_lock, flags); if (PageLRU(page) && !PageActive(page)) { list_del(&page->lru); list_add_tail(&page->lru, &zone->inactive_list); inc_page_state(pgrotated); } if (!test_clear_page_writeback(page)) BUG(); spin_unlock_irqrestore(&zone->lru_lock, flags); return 0; }
/* * Writeback is about to end against a page which has been marked for immediate * reclaim. If it still appears to be reclaimable, move it to the tail of the * inactive list. * * Returns zero if it cleared PG_writeback. */ int rotate_reclaimable_page(struct page *page) { struct pagevec *pvec; unsigned long flags; if (PageLocked(page)) return 1; if (PageDirty(page)) return 1; if (PageActive(page)) return 1; if (!PageLRU(page)) return 1; page_cache_get(page); local_irq_save(flags); pvec = &__get_cpu_var(lru_rotate_pvecs); if (!pagevec_add(pvec, page)) pagevec_move_tail(pvec); local_irq_restore(flags); if (!test_clear_page_writeback(page)) BUG(); return 0; }