at v6.14 3.0 kB view raw
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 8struct pglist_data; 9 10#ifdef CONFIG_PAGE_EXTENSION 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 */ 24struct 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/* 33 * The page_ext_flags users must set need_shared_flags to true. 34 */ 35enum page_ext_flags { 36 PAGE_EXT_OWNER, 37 PAGE_EXT_OWNER_ALLOCATED, 38#if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT) 39 PAGE_EXT_YOUNG, 40 PAGE_EXT_IDLE, 41#endif 42}; 43 44/* 45 * Page Extension can be considered as an extended mem_map. 46 * A page_ext page is associated with every page descriptor. The 47 * page_ext helps us add more information about the page. 48 * All page_ext are allocated at boot or memory hotplug event, 49 * then the page_ext for pfn always exists. 50 */ 51struct page_ext { 52 unsigned long flags; 53}; 54 55extern bool early_page_ext; 56extern unsigned long page_ext_size; 57extern void pgdat_page_ext_init(struct pglist_data *pgdat); 58 59static inline bool early_page_ext_enabled(void) 60{ 61 return early_page_ext; 62} 63 64#ifdef CONFIG_SPARSEMEM 65static inline void page_ext_init_flatmem(void) 66{ 67} 68extern void page_ext_init(void); 69static inline void page_ext_init_flatmem_late(void) 70{ 71} 72#else 73extern void page_ext_init_flatmem(void); 74extern void page_ext_init_flatmem_late(void); 75static inline void page_ext_init(void) 76{ 77} 78#endif 79 80extern struct page_ext *page_ext_get(const struct page *page); 81extern void page_ext_put(struct page_ext *page_ext); 82 83static inline void *page_ext_data(struct page_ext *page_ext, 84 struct page_ext_operations *ops) 85{ 86 return (void *)(page_ext) + ops->offset; 87} 88 89static inline struct page_ext *page_ext_next(struct page_ext *curr) 90{ 91 void *next = curr; 92 next += page_ext_size; 93 return next; 94} 95 96#else /* !CONFIG_PAGE_EXTENSION */ 97struct page_ext; 98 99static inline bool early_page_ext_enabled(void) 100{ 101 return false; 102} 103 104static inline void pgdat_page_ext_init(struct pglist_data *pgdat) 105{ 106} 107 108static inline void page_ext_init(void) 109{ 110} 111 112static inline void page_ext_init_flatmem_late(void) 113{ 114} 115 116static inline void page_ext_init_flatmem(void) 117{ 118} 119 120static inline struct page_ext *page_ext_get(const struct page *page) 121{ 122 return NULL; 123} 124 125static inline void page_ext_put(struct page_ext *page_ext) 126{ 127} 128#endif /* CONFIG_PAGE_EXTENSION */ 129#endif /* __LINUX_PAGE_EXT_H */