Beispiel #1
0
int test_clear_page_writeback(struct page *page)
{
	struct address_space *mapping = page_mapping(page);
	int ret;

	if (mapping) {
		struct backing_dev_info *bdi = mapping->backing_dev_info;
		unsigned long flags;

		spin_lock_irqsave(&mapping->tree_lock, flags);
		ret = TestClearPageWriteback(page);
		if (ret) {
			radix_tree_tag_clear(&mapping->page_tree,
						page_index(page),
						PAGECACHE_TAG_WRITEBACK);
			if (bdi_cap_account_writeback(bdi)) {
				__dec_bdi_stat(bdi, BDI_WRITEBACK);
				__bdi_writeout_inc(bdi);
			}
		}
		spin_unlock_irqrestore(&mapping->tree_lock, flags);
	} else {
		ret = TestClearPageWriteback(page);
	}
	if (ret)
		dec_zone_page_state(page, NR_WRITEBACK);
	return ret;
}
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.  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 (!TestClearPageWriteback(page))
		BUG();
	spin_unlock_irqrestore(&zone->lru_lock, flags);
	return 0;
}
Beispiel #3
0
int test_clear_page_writeback(struct page *page)
{
	struct address_space *mapping = page_mapping(page);
	int ret;

	if (mapping) {
		unsigned long flags;

		write_lock_irqsave(&mapping->tree_lock, flags);
		ret = TestClearPageWriteback(page);
		if (ret)
			radix_tree_tag_clear(&mapping->page_tree,
						page_index(page),
						PAGECACHE_TAG_WRITEBACK);
		write_unlock_irqrestore(&mapping->tree_lock, flags);
	} else {
		ret = TestClearPageWriteback(page);
	}
	return ret;
}