xref: /linux/mm/hugetlb_vmemmap.h (revision bbfd5594756011167b8f8de9a00e0c946afda1e6)
1f41f2ed4SMuchun Song // SPDX-License-Identifier: GPL-2.0
2f41f2ed4SMuchun Song /*
3dff03381SMuchun Song  * HugeTLB Vmemmap Optimization (HVO)
4f41f2ed4SMuchun Song  *
5dff03381SMuchun Song  * Copyright (c) 2020, ByteDance. All rights reserved.
6f41f2ed4SMuchun Song  *
7f41f2ed4SMuchun Song  *     Author: Muchun Song <songmuchun@bytedance.com>
8f41f2ed4SMuchun Song  */
9f41f2ed4SMuchun Song #ifndef _LINUX_HUGETLB_VMEMMAP_H
10f41f2ed4SMuchun Song #define _LINUX_HUGETLB_VMEMMAP_H
11f41f2ed4SMuchun Song #include <linux/hugetlb.h>
12*b1222550SFrank van der Linden #include <linux/io.h>
13*b1222550SFrank van der Linden #include <linux/memblock.h>
14f41f2ed4SMuchun Song 
15b65d4adbSMuchun Song /*
166213834cSMuchun Song  * Reserve one vmemmap page, all vmemmap addresses are mapped to it. See
17e5b16c86SVegard Nossum  * Documentation/mm/vmemmap_dedup.rst.
18b65d4adbSMuchun Song  */
196213834cSMuchun Song #define HUGETLB_VMEMMAP_RESERVE_SIZE	PAGE_SIZE
20fde1c4ecSUsama Arif #define HUGETLB_VMEMMAP_RESERVE_PAGES	(HUGETLB_VMEMMAP_RESERVE_SIZE / sizeof(struct page))
21fde1c4ecSUsama Arif 
22fde1c4ecSUsama Arif #ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
23c5ad3233SUsama Arif int hugetlb_vmemmap_restore_folio(const struct hstate *h, struct folio *folio);
24cfb8c750SMike Kravetz long hugetlb_vmemmap_restore_folios(const struct hstate *h,
25cfb8c750SMike Kravetz 					struct list_head *folio_list,
26cfb8c750SMike Kravetz 					struct list_head *non_hvo_folios);
27c5ad3233SUsama Arif void hugetlb_vmemmap_optimize_folio(const struct hstate *h, struct folio *folio);
2879359d6dSMike Kravetz void hugetlb_vmemmap_optimize_folios(struct hstate *h, struct list_head *folio_list);
29752fe17aSFrank van der Linden void hugetlb_vmemmap_optimize_bootmem_folios(struct hstate *h, struct list_head *folio_list);
30*b1222550SFrank van der Linden #ifdef CONFIG_SPARSEMEM_VMEMMAP_PREINIT
31*b1222550SFrank van der Linden void hugetlb_vmemmap_init_early(int nid);
32*b1222550SFrank van der Linden void hugetlb_vmemmap_init_late(int nid);
33*b1222550SFrank van der Linden #endif
34752fe17aSFrank van der Linden 
356213834cSMuchun Song 
hugetlb_vmemmap_size(const struct hstate * h)366213834cSMuchun Song static inline unsigned int hugetlb_vmemmap_size(const struct hstate *h)
37b65d4adbSMuchun Song {
386213834cSMuchun Song 	return pages_per_huge_page(h) * sizeof(struct page);
396213834cSMuchun Song }
406213834cSMuchun Song 
416213834cSMuchun Song /*
426213834cSMuchun Song  * Return how many vmemmap size associated with a HugeTLB page that can be
436213834cSMuchun Song  * optimized and can be freed to the buddy allocator.
446213834cSMuchun Song  */
hugetlb_vmemmap_optimizable_size(const struct hstate * h)456213834cSMuchun Song static inline unsigned int hugetlb_vmemmap_optimizable_size(const struct hstate *h)
466213834cSMuchun Song {
476213834cSMuchun Song 	int size = hugetlb_vmemmap_size(h) - HUGETLB_VMEMMAP_RESERVE_SIZE;
486213834cSMuchun Song 
496213834cSMuchun Song 	if (!is_power_of_2(sizeof(struct page)))
506213834cSMuchun Song 		return 0;
516213834cSMuchun Song 	return size > 0 ? size : 0;
52b65d4adbSMuchun Song }
53f41f2ed4SMuchun Song #else
hugetlb_vmemmap_restore_folio(const struct hstate * h,struct folio * folio)54c5ad3233SUsama Arif static inline int hugetlb_vmemmap_restore_folio(const struct hstate *h, struct folio *folio)
55ad2fa371SMuchun Song {
56ad2fa371SMuchun Song 	return 0;
57ad2fa371SMuchun Song }
58ad2fa371SMuchun Song 
hugetlb_vmemmap_restore_folios(const struct hstate * h,struct list_head * folio_list,struct list_head * non_hvo_folios)59eefd3d02SFrank van der Linden static inline long hugetlb_vmemmap_restore_folios(const struct hstate *h,
60cfb8c750SMike Kravetz 					struct list_head *folio_list,
61cfb8c750SMike Kravetz 					struct list_head *non_hvo_folios)
62cfb8c750SMike Kravetz {
63cfb8c750SMike Kravetz 	list_splice_init(folio_list, non_hvo_folios);
64cfb8c750SMike Kravetz 	return 0;
65cfb8c750SMike Kravetz }
66cfb8c750SMike Kravetz 
hugetlb_vmemmap_optimize_folio(const struct hstate * h,struct folio * folio)67c5ad3233SUsama Arif static inline void hugetlb_vmemmap_optimize_folio(const struct hstate *h, struct folio *folio)
68f41f2ed4SMuchun Song {
69f41f2ed4SMuchun Song }
70b65d4adbSMuchun Song 
hugetlb_vmemmap_optimize_folios(struct hstate * h,struct list_head * folio_list)7179359d6dSMike Kravetz static inline void hugetlb_vmemmap_optimize_folios(struct hstate *h, struct list_head *folio_list)
7279359d6dSMike Kravetz {
7379359d6dSMike Kravetz }
7479359d6dSMike Kravetz 
hugetlb_vmemmap_optimize_bootmem_folios(struct hstate * h,struct list_head * folio_list)75752fe17aSFrank van der Linden static inline void hugetlb_vmemmap_optimize_bootmem_folios(struct hstate *h,
76752fe17aSFrank van der Linden 						struct list_head *folio_list)
77752fe17aSFrank van der Linden {
78752fe17aSFrank van der Linden }
79752fe17aSFrank van der Linden 
hugetlb_vmemmap_init_early(int nid)80*b1222550SFrank van der Linden static inline void hugetlb_vmemmap_init_early(int nid)
81*b1222550SFrank van der Linden {
82*b1222550SFrank van der Linden }
83*b1222550SFrank van der Linden 
hugetlb_vmemmap_init_late(int nid)84*b1222550SFrank van der Linden static inline void hugetlb_vmemmap_init_late(int nid)
85*b1222550SFrank van der Linden {
86*b1222550SFrank van der Linden }
87*b1222550SFrank van der Linden 
hugetlb_vmemmap_optimizable_size(const struct hstate * h)886213834cSMuchun Song static inline unsigned int hugetlb_vmemmap_optimizable_size(const struct hstate *h)
89b65d4adbSMuchun Song {
90b65d4adbSMuchun Song 	return 0;
91b65d4adbSMuchun Song }
9247010c04SMuchun Song #endif /* CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP */
936213834cSMuchun Song 
hugetlb_vmemmap_optimizable(const struct hstate * h)946213834cSMuchun Song static inline bool hugetlb_vmemmap_optimizable(const struct hstate *h)
956213834cSMuchun Song {
966213834cSMuchun Song 	return hugetlb_vmemmap_optimizable_size(h) != 0;
976213834cSMuchun Song }
98f41f2ed4SMuchun Song #endif /* _LINUX_HUGETLB_VMEMMAP_H */
99