blob: 9cc130f5feb29c18c9038c6f107af9b673f5fd80 [file] [log] [blame]
Rik van Rielb2e18532008-10-18 20:26:30 -07001#ifndef LINUX_MM_INLINE_H
2#define LINUX_MM_INLINE_H
3
Rik van Riel2c888cf2011-01-13 15:47:13 -08004#include <linux/huge_mm.h>
Lisa Du6e543d52013-09-11 14:22:36 -07005#include <linux/swap.h>
Rik van Riel2c888cf2011-01-13 15:47:13 -08006
Mel Gormanbca67592016-07-28 15:47:05 -07007#ifdef CONFIG_HIGHMEM
8extern atomic_t highmem_file_pages;
9
10static inline void acct_highmem_file_pages(int zid, enum lru_list lru,
11 int nr_pages)
12{
13 if (is_highmem_idx(zid) && is_file_lru(lru))
14 atomic_add(nr_pages, &highmem_file_pages);
15}
16#else
17static inline void acct_highmem_file_pages(int zid, enum lru_list lru,
18 int nr_pages)
19{
20}
21#endif
22
Rik van Rielb2e18532008-10-18 20:26:30 -070023/**
24 * page_is_file_cache - should the page be on a file LRU or anon LRU?
25 * @page: the page to test
26 *
Johannes Weiner6c0b1352009-09-21 17:02:59 -070027 * Returns 1 if @page is page cache page backed by a regular filesystem,
Rik van Rielb2e18532008-10-18 20:26:30 -070028 * or 0 if @page is anonymous, tmpfs or otherwise ram or swap backed.
29 * Used by functions that manipulate the LRU lists, to sort a page
30 * onto the right LRU list.
31 *
32 * We would like to get this info without a page flag, but the state
33 * needs to survive until the page is last deleted from the LRU, which
34 * could be as far down as __page_cache_release.
35 */
36static inline int page_is_file_cache(struct page *page)
37{
Johannes Weiner6c0b1352009-09-21 17:02:59 -070038 return !PageSwapBacked(page);
Rik van Rielb2e18532008-10-18 20:26:30 -070039}
40
Hugh Dickins9d5e6a92016-05-19 17:12:38 -070041static __always_inline void __update_lru_size(struct lruvec *lruvec,
Mel Gorman599d0c92016-07-28 15:45:31 -070042 enum lru_list lru, enum zone_type zid,
43 int nr_pages)
Hugh Dickins9d5e6a92016-05-19 17:12:38 -070044{
Mel Gorman599d0c92016-07-28 15:45:31 -070045 struct pglist_data *pgdat = lruvec_pgdat(lruvec);
46
47 __mod_node_page_state(pgdat, NR_LRU_BASE + lru, nr_pages);
Minchan Kim71c799f2016-07-28 15:47:26 -070048 __mod_zone_page_state(&pgdat->node_zones[zid],
49 NR_ZONE_LRU_BASE + lru, nr_pages);
Mel Gormanbca67592016-07-28 15:47:05 -070050 acct_highmem_file_pages(zid, lru, nr_pages);
Hugh Dickins9d5e6a92016-05-19 17:12:38 -070051}
52
53static __always_inline void update_lru_size(struct lruvec *lruvec,
Mel Gorman599d0c92016-07-28 15:45:31 -070054 enum lru_list lru, enum zone_type zid,
55 int nr_pages)
Hugh Dickins9d5e6a92016-05-19 17:12:38 -070056{
Mel Gorman599d0c92016-07-28 15:45:31 -070057 __update_lru_size(lruvec, lru, zid, nr_pages);
Mel Gorman7ee36a12016-07-28 15:47:17 -070058#ifdef CONFIG_MEMCG
59 mem_cgroup_update_lru_size(lruvec, lru, nr_pages);
Hugh Dickins9d5e6a92016-05-19 17:12:38 -070060#endif
61}
62
Hugh Dickinsfa9add62012-05-29 15:07:09 -070063static __always_inline void add_page_to_lru_list(struct page *page,
64 struct lruvec *lruvec, enum lru_list lru)
Andrea Arcangeli71e3aac2011-01-13 15:46:52 -080065{
Mel Gorman599d0c92016-07-28 15:45:31 -070066 update_lru_size(lruvec, lru, page_zonenum(page), hpage_nr_pages(page));
Hugh Dickins41113042012-01-12 17:20:01 -080067 list_add(&page->lru, &lruvec->lists[lru]);
Andrea Arcangeli71e3aac2011-01-13 15:46:52 -080068}
69
Hugh Dickinsfa9add62012-05-29 15:07:09 -070070static __always_inline void del_page_from_lru_list(struct page *page,
71 struct lruvec *lruvec, enum lru_list lru)
Christoph Lameterb69408e2008-10-18 20:26:14 -070072{
73 list_del(&page->lru);
Mel Gorman599d0c92016-07-28 15:45:31 -070074 update_lru_size(lruvec, lru, page_zonenum(page), -hpage_nr_pages(page));
Christoph Lameterb69408e2008-10-18 20:26:14 -070075}
76
Johannes Weiner401a8e12009-09-21 17:02:58 -070077/**
78 * page_lru_base_type - which LRU list type should a page be on?
79 * @page: the page to test
80 *
81 * Used for LRU list index arithmetic.
82 *
83 * Returns the base LRU type - file or anon - @page should be on.
84 */
85static inline enum lru_list page_lru_base_type(struct page *page)
86{
87 if (page_is_file_cache(page))
88 return LRU_INACTIVE_FILE;
89 return LRU_INACTIVE_ANON;
90}
91
Hugh Dickins1c1c53d2012-01-12 17:20:04 -080092/**
93 * page_off_lru - which LRU list was page on? clearing its lru flags.
94 * @page: the page to test
95 *
96 * Returns the LRU list a page was on, as an index into the array of LRU
97 * lists; and clears its Unevictable or Active flags, ready for freeing.
98 */
Konstantin Khlebnikov014483b2012-05-29 15:06:53 -070099static __always_inline enum lru_list page_off_lru(struct page *page)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100{
Hugh Dickins41113042012-01-12 17:20:01 -0800101 enum lru_list lru;
Christoph Lameterb69408e2008-10-18 20:26:14 -0700102
Lee Schermerhorn894bc312008-10-18 20:26:39 -0700103 if (PageUnevictable(page)) {
104 __ClearPageUnevictable(page);
Hugh Dickins41113042012-01-12 17:20:01 -0800105 lru = LRU_UNEVICTABLE;
Lee Schermerhorn894bc312008-10-18 20:26:39 -0700106 } else {
Hugh Dickins41113042012-01-12 17:20:01 -0800107 lru = page_lru_base_type(page);
Lee Schermerhorn894bc312008-10-18 20:26:39 -0700108 if (PageActive(page)) {
109 __ClearPageActive(page);
Hugh Dickins41113042012-01-12 17:20:01 -0800110 lru += LRU_ACTIVE;
Lee Schermerhorn894bc312008-10-18 20:26:39 -0700111 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 }
Hugh Dickins1c1c53d2012-01-12 17:20:04 -0800113 return lru;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114}
Christoph Lameter21eac812006-01-08 01:00:45 -0800115
Christoph Lameterb69408e2008-10-18 20:26:14 -0700116/**
117 * page_lru - which LRU list should a page be on?
118 * @page: the page to test
119 *
120 * Returns the LRU list a page should be on, as an index
121 * into the array of LRU lists.
122 */
Konstantin Khlebnikov014483b2012-05-29 15:06:53 -0700123static __always_inline enum lru_list page_lru(struct page *page)
Christoph Lameterb69408e2008-10-18 20:26:14 -0700124{
Johannes Weiner401a8e12009-09-21 17:02:58 -0700125 enum lru_list lru;
Christoph Lameterb69408e2008-10-18 20:26:14 -0700126
Lee Schermerhorn894bc312008-10-18 20:26:39 -0700127 if (PageUnevictable(page))
128 lru = LRU_UNEVICTABLE;
129 else {
Johannes Weiner401a8e12009-09-21 17:02:58 -0700130 lru = page_lru_base_type(page);
Lee Schermerhorn894bc312008-10-18 20:26:39 -0700131 if (PageActive(page))
132 lru += LRU_ACTIVE;
Lee Schermerhorn894bc312008-10-18 20:26:39 -0700133 }
Christoph Lameterb69408e2008-10-18 20:26:14 -0700134 return lru;
135}
Rik van Rielb2e18532008-10-18 20:26:30 -0700136
Geliang Tangd72ee912016-01-14 15:22:01 -0800137#define lru_to_page(head) (list_entry((head)->prev, struct page, lru))
138
Rik van Rielb2e18532008-10-18 20:26:30 -0700139#endif