#include <linux/swap.h>
/**
- * page_is_file_lru - should the page be on a file LRU or anon LRU?
- * @page: the page to test
- *
- * Returns 1 if @page is a regular filesystem backed page cache page or a lazily
- * freed anonymous page (e.g. via MADV_FREE). Returns 0 if @page is a normal
- * anonymous page, a tmpfs page or otherwise ram or swap backed page. Used by
- * functions that manipulate the LRU lists, to sort a page onto the right LRU
- * list.
+ * pageset_is_file_lru - Should the pageset be on a file LRU or anon LRU?
+ * @pageset: The pageset to test.
*
* We would like to get this info without a page flag, but the state
- * needs to survive until the page is last deleted from the LRU, which
+ * needs to survive until the pageset is last deleted from the LRU, which
* could be as far down as __page_cache_release.
+ *
+ * Return: An integer (not a boolean!) used to sort a pageset onto the
+ * right LRU list and to account pagesets correctly.
+ * 1 if @pageset is a regular filesystem backed page cache pageset
+ * or a lazily freed anonymous pageset (e.g. via MADV_FREE).
+ * 0 if @pageset is a normal anonymous pageset, a tmpfs pageset or otherwise
+ * ram or swap backed pageset.
*/
+static inline int pageset_is_file_lru(struct pageset *pageset)
+{
+ return !pageset_test_swapbacked(pageset);
+}
+
static inline int page_is_file_lru(struct page *page)
{
- return !PageSwapBacked(page);
+ return pageset_is_file_lru(page_pageset(page));
}
static __always_inline void update_lru_size(struct lruvec *lruvec,
enum lru_list lru, enum zone_type zid,
- int nr_pages)
+ long nr_pages)
{
struct pglist_data *pgdat = lruvec_pgdat(lruvec);
}
/**
- * __clear_page_lru_flags - clear page lru flags before releasing a page
- * @page: the page that was on lru and now has a zero reference
+ * __pageset_clear_lru_flags - Clear page lru flags before releasing a page.
+ * @pageset: The pageset that was on lru and now has a zero reference.
*/
-static __always_inline void __clear_page_lru_flags(struct page *page)
+static __always_inline void __pageset_clear_lru_flags(struct pageset *pageset)
{
- VM_BUG_ON_PAGE(!PageLRU(page), page);
+ VM_BUG_ON_PAGESET(!pageset_test_lru(pageset), pageset);
- __ClearPageLRU(page);
+ __pageset_clear_lru(pageset);
/* this shouldn't happen, so leave the flags to bad_page() */
- if (PageActive(page) && PageUnevictable(page))
+ if (pageset_test_active(pageset) && pageset_test_unevictable(pageset))
return;
- __ClearPageActive(page);
- __ClearPageUnevictable(page);
+ __pageset_clear_active(pageset);
+ __pageset_clear_unevictable(pageset);
+}
+
+static __always_inline void __clear_page_lru_flags(struct page *page)
+{
+ __pageset_clear_lru_flags(page_pageset(page));
}
/**
- * page_lru - which LRU list should a page be on?
- * @page: the page to test
+ * pageset_lru_list - Which LRU list should a pageset be on?
+ * @pageset: The pageset to test.
*
- * Returns the LRU list a page should be on, as an index
+ * Return: The LRU list a pageset should be on, as an index
* into the array of LRU lists.
*/
-static __always_inline enum lru_list page_lru(struct page *page)
+static __always_inline enum lru_list pageset_lru_list(struct pageset *pageset)
{
enum lru_list lru;
- VM_BUG_ON_PAGE(PageActive(page) && PageUnevictable(page), page);
+ VM_BUG_ON_PAGESET(pageset_test_active(pageset) && pageset_test_unevictable(pageset), pageset);
- if (PageUnevictable(page))
+ if (pageset_test_unevictable(pageset))
return LRU_UNEVICTABLE;
- lru = page_is_file_lru(page) ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON;
- if (PageActive(page))
+ lru = pageset_is_file_lru(pageset) ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON;
+ if (pageset_test_active(pageset))
lru += LRU_ACTIVE;
return lru;
}
+static __always_inline
+void lruvec_add_pageset(struct lruvec *lruvec, struct pageset *pageset)
+{
+ enum lru_list lru = pageset_lru_list(pageset);
+
+ update_lru_size(lruvec, lru, pageset_zonenum(pageset),
+ pageset_nr_pages(pageset));
+ list_add(&pageset->lru, &lruvec->lists[lru]);
+}
+
static __always_inline void add_page_to_lru_list(struct page *page,
struct lruvec *lruvec)
{
- enum lru_list lru = page_lru(page);
+ lruvec_add_pageset(lruvec, page_pageset(page));
+}
- update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page));
- list_add(&page->lru, &lruvec->lists[lru]);
+static __always_inline
+void lruvec_add_pageset_tail(struct lruvec *lruvec, struct pageset *pageset)
+{
+ enum lru_list lru = pageset_lru_list(pageset);
+
+ update_lru_size(lruvec, lru, pageset_zonenum(pageset),
+ pageset_nr_pages(pageset));
+ list_add_tail(&pageset->lru, &lruvec->lists[lru]);
}
static __always_inline void add_page_to_lru_list_tail(struct page *page,
struct lruvec *lruvec)
{
- enum lru_list lru = page_lru(page);
+ lruvec_add_pageset_tail(lruvec, page_pageset(page));
+}
- update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page));
- list_add_tail(&page->lru, &lruvec->lists[lru]);
+static __always_inline
+void lruvec_del_pageset(struct lruvec *lruvec, struct pageset *pageset)
+{
+ list_del(&pageset->lru);
+ update_lru_size(lruvec, pageset_lru_list(pageset), pageset_zonenum(pageset),
+ -pageset_nr_pages(pageset));
}
static __always_inline void del_page_from_lru_list(struct page *page,
struct lruvec *lruvec)
{
- list_del(&page->lru);
- update_lru_size(lruvec, page_lru(page), page_zonenum(page),
- -thp_nr_pages(page));
+ lruvec_del_pageset(lruvec, page_pageset(page));
}
#endif