18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* internal.h: mm/ internal definitions 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 58c2ecf20Sopenharmony_ci * Written by David Howells (dhowells@redhat.com) 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#ifndef __MM_INTERNAL_H 88c2ecf20Sopenharmony_ci#define __MM_INTERNAL_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/fs.h> 118c2ecf20Sopenharmony_ci#include <linux/mm.h> 128c2ecf20Sopenharmony_ci#include <linux/pagemap.h> 138c2ecf20Sopenharmony_ci#include <linux/tracepoint-defs.h> 148c2ecf20Sopenharmony_ci#include <linux/swap.h> 158c2ecf20Sopenharmony_ci#include <linux/rmap.h> 168c2ecf20Sopenharmony_ci#include <linux/types.h> 178c2ecf20Sopenharmony_ci#include <linux/reclaim_acct.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* 208c2ecf20Sopenharmony_ci * The set of flags that only affect watermark checking and reclaim 218c2ecf20Sopenharmony_ci * behaviour. This is used by the MM to obey the caller constraints 228c2ecf20Sopenharmony_ci * about IO, FS and watermark checking while ignoring placement 238c2ecf20Sopenharmony_ci * hints such as HIGHMEM usage. 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_ci#define GFP_RECLAIM_MASK (__GFP_RECLAIM|__GFP_HIGH|__GFP_IO|__GFP_FS|\ 268c2ecf20Sopenharmony_ci __GFP_NOWARN|__GFP_RETRY_MAYFAIL|__GFP_NOFAIL|\ 278c2ecf20Sopenharmony_ci __GFP_NORETRY|__GFP_MEMALLOC|__GFP_NOMEMALLOC|\ 288c2ecf20Sopenharmony_ci __GFP_ATOMIC) 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* The GFP flags allowed during early boot */ 318c2ecf20Sopenharmony_ci#define GFP_BOOT_MASK (__GFP_BITS_MASK & ~(__GFP_RECLAIM|__GFP_IO|__GFP_FS)) 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci/* Control allocation cpuset and node placement constraints */ 348c2ecf20Sopenharmony_ci#define GFP_CONSTRAINT_MASK (__GFP_HARDWALL|__GFP_THISNODE) 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci/* Do not use these with a slab allocator */ 378c2ecf20Sopenharmony_ci#define GFP_SLAB_BUG_MASK (__GFP_DMA32|__GFP_HIGHMEM|~__GFP_BITS_MASK) 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cienum reclaim_invoker { 408c2ecf20Sopenharmony_ci ALL, 418c2ecf20Sopenharmony_ci KSWAPD, 428c2ecf20Sopenharmony_ci ZSWAPD, 438c2ecf20Sopenharmony_ci DIRECT_RECLAIM, 448c2ecf20Sopenharmony_ci NODE_RECLAIM, 458c2ecf20Sopenharmony_ci SOFT_LIMIT, 468c2ecf20Sopenharmony_ci RCC_RECLAIM, 478c2ecf20Sopenharmony_ci FILE_RECLAIM, 488c2ecf20Sopenharmony_ci ANON_RECLAIM 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistruct scan_control { 528c2ecf20Sopenharmony_ci /* How many pages shrink_list() should reclaim */ 538c2ecf20Sopenharmony_ci unsigned long nr_to_reclaim; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci /* 568c2ecf20Sopenharmony_ci * Nodemask of nodes allowed by the caller. If NULL, all nodes 578c2ecf20Sopenharmony_ci * are scanned. 588c2ecf20Sopenharmony_ci */ 598c2ecf20Sopenharmony_ci nodemask_t *nodemask; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* 628c2ecf20Sopenharmony_ci * The memory cgroup that hit its limit and as a result is the 638c2ecf20Sopenharmony_ci * primary target of this reclaim invocation. 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ci struct mem_cgroup *target_mem_cgroup; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci /* 688c2ecf20Sopenharmony_ci * Scan pressure balancing between anon and file LRUs 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_ci unsigned long anon_cost; 718c2ecf20Sopenharmony_ci unsigned long file_cost; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci /* Can active pages be deactivated as part of reclaim? */ 748c2ecf20Sopenharmony_ci#define DEACTIVATE_ANON 1 758c2ecf20Sopenharmony_ci#define DEACTIVATE_FILE 2 768c2ecf20Sopenharmony_ci unsigned int may_deactivate:2; 778c2ecf20Sopenharmony_ci unsigned int force_deactivate:1; 788c2ecf20Sopenharmony_ci unsigned int skipped_deactivate:1; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci /* Writepage batching in laptop mode; RECLAIM_WRITE */ 818c2ecf20Sopenharmony_ci unsigned int may_writepage:1; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci /* Can mapped pages be reclaimed? */ 848c2ecf20Sopenharmony_ci unsigned int may_unmap:1; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci /* Can pages be swapped as part of reclaim? */ 878c2ecf20Sopenharmony_ci unsigned int may_swap:1; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci /* 908c2ecf20Sopenharmony_ci * Cgroups are not reclaimed below their configured memory.low, 918c2ecf20Sopenharmony_ci * unless we threaten to OOM. If any cgroups are skipped due to 928c2ecf20Sopenharmony_ci * memory.low and nothing was reclaimed, go back for memory.low. 938c2ecf20Sopenharmony_ci */ 948c2ecf20Sopenharmony_ci unsigned int memcg_low_reclaim:1; 958c2ecf20Sopenharmony_ci unsigned int memcg_low_skipped:1; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci unsigned int hibernation_mode:1; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci /* One of the zones is ready for compaction */ 1008c2ecf20Sopenharmony_ci unsigned int compaction_ready:1; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci /* There is easily reclaimable cold cache in the current node */ 1038c2ecf20Sopenharmony_ci unsigned int cache_trim_mode:1; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci /* The file pages on the current node are dangerously low */ 1068c2ecf20Sopenharmony_ci unsigned int file_is_tiny:1; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci /* Allocation order */ 1098c2ecf20Sopenharmony_ci s8 order; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci /* Scan (total_size >> priority) pages at once */ 1128c2ecf20Sopenharmony_ci s8 priority; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci /* The highest zone to isolate pages for reclaim from */ 1158c2ecf20Sopenharmony_ci s8 reclaim_idx; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci /* This context's GFP mask */ 1188c2ecf20Sopenharmony_ci gfp_t gfp_mask; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci /* Incremented by the number of inactive pages that were scanned */ 1218c2ecf20Sopenharmony_ci unsigned long nr_scanned; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci /* Number of pages freed so far during a call to shrink_zones() */ 1248c2ecf20Sopenharmony_ci unsigned long nr_reclaimed; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci struct { 1278c2ecf20Sopenharmony_ci unsigned int dirty; 1288c2ecf20Sopenharmony_ci unsigned int unqueued_dirty; 1298c2ecf20Sopenharmony_ci unsigned int congested; 1308c2ecf20Sopenharmony_ci unsigned int writeback; 1318c2ecf20Sopenharmony_ci unsigned int immediate; 1328c2ecf20Sopenharmony_ci unsigned int file_taken; 1338c2ecf20Sopenharmony_ci unsigned int taken; 1348c2ecf20Sopenharmony_ci } nr; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci enum reclaim_invoker invoker; 1378c2ecf20Sopenharmony_ci u32 isolate_count; 1388c2ecf20Sopenharmony_ci unsigned long nr_scanned_anon; 1398c2ecf20Sopenharmony_ci unsigned long nr_scanned_file; 1408c2ecf20Sopenharmony_ci unsigned long nr_reclaimed_anon; 1418c2ecf20Sopenharmony_ci unsigned long nr_reclaimed_file; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci /* for recording the reclaimed slab by now */ 1448c2ecf20Sopenharmony_ci struct reclaim_state reclaim_state; 1458c2ecf20Sopenharmony_ci}; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cienum scan_balance { 1488c2ecf20Sopenharmony_ci SCAN_EQUAL, 1498c2ecf20Sopenharmony_ci SCAN_FRACT, 1508c2ecf20Sopenharmony_ci SCAN_ANON, 1518c2ecf20Sopenharmony_ci SCAN_FILE, 1528c2ecf20Sopenharmony_ci}; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_civoid page_writeback_init(void); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_civm_fault_t do_swap_page(struct vm_fault *vmf); 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_civoid free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma, 1598c2ecf20Sopenharmony_ci unsigned long floor, unsigned long ceiling); 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic inline bool can_madv_lru_vma(struct vm_area_struct *vma) 1628c2ecf20Sopenharmony_ci{ 1638c2ecf20Sopenharmony_ci return !(vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP)); 1648c2ecf20Sopenharmony_ci} 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_civoid unmap_page_range(struct mmu_gather *tlb, 1678c2ecf20Sopenharmony_ci struct vm_area_struct *vma, 1688c2ecf20Sopenharmony_ci unsigned long addr, unsigned long end, 1698c2ecf20Sopenharmony_ci struct zap_details *details); 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_civoid do_page_cache_ra(struct readahead_control *, unsigned long nr_to_read, 1728c2ecf20Sopenharmony_ci unsigned long lookahead_size); 1738c2ecf20Sopenharmony_civoid force_page_cache_ra(struct readahead_control *, struct file_ra_state *, 1748c2ecf20Sopenharmony_ci unsigned long nr); 1758c2ecf20Sopenharmony_cistatic inline void force_page_cache_readahead(struct address_space *mapping, 1768c2ecf20Sopenharmony_ci struct file *file, pgoff_t index, unsigned long nr_to_read) 1778c2ecf20Sopenharmony_ci{ 1788c2ecf20Sopenharmony_ci DEFINE_READAHEAD(ractl, file, mapping, index); 1798c2ecf20Sopenharmony_ci force_page_cache_ra(&ractl, &file->f_ra, nr_to_read); 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistruct page *find_get_entry(struct address_space *mapping, pgoff_t index); 1838c2ecf20Sopenharmony_cistruct page *find_lock_entry(struct address_space *mapping, pgoff_t index); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci/** 1868c2ecf20Sopenharmony_ci * page_evictable - test whether a page is evictable 1878c2ecf20Sopenharmony_ci * @page: the page to test 1888c2ecf20Sopenharmony_ci * 1898c2ecf20Sopenharmony_ci * Test whether page is evictable--i.e., should be placed on active/inactive 1908c2ecf20Sopenharmony_ci * lists vs unevictable list. 1918c2ecf20Sopenharmony_ci * 1928c2ecf20Sopenharmony_ci * Reasons page might not be evictable: 1938c2ecf20Sopenharmony_ci * (1) page's mapping marked unevictable 1948c2ecf20Sopenharmony_ci * (2) page is part of an mlocked VMA 1958c2ecf20Sopenharmony_ci * 1968c2ecf20Sopenharmony_ci */ 1978c2ecf20Sopenharmony_cistatic inline bool page_evictable(struct page *page) 1988c2ecf20Sopenharmony_ci{ 1998c2ecf20Sopenharmony_ci bool ret; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci /* Prevent address_space of inode and swap cache from being freed */ 2028c2ecf20Sopenharmony_ci rcu_read_lock(); 2038c2ecf20Sopenharmony_ci ret = !mapping_unevictable(page_mapping(page)) && !PageMlocked(page); 2048c2ecf20Sopenharmony_ci rcu_read_unlock(); 2058c2ecf20Sopenharmony_ci return ret; 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci/* 2098c2ecf20Sopenharmony_ci * Turn a non-refcounted page (->_refcount == 0) into refcounted with 2108c2ecf20Sopenharmony_ci * a count of one. 2118c2ecf20Sopenharmony_ci */ 2128c2ecf20Sopenharmony_cistatic inline void set_page_refcounted(struct page *page) 2138c2ecf20Sopenharmony_ci{ 2148c2ecf20Sopenharmony_ci VM_BUG_ON_PAGE(PageTail(page), page); 2158c2ecf20Sopenharmony_ci VM_BUG_ON_PAGE(page_ref_count(page), page); 2168c2ecf20Sopenharmony_ci set_page_count(page, 1); 2178c2ecf20Sopenharmony_ci} 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ciextern unsigned long highest_memmap_pfn; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci/* 2228c2ecf20Sopenharmony_ci * Maximum number of reclaim retries without progress before the OOM 2238c2ecf20Sopenharmony_ci * killer is consider the only way forward. 2248c2ecf20Sopenharmony_ci */ 2258c2ecf20Sopenharmony_ci#define MAX_RECLAIM_RETRIES 16 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci/* 2288c2ecf20Sopenharmony_ci * in mm/vmscan.c: 2298c2ecf20Sopenharmony_ci */ 2308c2ecf20Sopenharmony_ci#ifdef CONFIG_MEMORY_MONITOR 2318c2ecf20Sopenharmony_ciextern void kswapd_monitor_wake_up_queue(void); 2328c2ecf20Sopenharmony_ci#endif 2338c2ecf20Sopenharmony_ciextern int isolate_lru_page(struct page *page); 2348c2ecf20Sopenharmony_ciextern void putback_lru_page(struct page *page); 2358c2ecf20Sopenharmony_ciextern unsigned int shrink_page_list(struct list_head *page_list, struct pglist_data *pgdat, 2368c2ecf20Sopenharmony_ci struct scan_control *sc, struct reclaim_stat *stat, bool ignore_references); 2378c2ecf20Sopenharmony_ciextern unsigned long isolate_lru_pages(unsigned long nr_to_scan, struct lruvec *lruvec, 2388c2ecf20Sopenharmony_ci struct list_head *dst, unsigned long *nr_scanned, struct scan_control *sc, 2398c2ecf20Sopenharmony_ci enum lru_list lru); 2408c2ecf20Sopenharmony_ciextern unsigned move_pages_to_lru(struct lruvec *lruvec, struct list_head *list); 2418c2ecf20Sopenharmony_ciextern void shrink_active_list(unsigned long nr_to_scan, struct lruvec *lruvec, 2428c2ecf20Sopenharmony_ci struct scan_control *sc, enum lru_list lru); 2438c2ecf20Sopenharmony_ciextern unsigned long shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec, 2448c2ecf20Sopenharmony_ci struct scan_control *sc, enum lru_list lru); 2458c2ecf20Sopenharmony_ciextern void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc); 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci/* 2488c2ecf20Sopenharmony_ci * in mm/rmap.c: 2498c2ecf20Sopenharmony_ci */ 2508c2ecf20Sopenharmony_ciextern pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci/* 2538c2ecf20Sopenharmony_ci * in mm/page_alloc.c 2548c2ecf20Sopenharmony_ci */ 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci/* 2578c2ecf20Sopenharmony_ci * Structure for holding the mostly immutable allocation parameters passed 2588c2ecf20Sopenharmony_ci * between functions involved in allocations, including the alloc_pages* 2598c2ecf20Sopenharmony_ci * family of functions. 2608c2ecf20Sopenharmony_ci * 2618c2ecf20Sopenharmony_ci * nodemask, migratetype and highest_zoneidx are initialized only once in 2628c2ecf20Sopenharmony_ci * __alloc_pages_nodemask() and then never change. 2638c2ecf20Sopenharmony_ci * 2648c2ecf20Sopenharmony_ci * zonelist, preferred_zone and highest_zoneidx are set first in 2658c2ecf20Sopenharmony_ci * __alloc_pages_nodemask() for the fast path, and might be later changed 2668c2ecf20Sopenharmony_ci * in __alloc_pages_slowpath(). All other functions pass the whole structure 2678c2ecf20Sopenharmony_ci * by a const pointer. 2688c2ecf20Sopenharmony_ci */ 2698c2ecf20Sopenharmony_cistruct alloc_context { 2708c2ecf20Sopenharmony_ci struct zonelist *zonelist; 2718c2ecf20Sopenharmony_ci nodemask_t *nodemask; 2728c2ecf20Sopenharmony_ci struct zoneref *preferred_zoneref; 2738c2ecf20Sopenharmony_ci int migratetype; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci /* 2768c2ecf20Sopenharmony_ci * highest_zoneidx represents highest usable zone index of 2778c2ecf20Sopenharmony_ci * the allocation request. Due to the nature of the zone, 2788c2ecf20Sopenharmony_ci * memory on lower zone than the highest_zoneidx will be 2798c2ecf20Sopenharmony_ci * protected by lowmem_reserve[highest_zoneidx]. 2808c2ecf20Sopenharmony_ci * 2818c2ecf20Sopenharmony_ci * highest_zoneidx is also used by reclaim/compaction to limit 2828c2ecf20Sopenharmony_ci * the target zone since higher zone than this index cannot be 2838c2ecf20Sopenharmony_ci * usable for this allocation request. 2848c2ecf20Sopenharmony_ci */ 2858c2ecf20Sopenharmony_ci enum zone_type highest_zoneidx; 2868c2ecf20Sopenharmony_ci bool spread_dirty_pages; 2878c2ecf20Sopenharmony_ci}; 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci/* 2908c2ecf20Sopenharmony_ci * Locate the struct page for both the matching buddy in our 2918c2ecf20Sopenharmony_ci * pair (buddy1) and the combined O(n+1) page they form (page). 2928c2ecf20Sopenharmony_ci * 2938c2ecf20Sopenharmony_ci * 1) Any buddy B1 will have an order O twin B2 which satisfies 2948c2ecf20Sopenharmony_ci * the following equation: 2958c2ecf20Sopenharmony_ci * B2 = B1 ^ (1 << O) 2968c2ecf20Sopenharmony_ci * For example, if the starting buddy (buddy2) is #8 its order 2978c2ecf20Sopenharmony_ci * 1 buddy is #10: 2988c2ecf20Sopenharmony_ci * B2 = 8 ^ (1 << 1) = 8 ^ 2 = 10 2998c2ecf20Sopenharmony_ci * 3008c2ecf20Sopenharmony_ci * 2) Any buddy B will have an order O+1 parent P which 3018c2ecf20Sopenharmony_ci * satisfies the following equation: 3028c2ecf20Sopenharmony_ci * P = B & ~(1 << O) 3038c2ecf20Sopenharmony_ci * 3048c2ecf20Sopenharmony_ci * Assumption: *_mem_map is contiguous at least up to MAX_ORDER 3058c2ecf20Sopenharmony_ci */ 3068c2ecf20Sopenharmony_cistatic inline unsigned long 3078c2ecf20Sopenharmony_ci__find_buddy_pfn(unsigned long page_pfn, unsigned int order) 3088c2ecf20Sopenharmony_ci{ 3098c2ecf20Sopenharmony_ci return page_pfn ^ (1 << order); 3108c2ecf20Sopenharmony_ci} 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ciextern struct page *__pageblock_pfn_to_page(unsigned long start_pfn, 3138c2ecf20Sopenharmony_ci unsigned long end_pfn, struct zone *zone); 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_cistatic inline struct page *pageblock_pfn_to_page(unsigned long start_pfn, 3168c2ecf20Sopenharmony_ci unsigned long end_pfn, struct zone *zone) 3178c2ecf20Sopenharmony_ci{ 3188c2ecf20Sopenharmony_ci if (zone->contiguous) 3198c2ecf20Sopenharmony_ci return pfn_to_page(start_pfn); 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci return __pageblock_pfn_to_page(start_pfn, end_pfn, zone); 3228c2ecf20Sopenharmony_ci} 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ciextern int __isolate_free_page(struct page *page, unsigned int order); 3258c2ecf20Sopenharmony_ciextern void __putback_isolated_page(struct page *page, unsigned int order, 3268c2ecf20Sopenharmony_ci int mt); 3278c2ecf20Sopenharmony_ciextern void memblock_free_pages(struct page *page, unsigned long pfn, 3288c2ecf20Sopenharmony_ci unsigned int order); 3298c2ecf20Sopenharmony_ciextern void __free_pages_core(struct page *page, unsigned int order); 3308c2ecf20Sopenharmony_ciextern void prep_compound_page(struct page *page, unsigned int order); 3318c2ecf20Sopenharmony_ciextern void post_alloc_hook(struct page *page, unsigned int order, 3328c2ecf20Sopenharmony_ci gfp_t gfp_flags); 3338c2ecf20Sopenharmony_ciextern int user_min_free_kbytes; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ciextern void zone_pcp_update(struct zone *zone); 3368c2ecf20Sopenharmony_ciextern void zone_pcp_reset(struct zone *zone); 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci#if defined CONFIG_COMPACTION || defined CONFIG_CMA 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci/* 3418c2ecf20Sopenharmony_ci * in mm/compaction.c 3428c2ecf20Sopenharmony_ci */ 3438c2ecf20Sopenharmony_ci/* 3448c2ecf20Sopenharmony_ci * compact_control is used to track pages being migrated and the free pages 3458c2ecf20Sopenharmony_ci * they are being migrated to during memory compaction. The free_pfn starts 3468c2ecf20Sopenharmony_ci * at the end of a zone and migrate_pfn begins at the start. Movable pages 3478c2ecf20Sopenharmony_ci * are moved to the end of a zone during a compaction run and the run 3488c2ecf20Sopenharmony_ci * completes when free_pfn <= migrate_pfn 3498c2ecf20Sopenharmony_ci */ 3508c2ecf20Sopenharmony_cistruct compact_control { 3518c2ecf20Sopenharmony_ci struct list_head freepages; /* List of free pages to migrate to */ 3528c2ecf20Sopenharmony_ci struct list_head migratepages; /* List of pages being migrated */ 3538c2ecf20Sopenharmony_ci unsigned int nr_freepages; /* Number of isolated free pages */ 3548c2ecf20Sopenharmony_ci unsigned int nr_migratepages; /* Number of pages to migrate */ 3558c2ecf20Sopenharmony_ci unsigned long free_pfn; /* isolate_freepages search base */ 3568c2ecf20Sopenharmony_ci unsigned long migrate_pfn; /* isolate_migratepages search base */ 3578c2ecf20Sopenharmony_ci unsigned long fast_start_pfn; /* a pfn to start linear scan from */ 3588c2ecf20Sopenharmony_ci struct zone *zone; 3598c2ecf20Sopenharmony_ci unsigned long total_migrate_scanned; 3608c2ecf20Sopenharmony_ci unsigned long total_free_scanned; 3618c2ecf20Sopenharmony_ci unsigned short fast_search_fail;/* failures to use free list searches */ 3628c2ecf20Sopenharmony_ci short search_order; /* order to start a fast search at */ 3638c2ecf20Sopenharmony_ci const gfp_t gfp_mask; /* gfp mask of a direct compactor */ 3648c2ecf20Sopenharmony_ci int order; /* order a direct compactor needs */ 3658c2ecf20Sopenharmony_ci int migratetype; /* migratetype of direct compactor */ 3668c2ecf20Sopenharmony_ci const unsigned int alloc_flags; /* alloc flags of a direct compactor */ 3678c2ecf20Sopenharmony_ci const int highest_zoneidx; /* zone index of a direct compactor */ 3688c2ecf20Sopenharmony_ci enum migrate_mode mode; /* Async or sync migration mode */ 3698c2ecf20Sopenharmony_ci bool ignore_skip_hint; /* Scan blocks even if marked skip */ 3708c2ecf20Sopenharmony_ci bool no_set_skip_hint; /* Don't mark blocks for skipping */ 3718c2ecf20Sopenharmony_ci bool ignore_block_suitable; /* Scan blocks considered unsuitable */ 3728c2ecf20Sopenharmony_ci bool direct_compaction; /* False from kcompactd or /proc/... */ 3738c2ecf20Sopenharmony_ci bool proactive_compaction; /* kcompactd proactive compaction */ 3748c2ecf20Sopenharmony_ci bool whole_zone; /* Whole zone should/has been scanned */ 3758c2ecf20Sopenharmony_ci bool contended; /* Signal lock or sched contention */ 3768c2ecf20Sopenharmony_ci bool rescan; /* Rescanning the same pageblock */ 3778c2ecf20Sopenharmony_ci bool alloc_contig; /* alloc_contig_range allocation */ 3788c2ecf20Sopenharmony_ci}; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci/* 3818c2ecf20Sopenharmony_ci * Used in direct compaction when a page should be taken from the freelists 3828c2ecf20Sopenharmony_ci * immediately when one is created during the free path. 3838c2ecf20Sopenharmony_ci */ 3848c2ecf20Sopenharmony_cistruct capture_control { 3858c2ecf20Sopenharmony_ci struct compact_control *cc; 3868c2ecf20Sopenharmony_ci struct page *page; 3878c2ecf20Sopenharmony_ci}; 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ciunsigned long 3908c2ecf20Sopenharmony_ciisolate_freepages_range(struct compact_control *cc, 3918c2ecf20Sopenharmony_ci unsigned long start_pfn, unsigned long end_pfn); 3928c2ecf20Sopenharmony_ciunsigned long 3938c2ecf20Sopenharmony_ciisolate_migratepages_range(struct compact_control *cc, 3948c2ecf20Sopenharmony_ci unsigned long low_pfn, unsigned long end_pfn); 3958c2ecf20Sopenharmony_ciint find_suitable_fallback(struct free_area *area, unsigned int order, 3968c2ecf20Sopenharmony_ci int migratetype, bool only_stealable, bool *can_steal); 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci#endif 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci/* 4018c2ecf20Sopenharmony_ci * This function returns the order of a free page in the buddy system. In 4028c2ecf20Sopenharmony_ci * general, page_zone(page)->lock must be held by the caller to prevent the 4038c2ecf20Sopenharmony_ci * page from being allocated in parallel and returning garbage as the order. 4048c2ecf20Sopenharmony_ci * If a caller does not hold page_zone(page)->lock, it must guarantee that the 4058c2ecf20Sopenharmony_ci * page cannot be allocated or merged in parallel. Alternatively, it must 4068c2ecf20Sopenharmony_ci * handle invalid values gracefully, and use buddy_order_unsafe() below. 4078c2ecf20Sopenharmony_ci */ 4088c2ecf20Sopenharmony_cistatic inline unsigned int buddy_order(struct page *page) 4098c2ecf20Sopenharmony_ci{ 4108c2ecf20Sopenharmony_ci /* PageBuddy() must be checked by the caller */ 4118c2ecf20Sopenharmony_ci return page_private(page); 4128c2ecf20Sopenharmony_ci} 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci/* 4158c2ecf20Sopenharmony_ci * Like buddy_order(), but for callers who cannot afford to hold the zone lock. 4168c2ecf20Sopenharmony_ci * PageBuddy() should be checked first by the caller to minimize race window, 4178c2ecf20Sopenharmony_ci * and invalid values must be handled gracefully. 4188c2ecf20Sopenharmony_ci * 4198c2ecf20Sopenharmony_ci * READ_ONCE is used so that if the caller assigns the result into a local 4208c2ecf20Sopenharmony_ci * variable and e.g. tests it for valid range before using, the compiler cannot 4218c2ecf20Sopenharmony_ci * decide to remove the variable and inline the page_private(page) multiple 4228c2ecf20Sopenharmony_ci * times, potentially observing different values in the tests and the actual 4238c2ecf20Sopenharmony_ci * use of the result. 4248c2ecf20Sopenharmony_ci */ 4258c2ecf20Sopenharmony_ci#define buddy_order_unsafe(page) READ_ONCE(page_private(page)) 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_cistatic inline bool is_cow_mapping(vm_flags_t flags) 4288c2ecf20Sopenharmony_ci{ 4298c2ecf20Sopenharmony_ci return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; 4308c2ecf20Sopenharmony_ci} 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ci/* 4338c2ecf20Sopenharmony_ci * These three helpers classifies VMAs for virtual memory accounting. 4348c2ecf20Sopenharmony_ci */ 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci/* 4378c2ecf20Sopenharmony_ci * Executable code area - executable, not writable, not stack 4388c2ecf20Sopenharmony_ci */ 4398c2ecf20Sopenharmony_cistatic inline bool is_exec_mapping(vm_flags_t flags) 4408c2ecf20Sopenharmony_ci{ 4418c2ecf20Sopenharmony_ci return (flags & (VM_EXEC | VM_WRITE | VM_STACK)) == VM_EXEC; 4428c2ecf20Sopenharmony_ci} 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci/* 4458c2ecf20Sopenharmony_ci * Stack area - atomatically grows in one direction 4468c2ecf20Sopenharmony_ci * 4478c2ecf20Sopenharmony_ci * VM_GROWSUP / VM_GROWSDOWN VMAs are always private anonymous: 4488c2ecf20Sopenharmony_ci * do_mmap() forbids all other combinations. 4498c2ecf20Sopenharmony_ci */ 4508c2ecf20Sopenharmony_cistatic inline bool is_stack_mapping(vm_flags_t flags) 4518c2ecf20Sopenharmony_ci{ 4528c2ecf20Sopenharmony_ci return (flags & VM_STACK) == VM_STACK; 4538c2ecf20Sopenharmony_ci} 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci/* 4568c2ecf20Sopenharmony_ci * Data area - private, writable, not stack 4578c2ecf20Sopenharmony_ci */ 4588c2ecf20Sopenharmony_cistatic inline bool is_data_mapping(vm_flags_t flags) 4598c2ecf20Sopenharmony_ci{ 4608c2ecf20Sopenharmony_ci return (flags & (VM_WRITE | VM_SHARED | VM_STACK)) == VM_WRITE; 4618c2ecf20Sopenharmony_ci} 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci/* mm/util.c */ 4648c2ecf20Sopenharmony_civoid __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, 4658c2ecf20Sopenharmony_ci struct vm_area_struct *prev); 4668c2ecf20Sopenharmony_civoid __vma_unlink_list(struct mm_struct *mm, struct vm_area_struct *vma); 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci#ifdef CONFIG_MMU 4698c2ecf20Sopenharmony_ciextern long populate_vma_page_range(struct vm_area_struct *vma, 4708c2ecf20Sopenharmony_ci unsigned long start, unsigned long end, int *nonblocking); 4718c2ecf20Sopenharmony_ciextern void munlock_vma_pages_range(struct vm_area_struct *vma, 4728c2ecf20Sopenharmony_ci unsigned long start, unsigned long end); 4738c2ecf20Sopenharmony_cistatic inline void munlock_vma_pages_all(struct vm_area_struct *vma) 4748c2ecf20Sopenharmony_ci{ 4758c2ecf20Sopenharmony_ci munlock_vma_pages_range(vma, vma->vm_start, vma->vm_end); 4768c2ecf20Sopenharmony_ci} 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci/* 4798c2ecf20Sopenharmony_ci * must be called with vma's mmap_lock held for read or write, and page locked. 4808c2ecf20Sopenharmony_ci */ 4818c2ecf20Sopenharmony_ciextern void mlock_vma_page(struct page *page); 4828c2ecf20Sopenharmony_ciextern unsigned int munlock_vma_page(struct page *page); 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci/* 4858c2ecf20Sopenharmony_ci * Clear the page's PageMlocked(). This can be useful in a situation where 4868c2ecf20Sopenharmony_ci * we want to unconditionally remove a page from the pagecache -- e.g., 4878c2ecf20Sopenharmony_ci * on truncation or freeing. 4888c2ecf20Sopenharmony_ci * 4898c2ecf20Sopenharmony_ci * It is legal to call this function for any page, mlocked or not. 4908c2ecf20Sopenharmony_ci * If called for a page that is still mapped by mlocked vmas, all we do 4918c2ecf20Sopenharmony_ci * is revert to lazy LRU behaviour -- semantics are not broken. 4928c2ecf20Sopenharmony_ci */ 4938c2ecf20Sopenharmony_ciextern void clear_page_mlock(struct page *page); 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci/* 4968c2ecf20Sopenharmony_ci * mlock_migrate_page - called only from migrate_misplaced_transhuge_page() 4978c2ecf20Sopenharmony_ci * (because that does not go through the full procedure of migration ptes): 4988c2ecf20Sopenharmony_ci * to migrate the Mlocked page flag; update statistics. 4998c2ecf20Sopenharmony_ci */ 5008c2ecf20Sopenharmony_cistatic inline void mlock_migrate_page(struct page *newpage, struct page *page) 5018c2ecf20Sopenharmony_ci{ 5028c2ecf20Sopenharmony_ci if (TestClearPageMlocked(page)) { 5038c2ecf20Sopenharmony_ci int nr_pages = thp_nr_pages(page); 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci /* Holding pmd lock, no change in irq context: __mod is safe */ 5068c2ecf20Sopenharmony_ci __mod_zone_page_state(page_zone(page), NR_MLOCK, -nr_pages); 5078c2ecf20Sopenharmony_ci SetPageMlocked(newpage); 5088c2ecf20Sopenharmony_ci __mod_zone_page_state(page_zone(newpage), NR_MLOCK, nr_pages); 5098c2ecf20Sopenharmony_ci } 5108c2ecf20Sopenharmony_ci} 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ciextern pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma); 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci/* 5158c2ecf20Sopenharmony_ci * At what user virtual address is page expected in vma? 5168c2ecf20Sopenharmony_ci * Returns -EFAULT if all of the page is outside the range of vma. 5178c2ecf20Sopenharmony_ci * If page is a compound head, the entire compound page is considered. 5188c2ecf20Sopenharmony_ci */ 5198c2ecf20Sopenharmony_cistatic inline unsigned long 5208c2ecf20Sopenharmony_civma_address(struct page *page, struct vm_area_struct *vma) 5218c2ecf20Sopenharmony_ci{ 5228c2ecf20Sopenharmony_ci pgoff_t pgoff; 5238c2ecf20Sopenharmony_ci unsigned long address; 5248c2ecf20Sopenharmony_ci 5258c2ecf20Sopenharmony_ci VM_BUG_ON_PAGE(PageKsm(page), page); /* KSM page->index unusable */ 5268c2ecf20Sopenharmony_ci pgoff = page_to_pgoff(page); 5278c2ecf20Sopenharmony_ci if (pgoff >= vma->vm_pgoff) { 5288c2ecf20Sopenharmony_ci address = vma->vm_start + 5298c2ecf20Sopenharmony_ci ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); 5308c2ecf20Sopenharmony_ci /* Check for address beyond vma (or wrapped through 0?) */ 5318c2ecf20Sopenharmony_ci if (address < vma->vm_start || address >= vma->vm_end) 5328c2ecf20Sopenharmony_ci address = -EFAULT; 5338c2ecf20Sopenharmony_ci } else if (PageHead(page) && 5348c2ecf20Sopenharmony_ci pgoff + compound_nr(page) - 1 >= vma->vm_pgoff) { 5358c2ecf20Sopenharmony_ci /* Test above avoids possibility of wrap to 0 on 32-bit */ 5368c2ecf20Sopenharmony_ci address = vma->vm_start; 5378c2ecf20Sopenharmony_ci } else { 5388c2ecf20Sopenharmony_ci address = -EFAULT; 5398c2ecf20Sopenharmony_ci } 5408c2ecf20Sopenharmony_ci return address; 5418c2ecf20Sopenharmony_ci} 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci/* 5448c2ecf20Sopenharmony_ci * Then at what user virtual address will none of the page be found in vma? 5458c2ecf20Sopenharmony_ci * Assumes that vma_address() already returned a good starting address. 5468c2ecf20Sopenharmony_ci * If page is a compound head, the entire compound page is considered. 5478c2ecf20Sopenharmony_ci */ 5488c2ecf20Sopenharmony_cistatic inline unsigned long 5498c2ecf20Sopenharmony_civma_address_end(struct page *page, struct vm_area_struct *vma) 5508c2ecf20Sopenharmony_ci{ 5518c2ecf20Sopenharmony_ci pgoff_t pgoff; 5528c2ecf20Sopenharmony_ci unsigned long address; 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci VM_BUG_ON_PAGE(PageKsm(page), page); /* KSM page->index unusable */ 5558c2ecf20Sopenharmony_ci pgoff = page_to_pgoff(page) + compound_nr(page); 5568c2ecf20Sopenharmony_ci address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); 5578c2ecf20Sopenharmony_ci /* Check for address beyond vma (or wrapped through 0?) */ 5588c2ecf20Sopenharmony_ci if (address < vma->vm_start || address > vma->vm_end) 5598c2ecf20Sopenharmony_ci address = vma->vm_end; 5608c2ecf20Sopenharmony_ci return address; 5618c2ecf20Sopenharmony_ci} 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_cistatic inline struct file *maybe_unlock_mmap_for_io(struct vm_fault *vmf, 5648c2ecf20Sopenharmony_ci struct file *fpin) 5658c2ecf20Sopenharmony_ci{ 5668c2ecf20Sopenharmony_ci int flags = vmf->flags; 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci if (fpin) 5698c2ecf20Sopenharmony_ci return fpin; 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci /* 5728c2ecf20Sopenharmony_ci * FAULT_FLAG_RETRY_NOWAIT means we don't want to wait on page locks or 5738c2ecf20Sopenharmony_ci * anything, so we only pin the file and drop the mmap_lock if only 5748c2ecf20Sopenharmony_ci * FAULT_FLAG_ALLOW_RETRY is set, while this is the first attempt. 5758c2ecf20Sopenharmony_ci */ 5768c2ecf20Sopenharmony_ci if (fault_flag_allow_retry_first(flags) && 5778c2ecf20Sopenharmony_ci !(flags & FAULT_FLAG_RETRY_NOWAIT)) { 5788c2ecf20Sopenharmony_ci fpin = get_file(vmf->vma->vm_file); 5798c2ecf20Sopenharmony_ci mmap_read_unlock(vmf->vma->vm_mm); 5808c2ecf20Sopenharmony_ci } 5818c2ecf20Sopenharmony_ci return fpin; 5828c2ecf20Sopenharmony_ci} 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci#else /* !CONFIG_MMU */ 5858c2ecf20Sopenharmony_cistatic inline void clear_page_mlock(struct page *page) { } 5868c2ecf20Sopenharmony_cistatic inline void mlock_vma_page(struct page *page) { } 5878c2ecf20Sopenharmony_cistatic inline void mlock_migrate_page(struct page *new, struct page *old) { } 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci#endif /* !CONFIG_MMU */ 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci/* 5928c2ecf20Sopenharmony_ci * Return the mem_map entry representing the 'offset' subpage within 5938c2ecf20Sopenharmony_ci * the maximally aligned gigantic page 'base'. Handle any discontiguity 5948c2ecf20Sopenharmony_ci * in the mem_map at MAX_ORDER_NR_PAGES boundaries. 5958c2ecf20Sopenharmony_ci */ 5968c2ecf20Sopenharmony_cistatic inline struct page *mem_map_offset(struct page *base, int offset) 5978c2ecf20Sopenharmony_ci{ 5988c2ecf20Sopenharmony_ci if (unlikely(offset >= MAX_ORDER_NR_PAGES)) 5998c2ecf20Sopenharmony_ci return nth_page(base, offset); 6008c2ecf20Sopenharmony_ci return base + offset; 6018c2ecf20Sopenharmony_ci} 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci/* 6048c2ecf20Sopenharmony_ci * Iterator over all subpages within the maximally aligned gigantic 6058c2ecf20Sopenharmony_ci * page 'base'. Handle any discontiguity in the mem_map. 6068c2ecf20Sopenharmony_ci */ 6078c2ecf20Sopenharmony_cistatic inline struct page *mem_map_next(struct page *iter, 6088c2ecf20Sopenharmony_ci struct page *base, int offset) 6098c2ecf20Sopenharmony_ci{ 6108c2ecf20Sopenharmony_ci if (unlikely((offset & (MAX_ORDER_NR_PAGES - 1)) == 0)) { 6118c2ecf20Sopenharmony_ci unsigned long pfn = page_to_pfn(base) + offset; 6128c2ecf20Sopenharmony_ci if (!pfn_valid(pfn)) 6138c2ecf20Sopenharmony_ci return NULL; 6148c2ecf20Sopenharmony_ci return pfn_to_page(pfn); 6158c2ecf20Sopenharmony_ci } 6168c2ecf20Sopenharmony_ci return iter + 1; 6178c2ecf20Sopenharmony_ci} 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_ci/* Memory initialisation debug and verification */ 6208c2ecf20Sopenharmony_cienum mminit_level { 6218c2ecf20Sopenharmony_ci MMINIT_WARNING, 6228c2ecf20Sopenharmony_ci MMINIT_VERIFY, 6238c2ecf20Sopenharmony_ci MMINIT_TRACE 6248c2ecf20Sopenharmony_ci}; 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_MEMORY_INIT 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ciextern int mminit_loglevel; 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci#define mminit_dprintk(level, prefix, fmt, arg...) \ 6318c2ecf20Sopenharmony_cido { \ 6328c2ecf20Sopenharmony_ci if (level < mminit_loglevel) { \ 6338c2ecf20Sopenharmony_ci if (level <= MMINIT_WARNING) \ 6348c2ecf20Sopenharmony_ci pr_warn("mminit::" prefix " " fmt, ##arg); \ 6358c2ecf20Sopenharmony_ci else \ 6368c2ecf20Sopenharmony_ci printk(KERN_DEBUG "mminit::" prefix " " fmt, ##arg); \ 6378c2ecf20Sopenharmony_ci } \ 6388c2ecf20Sopenharmony_ci} while (0) 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_ciextern void mminit_verify_pageflags_layout(void); 6418c2ecf20Sopenharmony_ciextern void mminit_verify_zonelist(void); 6428c2ecf20Sopenharmony_ci#else 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_cistatic inline void mminit_dprintk(enum mminit_level level, 6458c2ecf20Sopenharmony_ci const char *prefix, const char *fmt, ...) 6468c2ecf20Sopenharmony_ci{ 6478c2ecf20Sopenharmony_ci} 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_cistatic inline void mminit_verify_pageflags_layout(void) 6508c2ecf20Sopenharmony_ci{ 6518c2ecf20Sopenharmony_ci} 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_cistatic inline void mminit_verify_zonelist(void) 6548c2ecf20Sopenharmony_ci{ 6558c2ecf20Sopenharmony_ci} 6568c2ecf20Sopenharmony_ci#endif /* CONFIG_DEBUG_MEMORY_INIT */ 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci/* mminit_validate_memmodel_limits is independent of CONFIG_DEBUG_MEMORY_INIT */ 6598c2ecf20Sopenharmony_ci#if defined(CONFIG_SPARSEMEM) 6608c2ecf20Sopenharmony_ciextern void mminit_validate_memmodel_limits(unsigned long *start_pfn, 6618c2ecf20Sopenharmony_ci unsigned long *end_pfn); 6628c2ecf20Sopenharmony_ci#else 6638c2ecf20Sopenharmony_cistatic inline void mminit_validate_memmodel_limits(unsigned long *start_pfn, 6648c2ecf20Sopenharmony_ci unsigned long *end_pfn) 6658c2ecf20Sopenharmony_ci{ 6668c2ecf20Sopenharmony_ci} 6678c2ecf20Sopenharmony_ci#endif /* CONFIG_SPARSEMEM */ 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci#define NODE_RECLAIM_NOSCAN -2 6708c2ecf20Sopenharmony_ci#define NODE_RECLAIM_FULL -1 6718c2ecf20Sopenharmony_ci#define NODE_RECLAIM_SOME 0 6728c2ecf20Sopenharmony_ci#define NODE_RECLAIM_SUCCESS 1 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci#ifdef CONFIG_NUMA 6758c2ecf20Sopenharmony_ciextern int node_reclaim(struct pglist_data *, gfp_t, unsigned int); 6768c2ecf20Sopenharmony_ci#else 6778c2ecf20Sopenharmony_cistatic inline int node_reclaim(struct pglist_data *pgdat, gfp_t mask, 6788c2ecf20Sopenharmony_ci unsigned int order) 6798c2ecf20Sopenharmony_ci{ 6808c2ecf20Sopenharmony_ci return NODE_RECLAIM_NOSCAN; 6818c2ecf20Sopenharmony_ci} 6828c2ecf20Sopenharmony_ci#endif 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_ciextern int hwpoison_filter(struct page *p); 6858c2ecf20Sopenharmony_ci 6868c2ecf20Sopenharmony_ciextern u32 hwpoison_filter_dev_major; 6878c2ecf20Sopenharmony_ciextern u32 hwpoison_filter_dev_minor; 6888c2ecf20Sopenharmony_ciextern u64 hwpoison_filter_flags_mask; 6898c2ecf20Sopenharmony_ciextern u64 hwpoison_filter_flags_value; 6908c2ecf20Sopenharmony_ciextern u64 hwpoison_filter_memcg; 6918c2ecf20Sopenharmony_ciextern u32 hwpoison_filter_enable; 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ciextern unsigned long __must_check vm_mmap_pgoff(struct file *, unsigned long, 6948c2ecf20Sopenharmony_ci unsigned long, unsigned long, 6958c2ecf20Sopenharmony_ci unsigned long, unsigned long); 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ciextern void set_pageblock_order(void); 6988c2ecf20Sopenharmony_ciunsigned int reclaim_clean_pages_from_list(struct zone *zone, 6998c2ecf20Sopenharmony_ci struct list_head *page_list); 7008c2ecf20Sopenharmony_ci/* The ALLOC_WMARK bits are used as an index to zone->watermark */ 7018c2ecf20Sopenharmony_ci#define ALLOC_WMARK_MIN WMARK_MIN 7028c2ecf20Sopenharmony_ci#define ALLOC_WMARK_LOW WMARK_LOW 7038c2ecf20Sopenharmony_ci#define ALLOC_WMARK_HIGH WMARK_HIGH 7048c2ecf20Sopenharmony_ci#define ALLOC_NO_WATERMARKS 0x04 /* don't check watermarks at all */ 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ci/* Mask to get the watermark bits */ 7078c2ecf20Sopenharmony_ci#define ALLOC_WMARK_MASK (ALLOC_NO_WATERMARKS-1) 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci/* 7108c2ecf20Sopenharmony_ci * Only MMU archs have async oom victim reclaim - aka oom_reaper so we 7118c2ecf20Sopenharmony_ci * cannot assume a reduced access to memory reserves is sufficient for 7128c2ecf20Sopenharmony_ci * !MMU 7138c2ecf20Sopenharmony_ci */ 7148c2ecf20Sopenharmony_ci#ifdef CONFIG_MMU 7158c2ecf20Sopenharmony_ci#define ALLOC_OOM 0x08 7168c2ecf20Sopenharmony_ci#else 7178c2ecf20Sopenharmony_ci#define ALLOC_OOM ALLOC_NO_WATERMARKS 7188c2ecf20Sopenharmony_ci#endif 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci#define ALLOC_HARDER 0x10 /* try to alloc harder */ 7218c2ecf20Sopenharmony_ci#define ALLOC_HIGH 0x20 /* __GFP_HIGH set */ 7228c2ecf20Sopenharmony_ci#define ALLOC_CPUSET 0x40 /* check for correct cpuset */ 7238c2ecf20Sopenharmony_ci#define ALLOC_CMA 0x80 /* allow allocations from CMA areas */ 7248c2ecf20Sopenharmony_ci#ifdef CONFIG_ZONE_DMA32 7258c2ecf20Sopenharmony_ci#define ALLOC_NOFRAGMENT 0x100 /* avoid mixing pageblock types */ 7268c2ecf20Sopenharmony_ci#else 7278c2ecf20Sopenharmony_ci#define ALLOC_NOFRAGMENT 0x0 7288c2ecf20Sopenharmony_ci#endif 7298c2ecf20Sopenharmony_ci#define ALLOC_KSWAPD 0x800 /* allow waking of kswapd, __GFP_KSWAPD_RECLAIM set */ 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_cienum ttu_flags; 7328c2ecf20Sopenharmony_cistruct tlbflush_unmap_batch; 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci/* 7368c2ecf20Sopenharmony_ci * only for MM internal work items which do not depend on 7378c2ecf20Sopenharmony_ci * any allocations or locks which might depend on allocations 7388c2ecf20Sopenharmony_ci */ 7398c2ecf20Sopenharmony_ciextern struct workqueue_struct *mm_percpu_wq; 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_ci#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH 7428c2ecf20Sopenharmony_civoid try_to_unmap_flush(void); 7438c2ecf20Sopenharmony_civoid try_to_unmap_flush_dirty(void); 7448c2ecf20Sopenharmony_civoid flush_tlb_batched_pending(struct mm_struct *mm); 7458c2ecf20Sopenharmony_ci#else 7468c2ecf20Sopenharmony_cistatic inline void try_to_unmap_flush(void) 7478c2ecf20Sopenharmony_ci{ 7488c2ecf20Sopenharmony_ci} 7498c2ecf20Sopenharmony_cistatic inline void try_to_unmap_flush_dirty(void) 7508c2ecf20Sopenharmony_ci{ 7518c2ecf20Sopenharmony_ci} 7528c2ecf20Sopenharmony_cistatic inline void flush_tlb_batched_pending(struct mm_struct *mm) 7538c2ecf20Sopenharmony_ci{ 7548c2ecf20Sopenharmony_ci} 7558c2ecf20Sopenharmony_ci#endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */ 7568c2ecf20Sopenharmony_ci 7578c2ecf20Sopenharmony_ciextern const struct trace_print_flags pageflag_names[]; 7588c2ecf20Sopenharmony_ciextern const struct trace_print_flags vmaflag_names[]; 7598c2ecf20Sopenharmony_ciextern const struct trace_print_flags gfpflag_names[]; 7608c2ecf20Sopenharmony_ci 7618c2ecf20Sopenharmony_cistatic inline bool is_migrate_highatomic(enum migratetype migratetype) 7628c2ecf20Sopenharmony_ci{ 7638c2ecf20Sopenharmony_ci return migratetype == MIGRATE_HIGHATOMIC; 7648c2ecf20Sopenharmony_ci} 7658c2ecf20Sopenharmony_ci 7668c2ecf20Sopenharmony_cistatic inline bool is_migrate_highatomic_page(struct page *page) 7678c2ecf20Sopenharmony_ci{ 7688c2ecf20Sopenharmony_ci return get_pageblock_migratetype(page) == MIGRATE_HIGHATOMIC; 7698c2ecf20Sopenharmony_ci} 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_civoid setup_zone_pageset(struct zone *zone); 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_cistruct migration_target_control { 7748c2ecf20Sopenharmony_ci int nid; /* preferred node id */ 7758c2ecf20Sopenharmony_ci nodemask_t *nmask; 7768c2ecf20Sopenharmony_ci gfp_t gfp_mask; 7778c2ecf20Sopenharmony_ci}; 7788c2ecf20Sopenharmony_ci 7798c2ecf20Sopenharmony_ci#ifdef CONFIG_RECLAIM_ACCT 7808c2ecf20Sopenharmony_ci#define DELAY_LV0 5000000 /* 5ms */ 7818c2ecf20Sopenharmony_ci#define DELAY_LV1 10000000 /* 10ms */ 7828c2ecf20Sopenharmony_ci#define DELAY_LV2 50000000 /* 50ms */ 7838c2ecf20Sopenharmony_ci#define DELAY_LV3 100000000 /* 100ms */ 7848c2ecf20Sopenharmony_ci#define DELAY_LV4 2000000000 /* 2000ms */ 7858c2ecf20Sopenharmony_ci#define DELAY_LV5 50000000000 /* 50000ms */ 7868c2ecf20Sopenharmony_ci#define NR_DELAY_LV 6 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_cistruct reclaim_acct { 7898c2ecf20Sopenharmony_ci u64 start[NR_RA_STUBS]; 7908c2ecf20Sopenharmony_ci u64 delay[NR_RA_STUBS]; 7918c2ecf20Sopenharmony_ci u64 count[NR_RA_STUBS]; 7928c2ecf20Sopenharmony_ci u64 freed[NR_RA_STUBS]; 7938c2ecf20Sopenharmony_ci unsigned int reclaim_type; 7948c2ecf20Sopenharmony_ci}; 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_cibool reclaimacct_initialize_show_data(void); 7978c2ecf20Sopenharmony_civoid reclaimacct_reinitialize_show_data(void); 7988c2ecf20Sopenharmony_civoid reclaimacct_destroy_show_data(void); 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_civoid reclaimacct_collect_data(void); 8018c2ecf20Sopenharmony_civoid reclaimacct_collect_reclaim_efficiency(void); 8028c2ecf20Sopenharmony_ci#endif 8038c2ecf20Sopenharmony_ci 8048c2ecf20Sopenharmony_ci#endif /* __MM_INTERNAL_H */ 805