Beispiel #1
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.  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;
}
Beispiel #2
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;
}