forked from mirrors/linux
		
	 9de4f22a60
			
		
	
	
		9de4f22a60
		
	
	
	
	
		
			
			Some comments for MADV_FREE is revised and added to help people understand the MADV_FREE code, especially the page flag, PG_swapbacked. This makes page_is_file_cache() isn't consistent with its comments. So the function is renamed to page_is_file_lru() to make them consistent again. All these are put in one patch as one logical change. Suggested-by: David Hildenbrand <david@redhat.com> Suggested-by: Johannes Weiner <hannes@cmpxchg.org> Suggested-by: David Rientjes <rientjes@google.com> Signed-off-by: "Huang, Ying" <ying.huang@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Acked-by: David Rientjes <rientjes@google.com> Acked-by: Michal Hocko <mhocko@kernel.org> Acked-by: Pankaj Gupta <pankaj.gupta.linux@gmail.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Minchan Kim <minchan@kernel.org> Cc: Hugh Dickins <hughd@google.com> Cc: Rik van Riel <riel@surriel.com> Link: http://lkml.kernel.org/r/20200317100342.2730705-1-ying.huang@intel.com Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
		
			
				
	
	
		
			128 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* SPDX-License-Identifier: GPL-2.0 */
 | |
| #ifndef LINUX_MM_INLINE_H
 | |
| #define LINUX_MM_INLINE_H
 | |
| 
 | |
| #include <linux/huge_mm.h>
 | |
| #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.
 | |
|  *
 | |
|  * 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
 | |
|  * could be as far down as __page_cache_release.
 | |
|  */
 | |
| static inline int page_is_file_lru(struct page *page)
 | |
| {
 | |
| 	return !PageSwapBacked(page);
 | |
| }
 | |
| 
 | |
| static __always_inline void __update_lru_size(struct lruvec *lruvec,
 | |
| 				enum lru_list lru, enum zone_type zid,
 | |
| 				int nr_pages)
 | |
| {
 | |
| 	struct pglist_data *pgdat = lruvec_pgdat(lruvec);
 | |
| 
 | |
| 	__mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages);
 | |
| 	__mod_zone_page_state(&pgdat->node_zones[zid],
 | |
| 				NR_ZONE_LRU_BASE + lru, nr_pages);
 | |
| }
 | |
| 
 | |
| static __always_inline void update_lru_size(struct lruvec *lruvec,
 | |
| 				enum lru_list lru, enum zone_type zid,
 | |
| 				int nr_pages)
 | |
| {
 | |
| 	__update_lru_size(lruvec, lru, zid, nr_pages);
 | |
| #ifdef CONFIG_MEMCG
 | |
| 	mem_cgroup_update_lru_size(lruvec, lru, zid, nr_pages);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| static __always_inline void add_page_to_lru_list(struct page *page,
 | |
| 				struct lruvec *lruvec, enum lru_list lru)
 | |
| {
 | |
| 	update_lru_size(lruvec, lru, page_zonenum(page), hpage_nr_pages(page));
 | |
| 	list_add(&page->lru, &lruvec->lists[lru]);
 | |
| }
 | |
| 
 | |
| static __always_inline void add_page_to_lru_list_tail(struct page *page,
 | |
| 				struct lruvec *lruvec, enum lru_list lru)
 | |
| {
 | |
| 	update_lru_size(lruvec, lru, page_zonenum(page), hpage_nr_pages(page));
 | |
| 	list_add_tail(&page->lru, &lruvec->lists[lru]);
 | |
| }
 | |
| 
 | |
| static __always_inline void del_page_from_lru_list(struct page *page,
 | |
| 				struct lruvec *lruvec, enum lru_list lru)
 | |
| {
 | |
| 	list_del(&page->lru);
 | |
| 	update_lru_size(lruvec, lru, page_zonenum(page), -hpage_nr_pages(page));
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * page_lru_base_type - which LRU list type should a page be on?
 | |
|  * @page: the page to test
 | |
|  *
 | |
|  * Used for LRU list index arithmetic.
 | |
|  *
 | |
|  * Returns the base LRU type - file or anon - @page should be on.
 | |
|  */
 | |
| static inline enum lru_list page_lru_base_type(struct page *page)
 | |
| {
 | |
| 	if (page_is_file_lru(page))
 | |
| 		return LRU_INACTIVE_FILE;
 | |
| 	return LRU_INACTIVE_ANON;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * page_off_lru - which LRU list was page on? clearing its lru flags.
 | |
|  * @page: the page to test
 | |
|  *
 | |
|  * Returns the LRU list a page was on, as an index into the array of LRU
 | |
|  * lists; and clears its Unevictable or Active flags, ready for freeing.
 | |
|  */
 | |
| static __always_inline enum lru_list page_off_lru(struct page *page)
 | |
| {
 | |
| 	enum lru_list lru;
 | |
| 
 | |
| 	if (PageUnevictable(page)) {
 | |
| 		__ClearPageUnevictable(page);
 | |
| 		lru = LRU_UNEVICTABLE;
 | |
| 	} else {
 | |
| 		lru = page_lru_base_type(page);
 | |
| 		if (PageActive(page)) {
 | |
| 			__ClearPageActive(page);
 | |
| 			lru += LRU_ACTIVE;
 | |
| 		}
 | |
| 	}
 | |
| 	return lru;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * page_lru - which LRU list should a page be on?
 | |
|  * @page: the page to test
 | |
|  *
 | |
|  * Returns the LRU list a page should be on, as an index
 | |
|  * into the array of LRU lists.
 | |
|  */
 | |
| static __always_inline enum lru_list page_lru(struct page *page)
 | |
| {
 | |
| 	enum lru_list lru;
 | |
| 
 | |
| 	if (PageUnevictable(page))
 | |
| 		lru = LRU_UNEVICTABLE;
 | |
| 	else {
 | |
| 		lru = page_lru_base_type(page);
 | |
| 		if (PageActive(page))
 | |
| 			lru += LRU_ACTIVE;
 | |
| 	}
 | |
| 	return lru;
 | |
| }
 | |
| #endif
 |