• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef LINUX_MM_INLINE_H
3 #define LINUX_MM_INLINE_H
4 
5 #include <linux/huge_mm.h>
6 #include <linux/swap.h>
7 #include <linux/string.h>
8 
9 /**
10  * page_is_file_lru - should the page be on a file LRU or anon LRU?
11  * @page: the page to test
12  *
13  * Returns 1 if @page is a regular filesystem backed page cache page or a lazily
14  * freed anonymous page (e.g. via MADV_FREE).  Returns 0 if @page is a normal
15  * anonymous page, a tmpfs page or otherwise ram or swap backed page.  Used by
16  * functions that manipulate the LRU lists, to sort a page onto the right LRU
17  * list.
18  *
19  * We would like to get this info without a page flag, but the state
20  * needs to survive until the page is last deleted from the LRU, which
21  * could be as far down as __page_cache_release.
22  */
page_is_file_lru(struct page * page)23 static inline int page_is_file_lru(struct page *page)
24 {
25 	return !PageSwapBacked(page);
26 }
27 
__update_lru_size(struct lruvec * lruvec,enum lru_list lru,enum zone_type zid,long nr_pages)28 static __always_inline void __update_lru_size(struct lruvec *lruvec,
29 				enum lru_list lru, enum zone_type zid,
30 				long nr_pages)
31 {
32 	struct pglist_data *pgdat = lruvec_pgdat(lruvec);
33 
34 	lockdep_assert_held(&lruvec->lru_lock);
35 	WARN_ON_ONCE(nr_pages != (int)nr_pages);
36 
37 	__mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages);
38 	__mod_zone_page_state(&pgdat->node_zones[zid],
39 				NR_ZONE_LRU_BASE + lru, nr_pages);
40 }
41 
update_lru_size(struct lruvec * lruvec,enum lru_list lru,enum zone_type zid,long nr_pages)42 static __always_inline void update_lru_size(struct lruvec *lruvec,
43 				enum lru_list lru, enum zone_type zid,
44 				long nr_pages)
45 {
46 	__update_lru_size(lruvec, lru, zid, nr_pages);
47 #ifdef CONFIG_MEMCG
48 	mem_cgroup_update_lru_size(lruvec, lru, zid, nr_pages);
49 #endif
50 }
51 
52 /**
53  * __clear_page_lru_flags - clear page lru flags before releasing a page
54  * @page: the page that was on lru and now has a zero reference
55  */
__clear_page_lru_flags(struct page * page)56 static __always_inline void __clear_page_lru_flags(struct page *page)
57 {
58 	VM_BUG_ON_PAGE(!PageLRU(page), page);
59 
60 	__ClearPageLRU(page);
61 
62 	/* this shouldn't happen, so leave the flags to bad_page() */
63 	if (PageActive(page) && PageUnevictable(page))
64 		return;
65 
66 	__ClearPageActive(page);
67 	__ClearPageUnevictable(page);
68 }
69 
70 /**
71  * page_lru - which LRU list should a page be on?
72  * @page: the page to test
73  *
74  * Returns the LRU list a page should be on, as an index
75  * into the array of LRU lists.
76  */
page_lru(struct page * page)77 static __always_inline enum lru_list page_lru(struct page *page)
78 {
79 	enum lru_list lru;
80 
81 	VM_BUG_ON_PAGE(PageActive(page) && PageUnevictable(page), page);
82 
83 	if (PageUnevictable(page))
84 		return LRU_UNEVICTABLE;
85 
86 	lru = page_is_file_lru(page) ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON;
87 	if (PageActive(page))
88 		lru += LRU_ACTIVE;
89 
90 	return lru;
91 }
92 
93 #ifdef CONFIG_LRU_GEN
94 
95 #ifdef CONFIG_LRU_GEN_ENABLED
lru_gen_enabled(void)96 static inline bool lru_gen_enabled(void)
97 {
98 	DECLARE_STATIC_KEY_TRUE(lru_gen_caps[NR_LRU_GEN_CAPS]);
99 
100 	return static_branch_likely(&lru_gen_caps[LRU_GEN_CORE]);
101 }
102 #else
lru_gen_enabled(void)103 static inline bool lru_gen_enabled(void)
104 {
105 	DECLARE_STATIC_KEY_FALSE(lru_gen_caps[NR_LRU_GEN_CAPS]);
106 
107 	return static_branch_unlikely(&lru_gen_caps[LRU_GEN_CORE]);
108 }
109 #endif
110 
lru_gen_in_fault(void)111 static inline bool lru_gen_in_fault(void)
112 {
113 	return current->in_lru_fault;
114 }
115 
116 #ifdef CONFIG_MEMCG
lru_gen_memcg_seg(struct lruvec * lruvec)117 static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
118 {
119 	return READ_ONCE(lruvec->lrugen.seg);
120 }
121 #else
lru_gen_memcg_seg(struct lruvec * lruvec)122 static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
123 {
124 	return 0;
125 }
126 #endif
127 
lru_gen_from_seq(unsigned long seq)128 static inline int lru_gen_from_seq(unsigned long seq)
129 {
130 	return seq % MAX_NR_GENS;
131 }
132 
lru_hist_from_seq(unsigned long seq)133 static inline int lru_hist_from_seq(unsigned long seq)
134 {
135 	return seq % NR_HIST_GENS;
136 }
137 
lru_tier_from_refs(int refs)138 static inline int lru_tier_from_refs(int refs)
139 {
140 	VM_WARN_ON_ONCE(refs > BIT(LRU_REFS_WIDTH));
141 
142 	/* see the comment in page_lru_refs() */
143 	return order_base_2(refs + 1);
144 }
145 
page_lru_refs(struct page * page)146 static inline int page_lru_refs(struct page *page)
147 {
148 	unsigned long flags = READ_ONCE(page->flags);
149 	bool workingset = flags & BIT(PG_workingset);
150 
151 	/*
152 	 * Return the number of accesses beyond PG_referenced, i.e., N-1 if the
153 	 * total number of accesses is N>1, since N=0,1 both map to the first
154 	 * tier. lru_tier_from_refs() will account for this off-by-one. Also see
155 	 * the comment on MAX_NR_TIERS.
156 	 */
157 	return ((flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF) + workingset;
158 }
159 
page_lru_gen(struct page * page)160 static inline int page_lru_gen(struct page *page)
161 {
162 	unsigned long flags = READ_ONCE(page->flags);
163 
164 	return ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
165 }
166 
lru_gen_is_active(struct lruvec * lruvec,int gen)167 static inline bool lru_gen_is_active(struct lruvec *lruvec, int gen)
168 {
169 	unsigned long max_seq = lruvec->lrugen.max_seq;
170 
171 	VM_WARN_ON_ONCE(gen >= MAX_NR_GENS);
172 
173 	/* see the comment on MIN_NR_GENS */
174 	return gen == lru_gen_from_seq(max_seq) || gen == lru_gen_from_seq(max_seq - 1);
175 }
176 
lru_gen_update_size(struct lruvec * lruvec,struct page * page,int old_gen,int new_gen)177 static inline void lru_gen_update_size(struct lruvec *lruvec, struct page *page,
178 				       int old_gen, int new_gen)
179 {
180 	int type = page_is_file_lru(page);
181 	int zone = page_zonenum(page);
182 	int delta = thp_nr_pages(page);
183 	enum lru_list lru = type * LRU_INACTIVE_FILE;
184 	struct lru_gen_page *lrugen = &lruvec->lrugen;
185 
186 	VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS);
187 	VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS);
188 	VM_WARN_ON_ONCE(old_gen == -1 && new_gen == -1);
189 
190 	if (old_gen >= 0)
191 		WRITE_ONCE(lrugen->nr_pages[old_gen][type][zone],
192 			   lrugen->nr_pages[old_gen][type][zone] - delta);
193 	if (new_gen >= 0)
194 		WRITE_ONCE(lrugen->nr_pages[new_gen][type][zone],
195 			   lrugen->nr_pages[new_gen][type][zone] + delta);
196 
197 	/* addition */
198 	if (old_gen < 0) {
199 		if (lru_gen_is_active(lruvec, new_gen))
200 			lru += LRU_ACTIVE;
201 		__update_lru_size(lruvec, lru, zone, delta);
202 		return;
203 	}
204 
205 	/* deletion */
206 	if (new_gen < 0) {
207 		if (lru_gen_is_active(lruvec, old_gen))
208 			lru += LRU_ACTIVE;
209 		__update_lru_size(lruvec, lru, zone, -delta);
210 		return;
211 	}
212 
213 	/* promotion */
214 	if (!lru_gen_is_active(lruvec, old_gen) && lru_gen_is_active(lruvec, new_gen)) {
215 		__update_lru_size(lruvec, lru, zone, -delta);
216 		__update_lru_size(lruvec, lru + LRU_ACTIVE, zone, delta);
217 	}
218 
219 	/* demotion requires isolation, e.g., lru_deactivate_fn() */
220 	VM_WARN_ON_ONCE(lru_gen_is_active(lruvec, old_gen) && !lru_gen_is_active(lruvec, new_gen));
221 }
222 
lru_gen_add_page(struct lruvec * lruvec,struct page * page,bool reclaiming)223 static inline bool lru_gen_add_page(struct lruvec *lruvec, struct page *page, bool reclaiming)
224 {
225 	unsigned long seq;
226 	unsigned long flags;
227 	int gen = page_lru_gen(page);
228 	int type = page_is_file_lru(page);
229 	int zone = page_zonenum(page);
230 	struct lru_gen_page *lrugen = &lruvec->lrugen;
231 
232 	VM_WARN_ON_ONCE_PAGE(gen != -1, page);
233 
234 	if (PageUnevictable(page) || !lrugen->enabled)
235 		return false;
236 	/*
237 	 * There are three common cases for this page:
238 	 * 1. If it's hot, e.g., freshly faulted in or previously hot and
239 	 *    migrated, add it to the youngest generation.
240 	 * 2. If it's cold but can't be evicted immediately, i.e., an anon page
241 	 *    not in swapcache or a dirty page pending writeback, add it to the
242 	 *    second oldest generation.
243 	 * 3. Everything else (clean, cold) is added to the oldest generation.
244 	 */
245 	if (PageActive(page))
246 		seq = lrugen->max_seq;
247 	else if ((type == LRU_GEN_ANON && !PageSwapCache(page)) ||
248 		 (PageReclaim(page) &&
249 		  (PageDirty(page) || PageWriteback(page))))
250 		seq = lrugen->min_seq[type] + 1;
251 	else
252 		seq = lrugen->min_seq[type];
253 
254 	gen = lru_gen_from_seq(seq);
255 	flags = (gen + 1UL) << LRU_GEN_PGOFF;
256 	/* see the comment on MIN_NR_GENS about PG_active */
257 	set_mask_bits(&page->flags, LRU_GEN_MASK | BIT(PG_active), flags);
258 
259 	lru_gen_update_size(lruvec, page, -1, gen);
260 	/* for rotate_reclaimable_page() */
261 	if (reclaiming)
262 		list_add_tail(&page->lru, &lrugen->pages[gen][type][zone]);
263 	else
264 		list_add(&page->lru, &lrugen->pages[gen][type][zone]);
265 
266 	return true;
267 }
268 
lru_gen_del_page(struct lruvec * lruvec,struct page * page,bool reclaiming)269 static inline bool lru_gen_del_page(struct lruvec *lruvec, struct page *page, bool reclaiming)
270 {
271 	unsigned long flags;
272 	int gen = page_lru_gen(page);
273 
274 	if (gen < 0)
275 		return false;
276 
277 	VM_WARN_ON_ONCE_PAGE(PageActive(page), page);
278 	VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page);
279 
280 	/* for migrate_page_states() */
281 	flags = !reclaiming && lru_gen_is_active(lruvec, gen) ? BIT(PG_active) : 0;
282 	flags = set_mask_bits(&page->flags, LRU_GEN_MASK, flags);
283 	gen = ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
284 
285 	lru_gen_update_size(lruvec, page, gen, -1);
286 	list_del(&page->lru);
287 
288 	return true;
289 }
290 
291 #else /* !CONFIG_LRU_GEN */
292 
lru_gen_enabled(void)293 static inline bool lru_gen_enabled(void)
294 {
295 	return false;
296 }
297 
lru_gen_in_fault(void)298 static inline bool lru_gen_in_fault(void)
299 {
300 	return false;
301 }
302 
lru_gen_memcg_seg(struct lruvec * lruvec)303 static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
304 {
305 	return 0;
306 }
307 
lru_gen_add_page(struct lruvec * lruvec,struct page * page,bool reclaiming)308 static inline bool lru_gen_add_page(struct lruvec *lruvec, struct page *page, bool reclaiming)
309 {
310 	return false;
311 }
312 
lru_gen_del_page(struct lruvec * lruvec,struct page * page,bool reclaiming)313 static inline bool lru_gen_del_page(struct lruvec *lruvec, struct page *page, bool reclaiming)
314 {
315 	return false;
316 }
317 
318 #endif /* CONFIG_LRU_GEN */
319 
add_page_to_lru_list(struct page * page,struct lruvec * lruvec)320 static __always_inline void add_page_to_lru_list(struct page *page,
321 				struct lruvec *lruvec)
322 {
323 	enum lru_list lru = page_lru(page);
324 
325 	if (lru_gen_add_page(lruvec, page, false))
326 		return;
327 
328 	update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page));
329 	list_add(&page->lru, &lruvec->lists[lru]);
330 }
331 
add_page_to_lru_list_tail(struct page * page,struct lruvec * lruvec)332 static __always_inline void add_page_to_lru_list_tail(struct page *page,
333 				struct lruvec *lruvec)
334 {
335 	enum lru_list lru = page_lru(page);
336 
337 	if (lru_gen_add_page(lruvec, page, true))
338 		return;
339 
340 	update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page));
341 	list_add_tail(&page->lru, &lruvec->lists[lru]);
342 }
343 
del_page_from_lru_list(struct page * page,struct lruvec * lruvec)344 static __always_inline void del_page_from_lru_list(struct page *page,
345 				struct lruvec *lruvec)
346 {
347 	if (lru_gen_del_page(lruvec, page, false))
348 		return;
349 
350 	list_del(&page->lru);
351 	update_lru_size(lruvec, page_lru(page), page_zonenum(page),
352 			-thp_nr_pages(page));
353 }
354 
355 #ifdef CONFIG_ANON_VMA_NAME
356 /*
357  * mmap_lock should be read-locked when calling anon_vma_name(). Caller should
358  * either keep holding the lock while using the returned pointer or it should
359  * raise anon_vma_name refcount before releasing the lock.
360  */
361 extern struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma);
362 extern struct anon_vma_name *anon_vma_name_alloc(const char *name);
363 extern void anon_vma_name_free(struct kref *kref);
364 
365 /* mmap_lock should be read-locked */
anon_vma_name_get(struct anon_vma_name * anon_name)366 static inline void anon_vma_name_get(struct anon_vma_name *anon_name)
367 {
368 	if (anon_name)
369 		kref_get(&anon_name->kref);
370 }
371 
anon_vma_name_put(struct anon_vma_name * anon_name)372 static inline void anon_vma_name_put(struct anon_vma_name *anon_name)
373 {
374 	if (anon_name)
375 		kref_put(&anon_name->kref, anon_vma_name_free);
376 }
377 
378 static inline
anon_vma_name_reuse(struct anon_vma_name * anon_name)379 struct anon_vma_name *anon_vma_name_reuse(struct anon_vma_name *anon_name)
380 {
381 	/* Prevent anon_name refcount saturation early on */
382 	if (kref_read(&anon_name->kref) < REFCOUNT_MAX) {
383 		anon_vma_name_get(anon_name);
384 		return anon_name;
385 
386 	}
387 	return anon_vma_name_alloc(anon_name->name);
388 }
389 
dup_anon_vma_name(struct vm_area_struct * orig_vma,struct vm_area_struct * new_vma)390 static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma,
391 				     struct vm_area_struct *new_vma)
392 {
393 	struct anon_vma_name *anon_name = anon_vma_name(orig_vma);
394 
395 	if (anon_name)
396 		new_vma->anon_name = anon_vma_name_reuse(anon_name);
397 }
398 
free_anon_vma_name(struct vm_area_struct * vma)399 static inline void free_anon_vma_name(struct vm_area_struct *vma)
400 {
401 	/*
402 	 * Not using anon_vma_name because it generates a warning if mmap_lock
403 	 * is not held, which might be the case here.
404 	 */
405 	if (!vma->vm_file)
406 		anon_vma_name_put(vma->anon_name);
407 }
408 
anon_vma_name_eq(struct anon_vma_name * anon_name1,struct anon_vma_name * anon_name2)409 static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1,
410 				    struct anon_vma_name *anon_name2)
411 {
412 	if (anon_name1 == anon_name2)
413 		return true;
414 
415 	return anon_name1 && anon_name2 &&
416 		!strcmp(anon_name1->name, anon_name2->name);
417 }
418 #else /* CONFIG_ANON_VMA_NAME */
anon_vma_name(struct vm_area_struct * vma)419 static inline struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma)
420 {
421 	return NULL;
422 }
423 
anon_vma_name_alloc(const char * name)424 static inline struct anon_vma_name *anon_vma_name_alloc(const char *name)
425 {
426 	return NULL;
427 }
428 
anon_vma_name_get(struct anon_vma_name * anon_name)429 static inline void anon_vma_name_get(struct anon_vma_name *anon_name) {}
anon_vma_name_put(struct anon_vma_name * anon_name)430 static inline void anon_vma_name_put(struct anon_vma_name *anon_name) {}
dup_anon_vma_name(struct vm_area_struct * orig_vma,struct vm_area_struct * new_vma)431 static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma,
432 				     struct vm_area_struct *new_vma) {}
free_anon_vma_name(struct vm_area_struct * vma)433 static inline void free_anon_vma_name(struct vm_area_struct *vma) {}
434 
anon_vma_name_eq(struct anon_vma_name * anon_name1,struct anon_vma_name * anon_name2)435 static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1,
436 				    struct anon_vma_name *anon_name2)
437 {
438 	return true;
439 }
440 
441 #endif  /* CONFIG_ANON_VMA_NAME */
442 
vma_has_recency(struct vm_area_struct * vma)443 static inline bool vma_has_recency(struct vm_area_struct *vma)
444 {
445 	if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))
446 		return false;
447 
448 	if (vma->vm_file && (vma->vm_file->f_mode & FMODE_NOREUSE))
449 		return false;
450 
451 	return true;
452 }
453 #endif
454