/* * This moves pages from the active list to * the inactive list. * * We move them the other way when we see the * reference bit on the page. */ static void refill_inactive(int nr_pages, zone_t * classzone) { struct list_head * entry; unsigned long ratio; ratio = (unsigned long) nr_pages * classzone->nr_active_pages / (((unsigned long) classzone->nr_inactive_pages * vm_lru_balance_ratio) + 1); entry = active_list.prev; while (ratio && entry != &active_list) { struct page * page; page = list_entry(entry, struct page, lru); entry = entry->prev; if (PageTestandClearReferenced(page)) { list_del(&page->lru); list_add(&page->lru, &active_list); continue; } ratio--; del_page_from_active_list(page); add_page_to_inactive_list(page); SetPageReferenced(page); } if (entry != &active_list) { list_del(&active_list); list_add(&active_list, entry); } }
/* * This moves pages from the active list to * the inactive list. * * We move them the other way when we see the * reference bit on the page. */ static void refill_inactive(int nr_pages) { struct list_head * entry; spin_lock(&pagemap_lru_lock); entry = active_list.prev; while (nr_pages && entry != &active_list) { struct page * page; page = list_entry(entry, struct page, lru); entry = entry->prev; if (PageTestandClearReferenced(page)) { list_del(&page->lru); list_add(&page->lru, &active_list); continue; } nr_pages--; del_page_from_active_list(page); add_page_to_inactive_list(page); SetPageReferenced(page); } spin_unlock(&pagemap_lru_lock); }
/* * Isolate one page from the LRU lists. If successful put it onto * the indicated list with elevated page count. * * Result: * -EBUSY: page not on LRU list * 0: page removed from LRU list and added to the specified list. */ int isolate_lru_page(struct page *page, struct list_head *pagelist) { int ret = -EBUSY; if (PageLRU(page)) { struct zone *zone = page_zone(page); spin_lock_irq(&zone->lru_lock); if (PageLRU(page) && get_page_unless_zero(page)) { ret = 0; ClearPageLRU(page); if (PageActive(page)) del_page_from_active_list(zone, page); else del_page_from_inactive_list(zone, page); list_add_tail(&page->lru, pagelist); } spin_unlock_irq(&zone->lru_lock); } return ret; }