2017-11-01 15:07:57 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2008-10-18 20:26:30 -07:00
|
|
|
#ifndef LINUX_MM_INLINE_H
|
|
|
|
|
#define LINUX_MM_INLINE_H
|
|
|
|
|
|
2011-01-13 15:47:13 -08:00
|
|
|
#include <linux/huge_mm.h>
|
2013-09-11 14:22:36 -07:00
|
|
|
#include <linux/swap.h>
|
2011-01-13 15:47:13 -08:00
|
|
|
|
2008-10-18 20:26:30 -07:00
|
|
|
/**
|
2021-02-25 09:47:41 -05:00
|
|
|
* folio_is_file_lru - Should the folio be on a file LRU or anon LRU?
|
|
|
|
|
* @folio: The folio to test.
|
2008-10-18 20:26:30 -07:00
|
|
|
*
|
|
|
|
|
* We would like to get this info without a page flag, but the state
|
2021-02-25 09:47:41 -05:00
|
|
|
* needs to survive until the folio is last deleted from the LRU, which
|
2008-10-18 20:26:30 -07:00
|
|
|
* could be as far down as __page_cache_release.
|
2021-02-25 09:47:41 -05:00
|
|
|
*
|
|
|
|
|
* Return: An integer (not a boolean!) used to sort a folio onto the
|
|
|
|
|
* right LRU list and to account folios correctly.
|
|
|
|
|
* 1 if @folio is a regular filesystem backed page cache folio
|
|
|
|
|
* or a lazily freed anonymous folio (e.g. via MADV_FREE).
|
|
|
|
|
* 0 if @folio is a normal anonymous folio, a tmpfs folio or otherwise
|
|
|
|
|
* ram or swap backed folio.
|
2008-10-18 20:26:30 -07:00
|
|
|
*/
|
2021-02-25 09:47:41 -05:00
|
|
|
static inline int folio_is_file_lru(struct folio *folio)
|
|
|
|
|
{
|
|
|
|
|
return !folio_test_swapbacked(folio);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-06 20:04:41 -07:00
|
|
|
static inline int page_is_file_lru(struct page *page)
|
2008-10-18 20:26:30 -07:00
|
|
|
{
|
2021-02-25 09:47:41 -05:00
|
|
|
return folio_is_file_lru(page_folio(page));
|
2008-10-18 20:26:30 -07:00
|
|
|
}
|
|
|
|
|
|
2021-02-24 12:08:40 -08:00
|
|
|
static __always_inline void update_lru_size(struct lruvec *lruvec,
|
2016-07-28 15:45:31 -07:00
|
|
|
enum lru_list lru, enum zone_type zid,
|
2021-02-25 09:47:41 -05:00
|
|
|
long nr_pages)
|
2016-05-19 17:12:38 -07:00
|
|
|
{
|
2016-07-28 15:45:31 -07:00
|
|
|
struct pglist_data *pgdat = lruvec_pgdat(lruvec);
|
|
|
|
|
|
2019-05-13 17:17:57 -07:00
|
|
|
__mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages);
|
2016-07-28 15:47:26 -07:00
|
|
|
__mod_zone_page_state(&pgdat->node_zones[zid],
|
|
|
|
|
NR_ZONE_LRU_BASE + lru, nr_pages);
|
2016-07-28 15:47:17 -07:00
|
|
|
#ifdef CONFIG_MEMCG
|
2017-01-10 16:58:04 -08:00
|
|
|
mem_cgroup_update_lru_size(lruvec, lru, zid, nr_pages);
|
2016-05-19 17:12:38 -07:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-12 17:20:04 -08:00
|
|
|
/**
|
2021-02-25 09:47:41 -05:00
|
|
|
* __folio_clear_lru_flags - Clear page lru flags before releasing a page.
|
|
|
|
|
* @folio: The folio that was on lru and now has a zero reference.
|
2012-01-12 17:20:04 -08:00
|
|
|
*/
|
2021-02-25 09:47:41 -05:00
|
|
|
static __always_inline void __folio_clear_lru_flags(struct folio *folio)
|
2005-04-16 15:20:36 -07:00
|
|
|
{
|
2021-02-25 09:47:41 -05:00
|
|
|
VM_BUG_ON_FOLIO(!folio_test_lru(folio), folio);
|
2021-02-24 12:08:32 -08:00
|
|
|
|
2021-02-25 09:47:41 -05:00
|
|
|
__folio_clear_lru(folio);
|
2008-10-18 20:26:14 -07:00
|
|
|
|
2021-02-24 12:08:28 -08:00
|
|
|
/* this shouldn't happen, so leave the flags to bad_page() */
|
2021-02-25 09:47:41 -05:00
|
|
|
if (folio_test_active(folio) && folio_test_unevictable(folio))
|
2021-02-24 12:08:28 -08:00
|
|
|
return;
|
|
|
|
|
|
2021-02-25 09:47:41 -05:00
|
|
|
__folio_clear_active(folio);
|
|
|
|
|
__folio_clear_unevictable(folio);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static __always_inline void __clear_page_lru_flags(struct page *page)
|
|
|
|
|
{
|
|
|
|
|
__folio_clear_lru_flags(page_folio(page));
|
2005-04-16 15:20:36 -07:00
|
|
|
}
|
2006-01-08 01:00:45 -08:00
|
|
|
|
2008-10-18 20:26:14 -07:00
|
|
|
/**
|
2021-02-25 09:47:41 -05:00
|
|
|
* folio_lru_list - Which LRU list should a folio be on?
|
|
|
|
|
* @folio: The folio to test.
|
2008-10-18 20:26:14 -07:00
|
|
|
*
|
2021-02-25 09:47:41 -05:00
|
|
|
* Return: The LRU list a folio should be on, as an index
|
2008-10-18 20:26:14 -07:00
|
|
|
* into the array of LRU lists.
|
|
|
|
|
*/
|
2021-02-25 09:47:41 -05:00
|
|
|
static __always_inline enum lru_list folio_lru_list(struct folio *folio)
|
2008-10-18 20:26:14 -07:00
|
|
|
{
|
2009-09-21 17:02:58 -07:00
|
|
|
enum lru_list lru;
|
2008-10-18 20:26:14 -07:00
|
|
|
|
2021-02-25 09:47:41 -05:00
|
|
|
VM_BUG_ON_FOLIO(folio_test_active(folio) && folio_test_unevictable(folio), folio);
|
2021-02-24 12:08:32 -08:00
|
|
|
|
2021-02-25 09:47:41 -05:00
|
|
|
if (folio_test_unevictable(folio))
|
2021-02-24 12:08:36 -08:00
|
|
|
return LRU_UNEVICTABLE;
|
|
|
|
|
|
2021-02-25 09:47:41 -05:00
|
|
|
lru = folio_is_file_lru(folio) ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON;
|
|
|
|
|
if (folio_test_active(folio))
|
2021-02-24 12:08:36 -08:00
|
|
|
lru += LRU_ACTIVE;
|
|
|
|
|
|
2008-10-18 20:26:14 -07:00
|
|
|
return lru;
|
|
|
|
|
}
|
2021-02-24 12:08:13 -08:00
|
|
|
|
2021-02-25 09:47:41 -05:00
|
|
|
static __always_inline
|
|
|
|
|
void lruvec_add_folio(struct lruvec *lruvec, struct folio *folio)
|
|
|
|
|
{
|
|
|
|
|
enum lru_list lru = folio_lru_list(folio);
|
|
|
|
|
|
|
|
|
|
update_lru_size(lruvec, lru, folio_zonenum(folio),
|
|
|
|
|
folio_nr_pages(folio));
|
|
|
|
|
list_add(&folio->lru, &lruvec->lists[lru]);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-24 12:08:13 -08:00
|
|
|
static __always_inline void add_page_to_lru_list(struct page *page,
|
2021-02-24 12:08:17 -08:00
|
|
|
struct lruvec *lruvec)
|
2021-02-24 12:08:13 -08:00
|
|
|
{
|
2021-02-25 09:47:41 -05:00
|
|
|
lruvec_add_folio(lruvec, page_folio(page));
|
|
|
|
|
}
|
2021-02-24 12:08:17 -08:00
|
|
|
|
2021-02-25 09:47:41 -05:00
|
|
|
static __always_inline
|
|
|
|
|
void lruvec_add_folio_tail(struct lruvec *lruvec, struct folio *folio)
|
|
|
|
|
{
|
|
|
|
|
enum lru_list lru = folio_lru_list(folio);
|
|
|
|
|
|
|
|
|
|
update_lru_size(lruvec, lru, folio_zonenum(folio),
|
|
|
|
|
folio_nr_pages(folio));
|
|
|
|
|
list_add_tail(&folio->lru, &lruvec->lists[lru]);
|
2021-02-24 12:08:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static __always_inline void add_page_to_lru_list_tail(struct page *page,
|
2021-02-24 12:08:17 -08:00
|
|
|
struct lruvec *lruvec)
|
2021-02-24 12:08:13 -08:00
|
|
|
{
|
2021-02-25 09:47:41 -05:00
|
|
|
lruvec_add_folio_tail(lruvec, page_folio(page));
|
|
|
|
|
}
|
2021-02-24 12:08:17 -08:00
|
|
|
|
2021-02-25 09:47:41 -05:00
|
|
|
static __always_inline
|
|
|
|
|
void lruvec_del_folio(struct lruvec *lruvec, struct folio *folio)
|
|
|
|
|
{
|
|
|
|
|
list_del(&folio->lru);
|
|
|
|
|
update_lru_size(lruvec, folio_lru_list(folio), folio_zonenum(folio),
|
|
|
|
|
-folio_nr_pages(folio));
|
2021-02-24 12:08:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static __always_inline void del_page_from_lru_list(struct page *page,
|
2021-02-24 12:08:25 -08:00
|
|
|
struct lruvec *lruvec)
|
2021-02-24 12:08:13 -08:00
|
|
|
{
|
2021-02-25 09:47:41 -05:00
|
|
|
lruvec_del_folio(lruvec, page_folio(page));
|
2021-02-24 12:08:13 -08:00
|
|
|
}
|
2008-10-18 20:26:30 -07:00
|
|
|
#endif
|