xref: /linux/mm/hugetlb_internal.h (revision f4b369c6fe0ceaba2da2daff8c9eb415f85926dd)
1ecd6703fSHui Zhu /* SPDX-License-Identifier: GPL-2.0 */
2ecd6703fSHui Zhu /*
3ecd6703fSHui Zhu  * Internal HugeTLB definitions.
4ecd6703fSHui Zhu  * (C) Nadia Yvette Chambers, April 2004
5ecd6703fSHui Zhu  */
6ecd6703fSHui Zhu 
7ecd6703fSHui Zhu #ifndef _LINUX_HUGETLB_INTERNAL_H
8ecd6703fSHui Zhu #define _LINUX_HUGETLB_INTERNAL_H
9ecd6703fSHui Zhu 
10ecd6703fSHui Zhu #include <linux/hugetlb.h>
11ecd6703fSHui Zhu #include <linux/hugetlb_cgroup.h>
12ecd6703fSHui Zhu 
13ecd6703fSHui Zhu /*
14ecd6703fSHui Zhu  * Check if the hstate represents gigantic pages but gigantic page
15ecd6703fSHui Zhu  * runtime support is not available. This is a common condition used to
16ecd6703fSHui Zhu  * skip operations that cannot be performed on gigantic pages when runtime
17ecd6703fSHui Zhu  * support is disabled.
18ecd6703fSHui Zhu  */
hstate_is_gigantic_no_runtime(struct hstate * h)19ecd6703fSHui Zhu static inline bool hstate_is_gigantic_no_runtime(struct hstate *h)
20ecd6703fSHui Zhu {
21ecd6703fSHui Zhu 	return hstate_is_gigantic(h) && !gigantic_page_runtime_supported();
22ecd6703fSHui Zhu }
23ecd6703fSHui Zhu 
24ecd6703fSHui Zhu /*
25ecd6703fSHui Zhu  * common helper functions for hstate_next_node_to_{alloc|free}.
26ecd6703fSHui Zhu  * We may have allocated or freed a huge page based on a different
27ecd6703fSHui Zhu  * nodes_allowed previously, so h->next_node_to_{alloc|free} might
28ecd6703fSHui Zhu  * be outside of *nodes_allowed.  Ensure that we use an allowed
29ecd6703fSHui Zhu  * node for alloc or free.
30ecd6703fSHui Zhu  */
next_node_allowed(int nid,nodemask_t * nodes_allowed)31ecd6703fSHui Zhu static inline int next_node_allowed(int nid, nodemask_t *nodes_allowed)
32ecd6703fSHui Zhu {
33ecd6703fSHui Zhu 	nid = next_node_in(nid, *nodes_allowed);
34ecd6703fSHui Zhu 	VM_BUG_ON(nid >= MAX_NUMNODES);
35ecd6703fSHui Zhu 
36ecd6703fSHui Zhu 	return nid;
37ecd6703fSHui Zhu }
38ecd6703fSHui Zhu 
get_valid_node_allowed(int nid,nodemask_t * nodes_allowed)39ecd6703fSHui Zhu static inline int get_valid_node_allowed(int nid, nodemask_t *nodes_allowed)
40ecd6703fSHui Zhu {
41ecd6703fSHui Zhu 	if (!node_isset(nid, *nodes_allowed))
42ecd6703fSHui Zhu 		nid = next_node_allowed(nid, nodes_allowed);
43ecd6703fSHui Zhu 	return nid;
44ecd6703fSHui Zhu }
45ecd6703fSHui Zhu 
46ecd6703fSHui Zhu /*
47ecd6703fSHui Zhu  * returns the previously saved node ["this node"] from which to
48ecd6703fSHui Zhu  * allocate a persistent huge page for the pool and advance the
49ecd6703fSHui Zhu  * next node from which to allocate, handling wrap at end of node
50ecd6703fSHui Zhu  * mask.
51ecd6703fSHui Zhu  */
hstate_next_node_to_alloc(int * next_node,nodemask_t * nodes_allowed)52ecd6703fSHui Zhu static inline int hstate_next_node_to_alloc(int *next_node,
53ecd6703fSHui Zhu 					    nodemask_t *nodes_allowed)
54ecd6703fSHui Zhu {
55ecd6703fSHui Zhu 	int nid;
56ecd6703fSHui Zhu 
57ecd6703fSHui Zhu 	VM_BUG_ON(!nodes_allowed);
58ecd6703fSHui Zhu 
59ecd6703fSHui Zhu 	nid = get_valid_node_allowed(*next_node, nodes_allowed);
60ecd6703fSHui Zhu 	*next_node = next_node_allowed(nid, nodes_allowed);
61ecd6703fSHui Zhu 
62ecd6703fSHui Zhu 	return nid;
63ecd6703fSHui Zhu }
64ecd6703fSHui Zhu 
65ecd6703fSHui Zhu /*
66ecd6703fSHui Zhu  * helper for remove_pool_hugetlb_folio() - return the previously saved
67ecd6703fSHui Zhu  * node ["this node"] from which to free a huge page.  Advance the
68ecd6703fSHui Zhu  * next node id whether or not we find a free huge page to free so
69ecd6703fSHui Zhu  * that the next attempt to free addresses the next node.
70ecd6703fSHui Zhu  */
hstate_next_node_to_free(struct hstate * h,nodemask_t * nodes_allowed)71ecd6703fSHui Zhu static inline int hstate_next_node_to_free(struct hstate *h, nodemask_t *nodes_allowed)
72ecd6703fSHui Zhu {
73ecd6703fSHui Zhu 	int nid;
74ecd6703fSHui Zhu 
75ecd6703fSHui Zhu 	VM_BUG_ON(!nodes_allowed);
76ecd6703fSHui Zhu 
77ecd6703fSHui Zhu 	nid = get_valid_node_allowed(h->next_nid_to_free, nodes_allowed);
78ecd6703fSHui Zhu 	h->next_nid_to_free = next_node_allowed(nid, nodes_allowed);
79ecd6703fSHui Zhu 
80ecd6703fSHui Zhu 	return nid;
81ecd6703fSHui Zhu }
82ecd6703fSHui Zhu 
83ecd6703fSHui Zhu #define for_each_node_mask_to_alloc(next_node, nr_nodes, node, mask)		\
84ecd6703fSHui Zhu 	for (nr_nodes = nodes_weight(*mask);				\
85ecd6703fSHui Zhu 		nr_nodes > 0 &&						\
86ecd6703fSHui Zhu 		((node = hstate_next_node_to_alloc(next_node, mask)) || 1);	\
87ecd6703fSHui Zhu 		nr_nodes--)
88ecd6703fSHui Zhu 
89ecd6703fSHui Zhu #define for_each_node_mask_to_free(hs, nr_nodes, node, mask)		\
90ecd6703fSHui Zhu 	for (nr_nodes = nodes_weight(*mask);				\
91ecd6703fSHui Zhu 		nr_nodes > 0 &&						\
92ecd6703fSHui Zhu 		((node = hstate_next_node_to_free(hs, mask)) || 1);	\
93ecd6703fSHui Zhu 		nr_nodes--)
94ecd6703fSHui Zhu 
95ecd6703fSHui Zhu extern void remove_hugetlb_folio(struct hstate *h, struct folio *folio,
96ecd6703fSHui Zhu 				 bool adjust_surplus);
97ecd6703fSHui Zhu extern void add_hugetlb_folio(struct hstate *h, struct folio *folio,
98ecd6703fSHui Zhu 			      bool adjust_surplus);
99ecd6703fSHui Zhu extern void init_new_hugetlb_folio(struct folio *folio);
100ecd6703fSHui Zhu extern void prep_and_add_allocated_folios(struct hstate *h,
101ecd6703fSHui Zhu 					  struct list_head *folio_list);
102ecd6703fSHui Zhu extern long demote_pool_huge_page(struct hstate *src,
103ecd6703fSHui Zhu 				  nodemask_t *nodes_allowed,
104ecd6703fSHui Zhu 				  unsigned long nr_to_demote);
105ecd6703fSHui Zhu extern ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
106ecd6703fSHui Zhu 					   struct hstate *h, int nid,
107ecd6703fSHui Zhu 					   unsigned long count, size_t len);
108ecd6703fSHui Zhu 
109ecd6703fSHui Zhu extern void hugetlb_sysfs_init(void) __init;
110ecd6703fSHui Zhu 
111*cdcb53e1SHui Zhu #ifdef CONFIG_SYSCTL
112*cdcb53e1SHui Zhu extern void hugetlb_sysctl_init(void);
113*cdcb53e1SHui Zhu #else
hugetlb_sysctl_init(void)114*cdcb53e1SHui Zhu static inline void hugetlb_sysctl_init(void) { }
115*cdcb53e1SHui Zhu #endif
116*cdcb53e1SHui Zhu 
117ecd6703fSHui Zhu #endif /* _LINUX_HUGETLB_INTERNAL_H */
118