1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __LINUX_PAGE_EXT_H 3 #define __LINUX_PAGE_EXT_H 4 5 #include <linux/types.h> 6 #include <linux/stacktrace.h> 7 #include <linux/stackdepot.h> 8 9 struct pglist_data; 10 11 /** 12 * struct page_ext_operations - per page_ext client operations 13 * @offset: Offset to the client's data within page_ext. Offset is returned to 14 * the client by page_ext_init. 15 * @size: The size of the client data within page_ext. 16 * @need: Function that returns true if client requires page_ext. 17 * @init: (optional) Called to initialize client once page_exts are allocated. 18 * @need_shared_flags: True when client is using shared page_ext->flags 19 * field. 20 * 21 * Each Page Extension client must define page_ext_operations in 22 * page_ext_ops array. 23 */ 24 struct page_ext_operations { 25 size_t offset; 26 size_t size; 27 bool (*need)(void); 28 void (*init)(void); 29 bool need_shared_flags; 30 }; 31 32 #ifdef CONFIG_PAGE_EXTENSION 33 34 /* 35 * The page_ext_flags users must set need_shared_flags to true. 36 */ 37 enum page_ext_flags { 38 PAGE_EXT_OWNER, 39 PAGE_EXT_OWNER_ALLOCATED, 40 #if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT) 41 PAGE_EXT_YOUNG, 42 PAGE_EXT_IDLE, 43 #endif 44 }; 45 46 /* 47 * Page Extension can be considered as an extended mem_map. 48 * A page_ext page is associated with every page descriptor. The 49 * page_ext helps us add more information about the page. 50 * All page_ext are allocated at boot or memory hotplug event, 51 * then the page_ext for pfn always exists. 52 */ 53 struct page_ext { 54 unsigned long flags; 55 }; 56 57 extern bool early_page_ext; 58 extern unsigned long page_ext_size; 59 extern void pgdat_page_ext_init(struct pglist_data *pgdat); 60 61 static inline bool early_page_ext_enabled(void) 62 { 63 return early_page_ext; 64 } 65 66 #ifdef CONFIG_SPARSEMEM 67 static inline void page_ext_init_flatmem(void) 68 { 69 } 70 extern void page_ext_init(void); 71 static inline void page_ext_init_flatmem_late(void) 72 { 73 } 74 #else 75 extern void page_ext_init_flatmem(void); 76 extern void page_ext_init_flatmem_late(void); 77 static inline void page_ext_init(void) 78 { 79 } 80 #endif 81 82 extern struct page_ext *page_ext_get(struct page *page); 83 extern void page_ext_put(struct page_ext *page_ext); 84 85 static inline struct page_ext *page_ext_next(struct page_ext *curr) 86 { 87 void *next = curr; 88 next += page_ext_size; 89 return next; 90 } 91 92 #else /* !CONFIG_PAGE_EXTENSION */ 93 struct page_ext; 94 95 static inline bool early_page_ext_enabled(void) 96 { 97 return false; 98 } 99 100 static inline void pgdat_page_ext_init(struct pglist_data *pgdat) 101 { 102 } 103 104 static inline void page_ext_init(void) 105 { 106 } 107 108 static inline void page_ext_init_flatmem_late(void) 109 { 110 } 111 112 static inline void page_ext_init_flatmem(void) 113 { 114 } 115 116 static inline struct page_ext *page_ext_get(struct page *page) 117 { 118 return NULL; 119 } 120 121 static inline void page_ext_put(struct page_ext *page_ext) 122 { 123 } 124 #endif /* CONFIG_PAGE_EXTENSION */ 125 #endif /* __LINUX_PAGE_EXT_H */ 126