1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * sparse.h: 4 * 5 * mm/ internal sparse and sparse-vmemmap declarations 6 */ 7 8 #ifndef __MM_SPARSE_H 9 #define __MM_SPARSE_H 10 11 #include <linux/mmzone.h> 12 13 /* 14 * mm/sparse.c 15 */ 16 #ifdef CONFIG_SPARSEMEM 17 void sparse_init(void); 18 int sparse_index_init(unsigned long section_nr, int nid); 19 20 static inline void sparse_init_one_section(struct mem_section *ms, 21 unsigned long pnum, struct page *mem_map, 22 struct mem_section_usage *usage, unsigned long flags) 23 { 24 unsigned long coded_mem_map; 25 26 BUILD_BUG_ON(SECTION_MAP_LAST_BIT > PFN_SECTION_SHIFT); 27 28 /* 29 * We encode the start PFN of the section into the mem_map such that 30 * page_to_pfn() on !CONFIG_SPARSEMEM_VMEMMAP can simply subtract it 31 * from the page pointer to obtain the PFN. 32 */ 33 coded_mem_map = (unsigned long)(mem_map - section_nr_to_pfn(pnum)); 34 VM_WARN_ON_ONCE(coded_mem_map & ~SECTION_MAP_MASK); 35 36 ms->section_mem_map &= ~SECTION_MAP_MASK; 37 ms->section_mem_map |= coded_mem_map; 38 ms->section_mem_map |= flags | SECTION_HAS_MEM_MAP; 39 ms->usage = usage; 40 } 41 42 static inline void __section_mark_present(struct mem_section *ms, 43 unsigned long section_nr) 44 { 45 if (section_nr > __highest_present_section_nr) 46 __highest_present_section_nr = section_nr; 47 48 ms->section_mem_map |= SECTION_MARKED_PRESENT; 49 } 50 51 static inline size_t mem_section_usage_size(void) 52 { 53 return struct_size_t(struct mem_section_usage, pageblock_flags, 54 BITS_TO_LONGS(SECTION_BLOCKFLAGS_BITS)); 55 } 56 #else 57 static inline void sparse_init(void) {} 58 #endif /* CONFIG_SPARSEMEM */ 59 60 /* 61 * mm/sparse-vmemmap.c 62 */ 63 #ifdef CONFIG_SPARSEMEM_VMEMMAP 64 void sparse_init_subsection_map(void); 65 #else 66 static inline void sparse_init_subsection_map(void) {} 67 #endif /* CONFIG_SPARSEMEM_VMEMMAP */ 68 69 #endif /* __MM_SPARSE_H */ 70